camaleon_cms 2.7.5 → 2.8.0

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

Potentially problematic release.


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

Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +20 -20
  3. data/app/apps/plugins/attack/config/config.json +2 -2
  4. data/app/apps/plugins/front_cache/admin_controller.rb +4 -6
  5. data/app/apps/plugins/front_cache/config/config.json +1 -1
  6. data/app/apps/plugins/front_cache/config/locales/translation.yml +1 -1
  7. data/app/apps/plugins/front_cache/front_cache_helper.rb +3 -3
  8. data/app/apps/plugins/visibility_post/config/config.json +2 -2
  9. data/app/apps/themes/camaleon_first/assets/js/main.js +1 -1
  10. data/app/apps/themes/camaleon_first/views/index.html.erb +1 -1
  11. data/app/apps/themes/default/assets/js/main.js +1 -1
  12. data/app/apps/themes/new/assets/js/main.js +1 -1
  13. data/app/apps/themes/new/views/index.html.erb +4 -4
  14. data/app/apps/themes/new/views/layouts/_footer.html.erb +2 -2
  15. data/app/assets/javascripts/camaleon_cms/admin/admin-basic-manifest.js +2 -2
  16. data/app/assets/javascripts/camaleon_cms/admin/admin-manifest.js +1 -1
  17. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/de.js +2 -2
  18. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/en.js +2 -2
  19. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/fr.js +2 -2
  20. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/it.js +2 -2
  21. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/nl.js +1 -1
  22. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/pt-BR.js +2 -2
  23. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/ru.js +2 -2
  24. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/uk.js +2 -2
  25. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/zh-CN.js +1 -1
  26. data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js +2 -2
  27. data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +15 -10
  28. data/app/controllers/camaleon_cms/admin/installers_controller.rb +1 -1
  29. data/app/controllers/camaleon_cms/admin/settings_controller.rb +1 -1
  30. data/app/controllers/camaleon_cms/camaleon_controller.rb +8 -2
  31. data/app/decorators/camaleon_cms/application_decorator.rb +8 -0
  32. data/app/decorators/camaleon_cms/category_decorator.rb +1 -1
  33. data/app/decorators/camaleon_cms/post_decorator.rb +5 -5
  34. data/app/decorators/camaleon_cms/post_type_decorator.rb +3 -3
  35. data/app/decorators/camaleon_cms/term_taxonomy_decorator.rb +1 -1
  36. data/app/helpers/camaleon_cms/admin/category_helper.rb +1 -1
  37. data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +12 -11
  38. data/app/helpers/camaleon_cms/html_helper.rb +6 -6
  39. data/app/helpers/camaleon_cms/plugins_helper.rb +1 -1
  40. data/app/helpers/camaleon_cms/session_helper.rb +1 -1
  41. data/app/helpers/camaleon_cms/short_code_helper.rb +1 -1
  42. data/app/helpers/camaleon_cms/site_helper.rb +1 -1
  43. data/app/helpers/camaleon_cms/theme_helper.rb +1 -1
  44. data/app/helpers/camaleon_cms/uploader_helper.rb +10 -5
  45. data/app/models/camaleon_cms/ability.rb +1 -1
  46. data/app/models/camaleon_cms/custom_field_group.rb +2 -2
  47. data/app/models/camaleon_cms/nav_menu.rb +1 -1
  48. data/app/models/camaleon_cms/post.rb +1 -1
  49. data/app/models/camaleon_cms/post_default.rb +1 -1
  50. data/app/models/camaleon_cms/post_type.rb +8 -8
  51. data/app/models/camaleon_cms/site.rb +1 -1
  52. data/app/models/camaleon_cms/term_taxonomy.rb +13 -0
  53. data/app/models/concerns/camaleon_cms/custom_fields_read.rb +11 -22
  54. data/app/models/concerns/camaleon_cms/site_default_settings.rb +1 -1
  55. data/app/uploaders/camaleon_cms_uploader.rb +5 -0
  56. data/app/validators/camaleon_cms/post_uniq_validator.rb +11 -12
  57. data/app/validators/camaleon_cms/uniq_validator.rb +9 -3
  58. data/app/views/camaleon_cms/admin/media/index.html.erb +1 -1
  59. data/app/views/camaleon_cms/admin/settings/_email_settings.html.erb +2 -2
  60. data/app/views/camaleon_cms/default_theme/index.html.erb +4 -4
  61. data/app/views/camaleon_cms/default_theme/sitemap.xml.builder +3 -3
  62. data/app/views/layouts/camaleon_cms/admin/_footer.html.erb +1 -1
  63. data/config/initializers/custom_initializers.rb +14 -0
  64. data/lib/camaleon_cms/engine.rb +1 -1
  65. data/lib/camaleon_cms/version.rb +1 -1
  66. data/lib/ext/hash.rb +1 -1
  67. data/lib/ext/string.rb +2 -2
  68. data/lib/generators/camaleon_cms/theme_template/assets/js/main.js +1 -1
  69. metadata +21 -7
@@ -41,8 +41,8 @@ module CamaleonCms
41
41
  if th.present?
42
42
  th
43
43
  else
44
- (default || object.post_type.get_option('default_thumb',
45
- nil) || h.asset_url('camaleon_cms/image-not-found.png'))
44
+ default || object.post_type.get_option('default_thumb',
45
+ nil) || h.asset_url('camaleon_cms/image-not-found.png')
46
46
  end
47
47
  end
48
48
  alias the_image_url the_thumb_url
@@ -61,12 +61,12 @@ module CamaleonCms
61
61
  end
62
62
 
63
63
  # return front url for this post
64
- # sample: http://localhost.com/my-page.html
64
+ # sample: https://localhost.com/my-page.html
65
65
  # args:
66
66
  # locale: language (default current language)
67
67
  # as_path: return the path instead of full url, sample: /my-page.html
68
68
  # Also, you can pass extra attributes as params for the url, sample: page.the_url(my_param: 'value', other: "asd")
69
- # => http://localhost.com/my-page.html?my_param=value&other=asd
69
+ # => https://localhost.com/my-page.html?my_param=value&other=asd
70
70
  # Return String URL
71
71
  def the_url(*args)
72
72
  args = args.extract_options!
@@ -127,7 +127,7 @@ module CamaleonCms
127
127
  end
128
128
 
129
129
  # return a hash of frontend urls for this post
130
- # sample: {es: 'http://mydomain.com/es/articulo-3.html', en: 'http://mydomain.com/en/post-3.html'}
130
+ # sample: {es: 'https://mydomain.com/es/articulo-3.html', en: 'https://mydomain.com/en/post-3.html'}
131
131
  def the_urls(*args)
132
132
  args = args.extract_options!
133
133
  res = {}
@@ -55,14 +55,14 @@ module CamaleonCms
55
55
 
56
56
  # return main categories (first level) for the post_type (active_record) filtered by permissions
57
57
  # in return object, you can add custom where's or pagination like here:
58
- # http://edgeguides.rubyonrails.org/active_record_querying.html
58
+ # https://edgeguides.rubyonrails.org/active_record_querying.html
59
59
  def the_categories
60
60
  object.categories
61
61
  end
62
62
 
63
63
  # return full categories (all levels) for the post_type (active_record) filtered by permissions
64
64
  # in return object, you can add custom where's or pagination like here:
65
- # http://edgeguides.rubyonrails.org/active_record_querying.html
65
+ # https://edgeguides.rubyonrails.org/active_record_querying.html
66
66
  def the_full_categories
67
67
  object.full_categories
68
68
  end
@@ -76,7 +76,7 @@ module CamaleonCms
76
76
 
77
77
  # return all post_tags for the post_type (active_record) filtered by permissions + hidden posts + roles + etc...
78
78
  # in return object, you can add custom where's or pagination like here:
79
- # http://edgeguides.rubyonrails.org/active_record_querying.html
79
+ # https://edgeguides.rubyonrails.org/active_record_querying.html
80
80
  def the_post_tags
81
81
  object.post_tags
82
82
  end
@@ -48,7 +48,7 @@ module CamaleonCms
48
48
  # ---------------------- filters
49
49
  # return all posts for this model (active_record) filtered by permissions + hidden posts + roles + etc...
50
50
  # in return object, you can add custom where's or pagination like here:
51
- # http://edgeguides.rubyonrails.org/active_record_querying.html
51
+ # https://edgeguides.rubyonrails.org/active_record_querying.html
52
52
  def the_posts
53
53
  h.verify_front_visibility(object.posts)
54
54
  end
@@ -17,7 +17,7 @@ module CamaleonCms
17
17
  options << [('—' * level) + category.the_title, category.id]
18
18
  children = attrs[:max_level] < level ? [] : category.children
19
19
  children = [] if attrs[:until_cats].include?(category.id)
20
- options += cama_category_get_options_html(children, level + 1, attrs) if children.size.positive?
20
+ options += cama_category_get_options_html(children, level + 1, attrs) unless children.empty?
21
21
  end
22
22
  options
23
23
  end
@@ -23,7 +23,7 @@ module CamaleonCms
23
23
  item_class_parent: 'dropdown', # class for all menu items that contain sub items
24
24
  sub_container: 'ul', # type of container for sub items
25
25
  sub_class: 'dropdown-menu', # class for sub container
26
- callback_item: ->(args) {},
26
+ callback_item: ->(args) {}, # rubocop:disable Lint/ShadowingOuterLocalVariable
27
27
  # callback executed for each item (args = { menu_item, link, level, settings, has_children, link_attrs = "", index}).
28
28
  # menu_item: (Object) Menu object
29
29
  # link: (Hash) link data: {link: '', name: ''}
@@ -48,10 +48,11 @@ module CamaleonCms
48
48
  container_append: '' # content append for menu container
49
49
  }
50
50
 
51
- args = args_def.merge(args)
51
+ args = args_def.merge!(args)
52
52
  nav_menu = current_site.nav_menus.find_by_slug(args[:menu_slug])
53
- nav_menu = current_site.nav_menus.first unless nav_menu.present?
54
- html = "<#{args[:container]} class='#{args[:container_class]}' id='#{args[:container_id]}'>#{args[:container_prepend]}{__}#{args[:container_append]}</#{args[:container]}>"
53
+ nav_menu ||= current_site.nav_menus.first
54
+ html = "<#{args[:container]} class='#{args[:container_class]}' "\
55
+ "id='#{args[:container_id]}'>#{args[:container_prepend]}{__}#{args[:container_append]}</#{args[:container]}>"
55
56
  if nav_menu.present?
56
57
  html.sub('{__}', cama_menu_draw_items(args, nav_menu.children.reorder(:term_order)))
57
58
  else
@@ -69,10 +70,10 @@ module CamaleonCms
69
70
  data_nav_item = cama_parse_menu_item(nav_menu_item)
70
71
  next if data_nav_item == false
71
72
 
72
- _is_current = data_nav_item[:current] || site_current_path == data_nav_item[:link] || site_current_path == data_nav_item[:link].sub(
73
- '.html', ''
74
- )
75
- has_children = nav_menu_item.have_children? && (args[:levels] == -1 || (args[:levels] != -1 && level <= args[:levels]))
73
+ _is_current = data_nav_item[:current] || site_current_path == data_nav_item[:link] ||
74
+ site_current_path == data_nav_item[:link].sub('.html', '')
75
+ has_children = nav_menu_item.have_children? && (args[:levels] == -1 ||
76
+ (args[:levels] != -1 && level <= args[:levels]))
76
77
  r = {
77
78
  menu_item: nav_menu_item.decorate,
78
79
  link: data_nav_item,
@@ -116,7 +117,7 @@ module CamaleonCms
116
117
  index += 1
117
118
  end
118
119
 
119
- if level.zero?
120
+ if level == 0
120
121
  html
121
122
  else
122
123
  html = "<#{args[:sub_container]} class='#{args[:sub_class]} #{if parent_current
@@ -142,7 +143,7 @@ module CamaleonCms
142
143
  '.html', ''
143
144
  )
144
145
  has_children = nav_menu_item.have_children?
145
- has_children = false if max_levels.positive? && max_levels == internal_level
146
+ has_children = false if max_levels > 0 && max_levels == internal_level
146
147
  data_nav_item[:label] = data_nav_item[:name]
147
148
  data_nav_item[:url] = data_nav_item[:link]
148
149
  r = {
@@ -169,7 +170,7 @@ module CamaleonCms
169
170
  res << r
170
171
  end
171
172
 
172
- if internal_level.zero?
173
+ if internal_level == 0
173
174
  res
174
175
  else
175
176
  [res, is_current_parent, levels.max]
@@ -72,14 +72,14 @@ module CamaleonCms
72
72
  def cama_draw_custom_assets
73
73
  cama_html_helpers_init unless @_assets_libraries.present?
74
74
  libs = []
75
- @_assets_libraries.each do |_key, assets|
75
+ @_assets_libraries.each_value do |assets|
76
76
  libs += assets[:css] if assets[:css].present?
77
77
  end
78
78
  stylesheets = libs.uniq
79
79
  css = stylesheet_link_tag(*stylesheets, media: 'all')
80
80
 
81
81
  libs = []
82
- @_assets_libraries.each do |_key, assets|
82
+ @_assets_libraries.each_value do |assets|
83
83
  libs += assets[:js] if assets[:js].present?
84
84
  end
85
85
  javascripts = libs.uniq
@@ -98,7 +98,7 @@ module CamaleonCms
98
98
  terms.all.each do |term|
99
99
  options << [('—' * level) + term.name, term.id] unless @term.id == term.id
100
100
  children = term.children
101
- options += cama_get_options_html_from_items(children, level + 1) if children.size.positive?
101
+ options += cama_get_options_html_from_items(children, level + 1) unless children.empty?
102
102
  end
103
103
  options
104
104
  end
@@ -121,18 +121,18 @@ module CamaleonCms
121
121
  libs[:datepicker] = { js: [] }
122
122
  libs[:datetimepicker] = { js: [], css: [] }
123
123
  libs[:tinymce] =
124
- { js: ['camaleon_cms/admin/tinymce/tinymce.min', 'camaleon_cms/admin/tinymce/plugins/filemanager/plugin.min'],
124
+ { js: %w[camaleon_cms/admin/tinymce/tinymce.min camaleon_cms/admin/tinymce/plugins/filemanager/plugin.min],
125
125
  css: ['camaleon_cms/admin/tinymce/skins/lightgray/content.min'] }
126
126
  libs[:form_ajax] = { js: ['camaleon_cms/admin/form/jquery.form'] }
127
127
  libs[:cropper] = {} # loaded by default
128
128
  libs[:post] =
129
- { js: ['camaleon_cms/admin/jquery.tagsinput.min', 'camaleon_cms/admin/post'],
129
+ { js: %w[camaleon_cms/admin/jquery.tagsinput.min camaleon_cms/admin/post],
130
130
  css: ['camaleon_cms/admin/jquery.tagsinput'] }
131
131
  libs[:multiselect] = { js: ['camaleon_cms/admin/bootstrap-select.js'] }
132
132
  libs[:validate] = { js: ['camaleon_cms/admin/jquery.validate'] }
133
133
  libs[:nav_menu] =
134
134
  { css: ['camaleon_cms/admin/nestable/jquery.nestable'],
135
- js: ['camaleon_cms/admin/jquery.nestable', 'camaleon_cms/admin/nav_menu'] }
135
+ js: %w[camaleon_cms/admin/jquery.nestable camaleon_cms/admin/nav_menu] }
136
136
  libs[:admin_intro] =
137
137
  { js: ['camaleon_cms/admin/introjs/intro.min'], css: ['camaleon_cms/admin/introjs/introjs.min'] }
138
138
  @_cama_assets_libraries = libs
@@ -127,7 +127,7 @@ module CamaleonCms
127
127
  # asset: (String) asset name
128
128
  # plugin_key: (optional) plugin name, default (current plugin caller to this function)
129
129
  # sample:
130
- # plugin_asset_url("css/main.css") => return: http://myhost.com/assets/plugins/my_plugin/assets/css/main-54505620f.css
130
+ # plugin_asset_url("css/main.css") => return: https://myhost.com/assets/plugins/my_plugin/assets/css/main-54505620f.css
131
131
  def plugin_asset_url(asset, plugin_key = nil)
132
132
  key = plugin_key || self_plugin_key(1)
133
133
  p = PluginRoutes.plugin_info(key)['gem_mode'] ? "plugins/#{key}/#{asset}" : "plugins/#{key}/assets/#{asset}"
@@ -6,7 +6,7 @@ module CamaleonCms
6
6
  # redirect_url (default nil): after initialized the session, this will be redirected to
7
7
  # "redirect_url" if defined
8
8
  # it doesn't redirect if redirect_url === false
9
- # return to previous page if defined the cookie['return_to'] or login url received extra param: return_to=http://mysite.com
9
+ # return to previous page if defined the cookie['return_to'] or login url received extra param: return_to=https://mysite.com
10
10
  def login_user(user, remember_me = false, redirect_url = nil)
11
11
  c = { value: [user.auth_token, request.user_agent, request.ip], expires: 24.hours.from_now }
12
12
  c[:domain] = :all if PluginRoutes.system_info['users_share_sites'].present? && CamaleonCms::Site.count > 1
@@ -15,7 +15,7 @@ module CamaleonCms
15
15
  return args[:shortcode] unless attrs.present?
16
16
 
17
17
  cama_load_libraries(*attrs['data'].to_s.split(','))
18
- return ''
18
+ ''
19
19
  },
20
20
  "Permit to load libraries on demand, sample: [load_libraries data='datepicker,tinymce']")
21
21
 
@@ -32,7 +32,7 @@ module CamaleonCms
32
32
  nil
33
33
  end
34
34
  unless r[:site].present?
35
- Rails.logger.error 'Camaleon CMS - Please define your current site: $current_site = CamaleonCms::Site.first.decorate or map your domains: http://camaleon.tuzitio.com/documentation/category/139779-examples/how.html'.cama_log_style(:red)
35
+ Rails.logger.error 'Camaleon CMS - Please define your current site: $current_site = CamaleonCms::Site.first.decorate or map your domains: https://camaleon.website/documentation/category/139779-examples/how.html'.cama_log_style(:red)
36
36
  end
37
37
  @current_site = r[:site]
38
38
  end
@@ -26,7 +26,7 @@ module CamaleonCms
26
26
  # asset: (String) asset name
27
27
  # theme_name: (optional) theme name, default (current theme caller to this function)
28
28
  # sample:
29
- # theme_asset_url("css/main.css") => return: http://myhost.com/assets/themes/my_theme/assets/css/main-54505620f.css
29
+ # theme_asset_url("css/main.css") => return: https://myhost.com/assets/themes/my_theme/assets/css/main-54505620f.css
30
30
  def theme_asset_url(asset, theme_name = nil)
31
31
  p = theme_asset_path(asset, theme_name)
32
32
  begin
@@ -16,7 +16,7 @@ module CamaleonCms
16
16
  # sample "test.png", versions: '200x200,450x450' will generate: thumb/test-png_200x200.png, test-png_450x450.png
17
17
  # thumb_size: String (redefine the dimensions of the thumbnail, sample: '100x100' ==> only for images)
18
18
  # temporal_time: if great than 0 seconds, then this file will expire (removed) in that time (default: 0)
19
- # To manage jobs, please check http://edgeguides.rubyonrails.org/active_job_basics.html
19
+ # To manage jobs, please check https://edgeguides.rubyonrails.org/active_job_basics.html
20
20
  # Note: if you are using temporal_time, you will need to copy the file to another directory later
21
21
  # sample: upload_file(params[:my_file], {formats: "images", folder: "temporal"})
22
22
  # sample: upload_file(params[:my_file], {formats: "jpg,png,gif,mp3,mp4", temporal_time: 10.minutes, maximum: 10.megabytes})
@@ -45,7 +45,7 @@ module CamaleonCms
45
45
  generate_thumb: true,
46
46
  temporal_time: 0,
47
47
  filename: begin
48
- (cached_name || uploaded_io.original_filename)
48
+ cached_name || uploaded_io.original_filename
49
49
  rescue StandardError
50
50
  uploaded_io.path.split('/').last
51
51
  end.cama_fix_filename,
@@ -72,7 +72,6 @@ module CamaleonCms
72
72
  # save file
73
73
  key = File.join(settings[:folder], settings[:filename]).to_s.cama_fix_slash
74
74
  res = cama_uploader.add_file(settings[:uploaded_io], key, { same_name: settings[:same_name] })
75
- {} if (settings[:temporal_time]).positive?
76
75
 
77
76
  # generate image versions
78
77
  if res['file_type'] == 'image'
@@ -92,6 +91,12 @@ module CamaleonCms
92
91
  FileUtils.rm_f(uploaded_io.path) if settings[:remove_source] && File.exist?(uploaded_io.path)
93
92
 
94
93
  hooks_run('after_upload', settings)
94
+
95
+ # temporal file upload (always put as local for temporal files)
96
+ if settings[:temporal_time] > 0
97
+ CamaleonCmsUploader.delete_block.call(settings, cama_uploader, key)
98
+ end
99
+
95
100
  res
96
101
  end
97
102
 
@@ -237,7 +242,7 @@ module CamaleonCms
237
242
  # upload tmp file
238
243
  # support for url and local path
239
244
  # sample:
240
- # cama_tmp_upload('http://camaleon.tuzitio.com/media/132/logo2.png') ==> /var/rails/my_project/public/tmp/1/logo2.png
245
+ # cama_tmp_upload('https://camaleon.website/media/132/logo2.png') ==> /var/rails/my_project/public/tmp/1/logo2.png
241
246
  # cama_tmp_upload('/var/www/media/132/logo 2.png') ==> /var/rails/my_project/public/tmp/1/logo-2.png
242
247
  # accept args:
243
248
  # name: to indicate the name to use, sample: cama_tmp_upload('/var/www/media/132/logo 2.png', {name: 'owen.png', formats: 'images'})
@@ -324,7 +329,7 @@ module CamaleonCms
324
329
  cloud_front: current_site.get_option('filesystem_s3_cloudfront'),
325
330
  aws_file_upload_settings: lambda { |settings|
326
331
  settings
327
- }, # permit to add your custom attributes for file_upload http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#upload_file-instance_method
332
+ }, # permit to add your custom attributes for file_upload https://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#upload_file-instance_method
328
333
  aws_file_read_settings: lambda { |data, _s3_file|
329
334
  data
330
335
  } # permit to read custom attributes from aws file and add to file parsed object
@@ -105,7 +105,7 @@ module CamaleonCms
105
105
  end
106
106
 
107
107
  # support for custom abilities for each posttype
108
- # sample: http://camaleon.tuzitio.com/documentation/category/40756-uncategorized/custom-models.html
108
+ # sample: https://camaleon.website/documentation/category/40756-uncategorized/custom-models.html
109
109
  @roles_post_type.each do |k, v|
110
110
  next if %w[edit edit_other edit_publish publish manage_categories].include?(k.to_s)
111
111
 
@@ -5,8 +5,8 @@ module CamaleonCms
5
5
  alias_attribute :site_id, :parent_id
6
6
 
7
7
  default_scope do
8
- where.not(object_class: '_fields')
9
- .reorder("#{CamaleonCms::CustomField.table_name}.field_order ASC")
8
+ where("object_class != '_fields'")
9
+ .reorder("#{CamaleonCms::CustomField.table_name}.field_order ASC")
10
10
  end
11
11
 
12
12
  has_many :metas, -> { where(object_class: 'CustomFieldGroup') }, foreign_key: :objectid, dependent: :destroy
@@ -10,7 +10,7 @@ module CamaleonCms
10
10
  # add menu item for current menu
11
11
  # value: (Hash) is a hash object that contains label, type, link
12
12
  # options for type: post | category | post_type | post_tag | external
13
- # sample: {label: "my label", type: "external", link: "http://camaleon.tuzitio.com", target: '_blank'}
13
+ # sample: {label: "my label", type: "external", link: "https://camaleon.website", target: '_blank'}
14
14
  # sample: {label: "my label", type: "post", link: 10}
15
15
  # sample: {label: "my label", type: "category", link: 12}
16
16
  # return item created
@@ -42,7 +42,7 @@ module CamaleonCms
42
42
  validates_with CamaleonCms::PostUniqValidator
43
43
  attr_accessor :show_title_with_parent
44
44
 
45
- before_create :fix_post_order, if: ->(p) { !p.post_order.present? || p.post_order.zero? }
45
+ before_create :fix_post_order, if: ->(p) { !p.post_order.present? || p.post_order == 0 }
46
46
 
47
47
  # return all parents for current page hierarchy ordered bottom to top
48
48
  def parents
@@ -42,7 +42,7 @@ module CamaleonCms
42
42
  res = where("#{CamaleonCms::Post.table_name}.slug = ? OR #{CamaleonCms::Post.table_name}.slug LIKE ? ", slug,
43
43
  "%-->#{slug}<!--%")
44
44
  # end
45
- res.reorder('').first
45
+ res.take
46
46
  end
47
47
 
48
48
  # return the parent of a post (support for sub contents or tree of posts)
@@ -101,7 +101,7 @@ module CamaleonCms
101
101
  # add a post for current model
102
102
  # title: title for post, => required
103
103
  # content: html text content, => required
104
- # thumb: image url, => default (empty). check http://camaleon.tuzitio.com/api-methods.html#section_fileuploads
104
+ # thumb: image url, => default (empty). check https://camaleon.website/api-methods.html#section_fileuploads
105
105
  # categories: [1,3,4,5], => default (empty)
106
106
  # tags: String comma separated, => default (empty)
107
107
  # slug: string key for post, => default (empty)
@@ -111,7 +111,7 @@ module CamaleonCms
111
111
  # settings: Hash of post settings, sample => settings:
112
112
  # {has_content: false, has_summary: true, default_layout: 'my_layout', default_template: 'my_template' } (optional, see more in post.set_setting(...))
113
113
  # data_metas: {template: "", layout: ""}
114
- # sample: my_posttype.add_post(title: "My Title", post_order: 5, content: 'lorem_ipsum', settings: {default_template: "home/counters", has_content: false, has_seo: false, skip_fields: ["sub_tite", 'banner']}, fields: {pattern: true, bg: 'http://www.reallusion.com/de/images/3dx5/whatsnew/3dx5_features_banner_bg_02.jpg'})
114
+ # sample: my_posttype.add_post(title: "My Title", post_order: 5, content: 'lorem_ipsum', settings: {default_template: "home/counters", has_content: false, has_seo: false, skip_fields: ["sub_tite", 'banner']}, fields: {pattern: true, bg: 'https://www.reallusion.com/de/images/3dx5/whatsnew/3dx5_features_banner_bg_02.jpg'})
115
115
  # More samples here: https://gist.github.com/owen2345/eba9691585ed78ad6f7b52e9591357bf
116
116
  # return created post if it was created, else return errors
117
117
  def add_post(args)
@@ -139,12 +139,12 @@ module CamaleonCms
139
139
  # return all available route formats of this post type for content posts
140
140
  def contents_route_formats
141
141
  {
142
- 'post_of_post_type' => '<code>/group/:post_type_id-:title/:slug</code><br> (Sample: http://localhost.com/group/17-services/myservice.html)',
143
- 'post_of_category' => '<code>/category/:category_id-:title/:slug</code><br> (Sample: http://localhost.com/category/17-services/myservice.html)',
144
- 'post_of_category_post_type' => '<code>/:post_type_title/category/:category_id-:title/:slug</code><br> (Sample: http://localhost.com/services/category/17-services/myservice.html)',
145
- 'post_of_posttype' => '<code>/:post_type_title/:slug</code><br> (Sample: http://localhost.com/services/myservice.html)',
146
- 'post' => '<code>/:slug</code><br> (Sample: http://localhost.com/myservice.html)',
147
- 'hierarchy_post' => '<code>/:parent1_slug/:parent2_slug/.../:slug</code><br> (Sample: http://localhost.com/item-1/item-1-1/item-111.html)'
142
+ 'post_of_post_type' => '<code>/group/:post_type_id-:title/:slug</code><br> (Sample: https://localhost.com/group/17-services/myservice.html)',
143
+ 'post_of_category' => '<code>/category/:category_id-:title/:slug</code><br> (Sample: https://localhost.com/category/17-services/myservice.html)',
144
+ 'post_of_category_post_type' => '<code>/:post_type_title/category/:category_id-:title/:slug</code><br> (Sample: https://localhost.com/services/category/17-services/myservice.html)',
145
+ 'post_of_posttype' => '<code>/:post_type_title/:slug</code><br> (Sample: https://localhost.com/services/myservice.html)',
146
+ 'post' => '<code>/:slug</code><br> (Sample: https://localhost.com/myservice.html)',
147
+ 'hierarchy_post' => '<code>/:parent1_slug/:parent2_slug/.../:slug</code><br> (Sample: https://localhost.com/item-1/item-1-1/item-111.html)'
148
148
  }
149
149
  end
150
150
 
@@ -91,7 +91,7 @@ module CamaleonCms
91
91
  # return theme model with slug theme_slug for this site
92
92
  # theme_slug: (optional) if it is null, this will return current theme for this site
93
93
  def get_theme(theme_slug = nil)
94
- themes.where(slug: (theme_slug || get_theme_slug), status: nil).first_or_create!
94
+ themes.where(slug: theme_slug || get_theme_slug, status: nil).first_or_create!
95
95
  end
96
96
 
97
97
  # return plugin model with slug plugin_slug
@@ -16,6 +16,19 @@ module CamaleonCms
16
16
  # attr_accessible :data_options
17
17
  # attr_accessible :data_metas
18
18
 
19
+ # TODO: Remove the 1st branch when support will be dropped of Rails < 7.1
20
+ if ::Rails::VERSION::STRING < '7.1.0'
21
+ before_validation(on: %i[create update]) do
22
+ %i[name description].each do |attr|
23
+ next unless new_record? || attribute_changed?(attr)
24
+
25
+ self[attr] = ActionController::Base.helpers.sanitize(__send__(attr))
26
+ end
27
+ end
28
+ else
29
+ normalizes :name, :description, with: ->(field) { ActionController::Base.helpers.sanitize(field) }
30
+ end
31
+
19
32
  # callbacks
20
33
  before_validation :before_validating
21
34
  before_destroy :destroy_dependencies
@@ -3,18 +3,6 @@ module CamaleonCms
3
3
  extend ActiveSupport::Concern
4
4
  included do
5
5
  before_destroy :_destroy_custom_field_groups
6
- # DEPRECATED, INSTEAD USE: custom_fields
7
- has_many :fields, lambda { |object|
8
- where(object_class: object.class.to_s.gsub('Decorator', '').gsub('CamaleonCms::', ''))
9
- }, class_name: 'CamaleonCms::CustomField', foreign_key: :objectid
10
- # DEPRECATED, INSTEAD USE: custom_field_values
11
- has_many :field_values, lambda { |object|
12
- where(object_class: object.class.to_s.gsub('Decorator', '').gsub('CamaleonCms::', ''))
13
- }, class_name: 'CamaleonCms::CustomFieldsRelationship', foreign_key: :objectid, dependent: :delete_all
14
- # DEPRECATED, INSTEAD USE: custom_field_groups
15
- has_many :field_groups, lambda { |object|
16
- where(object_class: object.class.to_s.parseCamaClass)
17
- }, class_name: 'CamaleonCms::CustomFieldGroup', foreign_key: :objectid
18
6
  end
19
7
 
20
8
  # get custom field groups for current object
@@ -38,7 +26,7 @@ module CamaleonCms
38
26
  { kind: args,
39
27
  include_parent: false }
40
28
  else
41
- { kind: 'Post', include_parent: false }.merge(args)
29
+ { kind: 'Post', include_parent: false }.merge!(args)
42
30
  end
43
31
  class_name = self.class.to_s.parseCamaClass
44
32
  case class_name
@@ -73,7 +61,7 @@ module CamaleonCms
73
61
  CamaleonCms::CustomFieldGroup.where(object_class: "PostType_#{args[:kind]}", objectid: id)
74
62
  end
75
63
  else # 'Plugin' or other classes
76
- field_groups
64
+ custom_field_groups
77
65
  end
78
66
  end
79
67
 
@@ -131,7 +119,7 @@ module CamaleonCms
131
119
  # puts res[0]['my_slug1'].first ==> "val 1"
132
120
  def get_fields_grouped(field_keys)
133
121
  res = []
134
- custom_field_values.where(custom_field_slug: field_keys).order(group_number: :asc).group_by(&:group_number).each do |_group_number, group_fields|
122
+ custom_field_values.where(custom_field_slug: field_keys).order(group_number: :asc).group_by(&:group_number).each_value do |group_fields|
135
123
  group = {}
136
124
  field_keys.each do |field_key|
137
125
  _tmp = []
@@ -196,8 +184,8 @@ module CamaleonCms
196
184
  # kind: argument only for PostType model: (Post | Category | PostTag), default => Post. If kind = "" this will add group for all post_types
197
185
  def add_custom_field_group(values, kind = 'Post')
198
186
  values = values.with_indifferent_access
199
- group = get_field_groups(kind).where(slug: values[:slug]).first
200
- unless group.present?
187
+ group = get_field_groups(kind).find_by(slug: values[:slug])
188
+ unless group
201
189
  site = _cama_get_field_site
202
190
  values[:parent_id] = site.id if site.present?
203
191
  group = if is_a?(CamaleonCms::Post) # harcoded for post to support custom field groups
@@ -206,6 +194,7 @@ module CamaleonCms
206
194
  get_field_groups(kind).create!(values)
207
195
  end
208
196
  end
197
+
209
198
  group
210
199
  end
211
200
  alias add_field_group add_custom_field_group
@@ -215,8 +204,8 @@ module CamaleonCms
215
204
  # more details in add_manual_field(item, options) from custom field groups
216
205
  # kind: argument only for PostType model: (Post | Category | PostTag), default => Post
217
206
  def add_custom_field_to_default_group(item, options, kind = 'Post')
218
- g = get_field_groups(kind).where(slug: '_default').first
219
- g = add_custom_field_group({ name: 'Default Field Group', slug: '_default' }, kind) unless g.present?
207
+ g = get_field_groups(kind).find_by(slug: '_default')
208
+ g ||= add_custom_field_group({ name: 'Default Field Group', slug: '_default' }, kind)
220
209
  g.add_manual_field(item, options)
221
210
  end
222
211
  alias add_field add_custom_field_to_default_group
@@ -243,7 +232,7 @@ module CamaleonCms
243
232
 
244
233
  ActiveRecord::Base.transaction do
245
234
  custom_field_values.delete_all
246
- datas.each do |_index, fields_data|
235
+ datas.each_value do |fields_data|
247
236
  fields_data.each do |field_key, values|
248
237
  next unless values[:values].present?
249
238
 
@@ -260,7 +249,7 @@ module CamaleonCms
260
249
  # update new value for field with slug _key
261
250
  # Sample: my_posy.update_field_value('sub_title', 'Test Sub Title')
262
251
  def update_field_value(_key, value = nil, group_number = 0)
263
- custom_field_values.where(custom_field_slug: _key, group_number: group_number).first.update_column('value', value)
252
+ custom_field_values.find_by(custom_field_slug: _key, group_number: group_number)&.update_column('value', value)
264
253
  rescue StandardError
265
254
  nil
266
255
  end
@@ -287,7 +276,7 @@ module CamaleonCms
287
276
  # sample: my_post.set_field_value('subtitle', 'Sub Title', {group_number: 1})
288
277
  # sample: my_post.set_field_value('subtitle', 'Sub Title', {group_number: 1, group_number: 1}) # add field values for fields in group 1
289
278
  def set_field_value(key, value, args = {})
290
- args = { order: 0, group_number: 0, field_id: nil, clear: true }.merge(args)
279
+ args = { order: 0, group_number: 0, field_id: nil, clear: true }.merge!(args)
291
280
  unless args[:field_id].present?
292
281
  args[:field_id] = begin
293
282
  get_field_object(key).id
@@ -25,7 +25,7 @@ module CamaleonCms
25
25
  else
26
26
  title = 'Welcome'
27
27
  slug = 'welcome'
28
- content = "<p style='text-align: center;'><img width='155' height='155' src='http://camaleon.tuzitio.com/media/132/logo2.png' alt='logo' /></p><p><strong>Camaleon CMS</strong>&nbsp;is a free and open-source tool and a fexible content management system (CMS) based on <a href='http://rubyonrails.org'>Ruby on Rails</a>.</p> <p>With Camaleon you can do the following:</p> <ul> <li>Create instantly a lot of sites&nbsp;in the same installation</li> <li>Manage your content information in several languages</li> <li>Extend current functionality by&nbsp;plugins (MVC structure and no more echo or prints anywhere)</li> <li>Create or install different themes for each site</li> <li>Create your own structure without coding anything (adapt Camaleon as you want&nbsp;and not you for Camaleon)</li> <li>Create your store and start to sell your products using our plugins</li> <li>Avoid web attacks</li> <li>Compare the speed and enjoy the speed of your new Camaleon site</li> <li>Customize or create your themes for mobile support</li> <li>Support&nbsp;more visitors at the same time</li> <li>Manage your information with a panel like wordpress&nbsp;</li> <li>All urls are oriented for SEO</li> <li>Multiples roles of users</li> </ul>"
28
+ content = "<p style='text-align: center;'><img width='155' height='155' src='https://camaleon.website/media/132/logo2.png' alt='logo' /></p><p><strong>Camaleon CMS</strong>&nbsp;is a free and open-source tool and a fexible content management system (CMS) based on <a href='https://rubyonrails.org'>Ruby on Rails</a>.</p> <p>With Camaleon you can do the following:</p> <ul> <li>Create instantly a lot of sites&nbsp;in the same installation</li> <li>Manage your content information in several languages</li> <li>Extend current functionality by&nbsp;plugins (MVC structure and no more echo or prints anywhere)</li> <li>Create or install different themes for each site</li> <li>Create your own structure without coding anything (adapt Camaleon as you want&nbsp;and not you for Camaleon)</li> <li>Create your store and start to sell your products using our plugins</li> <li>Avoid web attacks</li> <li>Compare the speed and enjoy the speed of your new Camaleon site</li> <li>Customize or create your themes for mobile support</li> <li>Support&nbsp;more visitors at the same time</li> <li>Manage your information with a panel like wordpress&nbsp;</li> <li>All urls are oriented for SEO</li> <li>Multiples roles of users</li> </ul>"
29
29
  end
30
30
  user = users.admin_scope.first
31
31
  unless user.present?
@@ -158,6 +158,11 @@ class CamaleonCmsUploader
158
158
  File.exist?(file_name)
159
159
  end
160
160
 
161
+ def self.delete_block(&block)
162
+ @delete_block = block if block
163
+ @delete_block
164
+ end
165
+
161
166
  private
162
167
 
163
168
  def cache_key
@@ -14,18 +14,17 @@ module CamaleonCms
14
14
  )
15
15
  .where.not(id: record.id)
16
16
  .where.not(status: %i[draft draft_child trash])
17
- if posts.size.positive?
18
- record.errors[:base] << if slug_array.size > 1
19
- "#{I18n.t('camaleon_cms.admin.post.message.requires_different_slug')}: #{posts.pluck(:slug).map do |slug|
20
- record.slug.to_s.translations.map do |lng, r_slug|
21
- if slug.translations_array.include?(r_slug)
22
- "#{r_slug} (#{lng})"
23
- end
24
- end.join(',')
25
- end.join(',').split(',').uniq.clean_empty.join(', ')} "
26
- else
27
- "#{I18n.t('camaleon_cms.admin.post.message.requires_different_slug')}: #{record.slug} "
28
- end
17
+ unless posts.empty?
18
+ record.errors[:base] <<
19
+ if slug_array.size > 1
20
+ "#{I18n.t('camaleon_cms.admin.post.message.requires_different_slug')}: #{posts.pluck(:slug).map do |slug|
21
+ record.slug.to_s.translations.map do |lng, r_slug|
22
+ "#{r_slug} (#{lng})" if slug.translations_array.include?(r_slug)
23
+ end.join(',')
24
+ end.join(',').split(',').uniq.clean_empty.join(', ')} "
25
+ else
26
+ "#{I18n.t('camaleon_cms.admin.post.message.requires_different_slug')}: #{record.slug} "
27
+ end
29
28
  end
30
29
 
31
30
  # avoid recursive page parent
@@ -3,9 +3,15 @@ module CamaleonCms
3
3
  def validate(record)
4
4
  return if record.skip_slug_validation?
5
5
 
6
- if CamaleonCms::TermTaxonomy.where(slug: record.slug).where.not(id: record.id).where("#{CamaleonCms::TermTaxonomy.table_name}.taxonomy" => record.taxonomy).where("#{CamaleonCms::TermTaxonomy.table_name}.parent_id" => record.parent_id).size.positive?
7
- record.errors[:base] << I18n.t('camaleon_cms.admin.post.message.requires_different_slug').to_s
8
- end
6
+ taxonomy_table = CamaleonCms::TermTaxonomy.table_name
7
+ slug_exists = CamaleonCms::TermTaxonomy.where(slug: record.slug)
8
+ .where.not(id: record.id)
9
+ .where("#{taxonomy_table}.taxonomy" => record.taxonomy)
10
+ .where("#{taxonomy_table}.parent_id" => record.parent_id).exists?
11
+
12
+ return unless slug_exists
13
+
14
+ record.errors[:base] << I18n.t('camaleon_cms.admin.post.message.requires_different_slug').to_s
9
15
  end
10
16
  end
11
17
  end
@@ -48,7 +48,7 @@
48
48
  <fieldset>
49
49
  <legend><%= t("camaleon_cms.admin.media.external", default: 'From URL') %></legend>
50
50
  <div class="form-group">
51
- <input type="text" name="remote_file" class="form-control" placeholder="http://..." class="required">
51
+ <input type="text" name="remote_file" class="form-control" placeholder="https://..." class="required">
52
52
  </div>
53
53
  <div class="form-group">
54
54
  <button type="submit" class="btn btn-primary"><%= t("camaleon_cms.admin.button.submit") %></button>