camaleon_cms 2.1.1.4 → 2.1.2.0

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

Potentially problematic release.


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

Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -3
  3. data/app/apps/plugins/contact_form/contact_form_helper.rb +3 -44
  4. data/app/apps/plugins/contact_form/contact_form_html_helper.rb +1 -1
  5. data/app/apps/plugins/contact_form/views/contact_form/{_submission.html.erb → _email_content.html.erb} +0 -0
  6. data/app/apps/themes/camaleon_first/views/index.html.erb +1 -1
  7. data/app/apps/themes/default/views/category.html.erb +1 -1
  8. data/app/apps/themes/default/views/page.html.erb +1 -1
  9. data/app/apps/themes/default/views/partials/_comments.html.erb +5 -5
  10. data/app/apps/themes/default/views/post.html.erb +1 -1
  11. data/app/apps/themes/default/views/post_tag.html.erb +1 -1
  12. data/app/apps/themes/default/views/post_type.html.erb +1 -1
  13. data/app/apps/themes/default/views/search.html.erb +2 -2
  14. data/app/apps/themes/new/views/category.html.erb +1 -1
  15. data/app/apps/themes/new/views/page.html.erb +1 -1
  16. data/app/apps/themes/new/views/post_tag.html.erb +1 -1
  17. data/app/apps/themes/new/views/post_type.html.erb +1 -1
  18. data/app/apps/themes/new/views/search.html.erb +2 -2
  19. data/app/assets/javascripts/camaleon_cms/admin/_actions.js +1 -1
  20. data/app/assets/javascripts/camaleon_cms/admin/{bootstrap-datepicker.js → _bootstrap-datepicker.js} +0 -0
  21. data/app/assets/javascripts/camaleon_cms/admin/_bootstrap-select.js +7 -0
  22. data/app/assets/javascripts/camaleon_cms/admin/_custom_fields.js +9 -0
  23. data/app/assets/javascripts/camaleon_cms/admin/admin-manifest.js +2 -1
  24. data/app/assets/javascripts/camaleon_cms/admin/jquery.validate.js +3 -1
  25. data/app/assets/javascripts/camaleon_cms/admin/nav_menu.js.coffee +125 -0
  26. data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js.coffee +53 -23
  27. data/app/assets/javascripts/camaleon_cms/admin/user_profile.js +23 -29
  28. data/app/assets/stylesheets/camaleon_cms/admin/{bootstrap-datepicker.css.scss → _bootstrap-datepicker.css.scss} +0 -0
  29. data/app/assets/stylesheets/camaleon_cms/admin/_bootstrap-select.css +6 -0
  30. data/app/assets/stylesheets/camaleon_cms/admin/admin-manifest.css +2 -3
  31. data/app/assets/stylesheets/camaleon_cms/admin/colorpicker.css.scss +9 -8
  32. data/app/assets/stylesheets/camaleon_cms/admin/uploader/_uploadfile.css.scss +1 -12
  33. data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +102 -81
  34. data/app/controllers/camaleon_cms/admin/media_controller.rb +8 -25
  35. data/app/controllers/camaleon_cms/admin_controller.rb +1 -1
  36. data/app/controllers/camaleon_cms/camaleon_controller.rb +24 -0
  37. data/app/controllers/camaleon_cms/frontend_controller.rb +0 -1
  38. data/app/decorators/camaleon_cms/application_decorator.rb +5 -8
  39. data/app/decorators/camaleon_cms/post_decorator.rb +5 -5
  40. data/app/decorators/camaleon_cms/post_type_decorator.rb +2 -5
  41. data/app/decorators/camaleon_cms/site_decorator.rb +12 -0
  42. data/app/decorators/camaleon_cms/term_taxonomy_decorator.rb +1 -1
  43. data/app/helpers/camaleon_cms/admin/application_helper.rb +8 -1
  44. data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +17 -16
  45. data/app/helpers/camaleon_cms/admin/menus_helper.rb +1 -1
  46. data/app/helpers/camaleon_cms/camaleon_helper.rb +2 -2
  47. data/app/helpers/camaleon_cms/captcha_helper.rb +15 -14
  48. data/app/helpers/camaleon_cms/email_helper.rb +7 -3
  49. data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +7 -1
  50. data/app/helpers/camaleon_cms/html_helper.rb +1 -1
  51. data/app/helpers/camaleon_cms/site_helper.rb +6 -15
  52. data/app/helpers/camaleon_cms/uploader_helper.rb +31 -187
  53. data/app/mailers/camaleon_cms/html_mailer.rb +4 -8
  54. data/app/models/camaleon_cms/custom_field_group.rb +1 -0
  55. data/app/models/camaleon_cms/nav_menu.rb +1 -20
  56. data/app/models/camaleon_cms/nav_menu_item.rb +13 -0
  57. data/app/models/camaleon_cms/post.rb +1 -1
  58. data/app/models/camaleon_cms/post_type.rb +8 -7
  59. data/app/models/camaleon_cms/site.rb +22 -2
  60. data/app/models/camaleon_cms/user.rb +2 -1
  61. data/app/models/concerns/camaleon_cms/custom_fields_read.rb +21 -29
  62. data/app/models/concerns/camaleon_cms/metas.rb +4 -3
  63. data/app/uploaders/camaleon_cms_aws_uploader.rb +81 -0
  64. data/app/uploaders/camaleon_cms_local_uploader.rb +84 -0
  65. data/app/uploaders/camaleon_cms_uploader.rb +146 -0
  66. data/app/views/camaleon_cms/admin/appearances/nav_menus/_custom_fields.html.erb +3 -5
  67. data/app/views/camaleon_cms/admin/appearances/nav_menus/_external_menu.html.erb +7 -6
  68. data/app/views/camaleon_cms/admin/appearances/nav_menus/_form.html.erb +13 -0
  69. data/app/views/camaleon_cms/admin/appearances/nav_menus/_left_menu_items.html.erb +77 -0
  70. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_items.html.erb +18 -0
  71. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_items_list.html.erb +12 -0
  72. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_options.html.erb +21 -0
  73. data/app/views/camaleon_cms/admin/appearances/nav_menus/index.html.erb +5 -98
  74. data/app/views/camaleon_cms/admin/media/_files_list.html.erb +2 -7
  75. data/app/views/camaleon_cms/admin/media/_render_file_item.html.erb +28 -26
  76. data/app/views/camaleon_cms/admin/media/_render_folder_item.html.erb +14 -12
  77. data/app/views/camaleon_cms/admin/media/index.html.erb +23 -22
  78. data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +4 -5
  79. data/app/views/camaleon_cms/admin/posts/form.html.erb +1 -0
  80. data/app/views/camaleon_cms/admin/sessions/forgot.html.erb +6 -6
  81. data/app/views/camaleon_cms/admin/sessions/login.html.erb +7 -7
  82. data/app/views/camaleon_cms/admin/sessions/register.html.erb +8 -8
  83. data/app/views/camaleon_cms/admin/settings/_configuration_settings.html.erb +30 -6
  84. data/app/views/camaleon_cms/admin/settings/_email_settings.html.erb +26 -23
  85. data/app/views/camaleon_cms/admin/settings/_file_system_settings.html.erb +25 -20
  86. data/app/views/camaleon_cms/admin/settings/_media_settings.html.erb +10 -0
  87. data/app/views/camaleon_cms/admin/settings/custom_fields/_get_items.html.erb +2 -3
  88. data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +2 -2
  89. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_audio.html.erb +1 -1
  90. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_colorpicker.html.erb +2 -2
  91. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_date.html.erb +1 -1
  92. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_field_attrs.html.erb +2 -2
  93. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_file.html.erb +1 -1
  94. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_image.html.erb +1 -1
  95. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_video.html.erb +1 -1
  96. data/app/views/camaleon_cms/admin/settings/post_types/_form.html.erb +2 -2
  97. data/app/views/camaleon_cms/admin/settings/post_types/index.html.erb +1 -1
  98. data/app/views/camaleon_cms/admin/settings/site.html.erb +11 -13
  99. data/app/views/camaleon_cms/admin/settings/sites/index.html.erb +5 -3
  100. data/app/views/camaleon_cms/admin/users/form.html.erb +14 -22
  101. data/app/views/camaleon_cms/default_theme/category.html.erb +1 -1
  102. data/app/views/camaleon_cms/default_theme/partials/_comments.html.erb +5 -5
  103. data/app/views/camaleon_cms/default_theme/partials/_search_form.html.erb +1 -1
  104. data/app/views/camaleon_cms/default_theme/partials/_sidebar.html.erb +4 -4
  105. data/app/views/camaleon_cms/default_theme/post_tag.html.erb +1 -1
  106. data/app/views/camaleon_cms/default_theme/post_type.html.erb +1 -1
  107. data/app/views/camaleon_cms/default_theme/search.html.erb +1 -1
  108. data/app/views/camaleon_cms/default_theme/single.html.erb +1 -1
  109. data/config/locales/camaleon_cms/admin/en.yml +1 -1
  110. data/config/locales/camaleon_cms/admin/es.yml +36 -0
  111. data/config/locales/camaleon_cms/common.yml +4 -2
  112. data/config/routes/admin.rb +13 -7
  113. data/config/routes/frontend.rb +9 -7
  114. data/config/system.json +1 -0
  115. data/lib/camaleon_cms/engine.rb +1 -1
  116. data/lib/camaleon_cms/version.rb +1 -1
  117. data/lib/ext/string.rb +12 -0
  118. data/lib/generators/camaleon_cms/gem_plugin_generator.rb +1 -1
  119. data/lib/plugin_routes.rb +1 -1
  120. metadata +17 -24
  121. data/app/assets/javascripts/camaleon_cms/admin/bootstrap-select.js +0 -1022
  122. data/app/assets/javascripts/camaleon_cms/admin/nav-menu.js +0 -177
  123. data/app/assets/stylesheets/camaleon_cms/admin/nav-menu.css.scss +0 -33
  124. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_form.html.erb +0 -36
  125. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_list.html.erb +0 -22
@@ -1,5 +1,5 @@
1
1
  module CamaleonCms::EmailHelper
2
-
2
+ include CamaleonCms::HooksHelper
3
3
  # send and email
4
4
  # email: email to
5
5
  # subject: Subject of the email
@@ -9,13 +9,17 @@ module CamaleonCms::EmailHelper
9
9
  # layout_name: path of the template to render
10
10
  # template_name: template name to render in template_path
11
11
  def send_email(email, subject='Tiene una notificacion', content='', from=nil, attachs=[], template_name = nil, layout_name = nil, extra_data = {})
12
- args = {template_name: template_name, layout_name: layout_name, from: from || current_site.get_option("email"), url_base: cama_root_url, content: content, attachs: attachs, extra_data: extra_data, current_site: current_site}
12
+ args = {attachs: attachs, extra_data: extra_data}
13
+ args[:template_name] = template_name if template_name.present?
14
+ args[:layout_name] = layout_name if layout_name.present?
15
+ args[:from] = from if from.present?
16
+ args[:content] = content if content.present?
13
17
  cama_send_email(email, subject, args)
14
18
  end
15
19
 
16
20
  # short method of send_email
17
21
  def cama_send_email(email_to, subject, args = {})
18
- args = {from: current_site.get_option("email"), url_base: cama_root_url, current_site: current_site, cc_to: [], template_name: 'mailer', layout_name: 'camaleon_cms/mailer', format: 'html', subject: subject}.merge(args)
22
+ args = {url_base: cama_root_url, current_site: current_site, subject: subject}.merge(args)
19
23
  args[:attachments] = args[:attachs] if args[:attachs].present?
20
24
  args[:current_site] = args[:current_site].id
21
25
 
@@ -161,7 +161,13 @@ module CamaleonCms::Frontend::NavMenuHelper
161
161
  r[:link] = cama_root_path if r[:link] == "root_url"
162
162
  r[:link] = site_current_path if site_current_path == "#{current_site.the_path}#{r[:link]}"
163
163
  r[:current] = r[:link] == site_current_url || r[:link] == site_current_path
164
- r
164
+ # permit to customize or mark as current menu
165
+ # _args: (HASH) {menu_item: Model Menu Item, parsed_menu: Parsed Menu }
166
+ # Sample parsed_menu: {link: "url of the link", name: "Text of the menu", type_menu: 'external', current: Boolean (true => is current menu, false => not current menu item)}
167
+ _args = {menu_item: nav_menu_item, parsed_menu: r}; hooks_run("on_external_menu", _args)
168
+ r = _args[:parsed_menu]
169
+ return false if _args[:parsed_menu] == false
170
+
165
171
  else
166
172
  return false
167
173
  end
@@ -128,7 +128,7 @@ module CamaleonCms::HtmlHelper
128
128
  libs[:post] = {js: ["camaleon_cms/admin/jquery.tagsinput.min", 'camaleon_cms/admin/post'], css: ["camaleon_cms/admin/jquery.tagsinput"]}
129
129
  libs[:multiselect] = {js: ['camaleon_cms/admin/bootstrap-select.js']}
130
130
  libs[:validate] = {js: ['camaleon_cms/admin/jquery.validate']}
131
- libs[:nav_menu] = {css: ['camaleon_cms/admin/nestable/jquery.nestable', "camaleon_cms/admin/nav-menu"], js: ["camaleon_cms/admin/jquery.nestable", 'camaleon_cms/admin/nav-menu']}
131
+ libs[:nav_menu] = {css: ['camaleon_cms/admin/nestable/jquery.nestable'], js: ["camaleon_cms/admin/jquery.nestable", 'camaleon_cms/admin/nav_menu']}
132
132
  libs[:admin_intro] = {js: ['camaleon_cms/admin/introjs/intro.min'], css: ["camaleon_cms/admin/introjs/introjs.min"]}
133
133
  @_cama_assets_libraries = libs
134
134
  end
@@ -25,41 +25,32 @@ module CamaleonCms::SiteHelper
25
25
  @current_site = r[:site]
26
26
  end
27
27
 
28
- # check if current site exist, if not, this will be redirected to main domain
29
- def cama_site_check_existence()
30
- if !current_site.present?
31
- if Cama::Site.main_site.present?
32
- redirect_to Cama::Site.main_site.decorate.the_url
33
- else
34
- redirect_to cama_admin_installers_path
35
- end
36
- end
37
- end
38
-
39
28
  # return current theme model for current site
40
29
  def current_theme
41
30
  @_current_theme ||= current_site.get_theme.decorate
42
31
  end
43
32
 
44
33
  # get list templates files of current theme
45
- def cama_get_list_template_files
34
+ def cama_get_list_template_files(post_type)
46
35
  contained_files = []
47
36
  Dir[File.join(current_theme.settings["path"], "views", '*')].each do |path|
48
37
  f_name = File.basename(path)
49
38
  contained_files << f_name.split(".").first if f_name.include?('template_')
50
39
  end
51
- contained_files
40
+ _args={tempates: contained_files, post_type: post_type}; hooks_run("post_get_list_templates", _args)
41
+ _args[:tempates]
52
42
  end
53
43
 
54
44
  # get list layouts files of current theme
55
45
  # return an array of layouts for current theme
56
- def cama_get_list_layouts_files
46
+ def cama_get_list_layouts_files(post_type)
57
47
  contained_files = []
58
48
  Dir[File.join(current_theme.settings["path"], "views", "layouts", '*')].each do |path|
59
49
  f_name = File.basename(path)
60
50
  contained_files << f_name.split(".").first unless f_name.start_with?('_')
61
51
  end
62
- contained_files
52
+ _args={layouts: contained_files, post_type: post_type}; hooks_run("post_get_list_layouts", _args)
53
+ _args[:layouts]
63
54
  end
64
55
 
65
56
 
@@ -7,6 +7,7 @@
7
7
  See the GNU Affero General Public License (GPLv3) for more details.
8
8
  =end
9
9
  module CamaleonCms::UploaderHelper
10
+ include ActionView::Helpers::NumberHelper
10
11
  # upload a file into server
11
12
  # settings:
12
13
  # folder: Directory where the file will be saved (default: "")
@@ -23,19 +24,14 @@ module CamaleonCms::UploaderHelper
23
24
  # sample: upload_file(params[:my_file], {formats: "images", folder: "temporal"})
24
25
  # sample: upload_file(params[:my_file], {formats: "jpg,png,gif,mp3,mp4", temporal_time: 10.minutes, maximum: 10.megabytes})
25
26
  def upload_file(uploaded_io, settings = {})
26
- unless uploaded_io.present?
27
- return {error: "File is empty", file: nil, size: nil}
28
- end
27
+ return {error: "File is empty", file: nil, size: nil} unless uploaded_io.present?
29
28
  uploaded_io = File.open(uploaded_io) if uploaded_io.is_a?(String)
30
-
31
29
  uploaded_io = File.open(cama_resize_upload(uploaded_io.path, settings[:dimension])) if settings[:dimension].present? # resize file into specific dimensions
32
-
33
- cama_uploader_init_connection(true)
34
30
  settings = settings.to_sym
35
31
  settings[:uploaded_io] = uploaded_io
36
32
  settings = {
37
33
  folder: "",
38
- maximum: 100.megabytes,
34
+ maximum: current_site.get_option('filesystem_max_size', 100).to_f.megabytes,
39
35
  formats: "*",
40
36
  generate_thumb: true,
41
37
  temporal_time: 0,
@@ -45,176 +41,37 @@ module CamaleonCms::UploaderHelper
45
41
  same_name: false
46
42
  }.merge(settings)
47
43
  hooks_run("before_upload", settings)
48
-
49
44
  res = {error: nil}
50
45
 
51
46
  # formats validations
52
- return {error: "#{ct("file_format_error")} (#{settings[:formats]})"} unless cama_verify_format(uploaded_io.path, settings[:formats])
47
+ return {error: "#{ct("file_format_error")} (#{settings[:formats]})"} unless cama_uploader.class.validate_file_format(uploaded_io.path, settings[:formats])
53
48
 
54
49
  # file size validations
55
50
  if settings[:maximum] < settings[:file_size]
56
- res[:error] = ct("file_size_exceeded")
51
+ res[:error] = "#{ct("file_size_exceeded", default: "File size exceeded")} (#{number_to_human_size(settings[:maximum])})"
57
52
  return res
58
53
  end
59
54
 
60
- File.chmod(0644, uploaded_io.path) # fix reading permission (Fix Fog-Local)
61
-
62
55
  # save file
63
- if settings[:same_name]
64
- partial_path = "#{current_site.upload_directory_name}/#{"#{settings[:folder]}/" if settings[:folder].present?}#{settings[:filename]}"
65
- else
66
- partial_path = "#{current_site.upload_directory_name}/#{cama_uploader_check_name("#{"#{settings[:folder]}/" if settings[:folder].present?}#{settings[:filename]}")}"
67
- end
68
- partial_path = partial_path.gsub(/(\/){2,}/, "/")
69
- file = @fog_connection_bucket_dir.files.create({:key => partial_path, :body => uploaded_io, :public => true})
70
-
71
- if settings[:temporal_time] > 0 # temporal file upload (always put as local for temporal files)
72
- Thread.new do
73
- sleep(settings[:temporal_time])
74
- file.destroy
75
- ActiveRecord::Base.connection.close
76
- end
77
- end
78
-
79
- res = cama_uploader_parse_file(file)
56
+ key = File.join(settings[:folder], settings[:filename]).to_s.gsub(/(\/){2,}/, "/")
57
+ res = cama_uploader.add_file(uploaded_io, key, {same_name: settings[:same_name]})
58
+ {} if settings[:temporal_time] > 0 # temporal file upload (always put as local for temporal files) (TODO: use delayjob)
80
59
 
81
60
  # generate thumb
82
- if settings[:generate_thumb] && res["format"] == "image" && File.extname(file.key) != ".gif"
83
-
84
- cama_uploader_generate_thumbnail(uploaded_io.path, file.key, settings[:folder].split("/").push(@fog_connection_hook_res[:thumb_folder_name]).join("/"))
85
- end
61
+ cama_uploader_generate_thumbnail(uploaded_io.path, res['key']) if settings[:generate_thumb] && res['thumb'].present?
86
62
  FileUtils.rm_f(uploaded_io.path) if settings[:remove_source]
87
63
  res
88
64
  end
89
65
 
90
- # generate thumbnail
91
- def cama_uploader_generate_thumbnail(source_path, filename, folder)
92
- thumb_name = cama_parse_for_thumb_name(filename)
93
- path_thumb = cama_resize_and_crop(source_path, @fog_connection_hook_res[:thumb][:w], @fog_connection_hook_res[:thumb][:h], {overwrite: false, output_name: thumb_name.split("/").last})
94
- upload_file(path_thumb, {generate_thumb: false, same_name: true, remove_source: true, folder: folder})
95
- end
96
-
97
- # destroy file from fog
98
- # sample: "owen/campaign-date-picker_1.png"
99
- def cama_uploader_destroy_file(file_path, destroy_thumb = true)
100
- cama_uploader_init_connection(true)
101
- file = @fog_connection_bucket_dir.files.head("#{current_site.upload_directory_name}/#{file_path}".gsub(/(\/){2,}/, "/"))
102
- _file = cama_uploader_parse_file(file)
103
- if destroy_thumb && _file["format"] == "image" && File.extname(file_path) != ".gif" # destroy thumb
104
- cama_uploader_destroy_file("#{File.dirname(file_path)}/#{cama_parse_for_thumb_name(file.key)}", false) rescue ""
105
- end
106
- file.destroy
107
- end
108
-
109
- # destroy a folder from fog
110
- def cama_uploader_destroy_folder(folder)
111
- cama_uploader_init_connection(true)
112
- if @fog_connection.class.name.include?("AWS")
113
- dir = @fog_connection.directories.get(@fog_connection_hook_res[:bucket_name], prefix: "#{current_site.upload_directory_name}/#{folder}".gsub(/(\/){2,}/, "/"))
114
- dir.files.each{|f| f.destroy }
115
- end
116
- @fog_connection_bucket_dir.files.head("#{current_site.upload_directory_name}/#{folder}/".gsub(/(\/){2,}/, "/")).destroy rescue ""
117
- end
118
-
119
- # add a new folder in fog
120
- def cama_uploader_add_folder(folder)
121
- cama_uploader_init_connection(true)
122
- key = "#{@fog_connection_hook_res[:bucket_name]}/#{current_site.upload_directory_name}/#{folder}/".split("/").clean_empty.join("/")
123
- dir = @fog_connection.directories.create(:key => key)
124
- dir.files.create({:key => '_tmp.txt', content: "", :public => true}) unless @fog_connection.class.name.include?("AWS")
125
- end
126
-
127
- # initialize fog uploader and trigger hook to customize fog storage
128
- def cama_uploader_init_connection(clear_cache = false)
129
- server = current_site.get_option("filesystem_type", "local")
130
- @fog_connection_hook_res ||= {server: server, connection: nil, thumb_folder_name: "thumb", bucket_name: server == "local" ? "media" : current_site.get_option("filesystem_s3_bucket_name"), thumb: {w: 100, h: 100}}; hooks_run("on_uploader", @fog_connection_hook_res)
131
- case @fog_connection_hook_res[:server]
132
- when "local"
133
- Dir.mkdir(Rails.root.join("public", @fog_connection_hook_res[:bucket_name]).to_s) unless Dir.exist?(Rails.root.join("public", @fog_connection_hook_res[:bucket_name]).to_s)
134
- @fog_connection ||= !@fog_connection_hook_res[:connection].present? ? Fog::Storage.new({ :local_root => Rails.root.join("public").to_s, :provider => 'Local', endpoint: (root_url rescue cama_root_url) }) : @fog_connection_hook_res[:connection]
135
- when "s3"
136
- @fog_connection ||= !@fog_connection_hook_res[:connection].present? ? Fog::Storage.new({ :aws_access_key_id => current_site.get_option("filesystem_s3_access_key"), :provider => 'AWS', aws_secret_access_key: current_site.get_option("filesystem_s3_secret_key"), :region => current_site.get_option("filesystem_region") }) : @fog_connection_hook_res[:connection]
137
- end
138
- @fog_connection_bucket_dir ||= @fog_connection.directories.get(@fog_connection_hook_res[:bucket_name])
139
- current_site.set_meta("cache_browser_files_#{@fog_connection_hook_res}", nil) if clear_cache
140
- end
141
-
142
- # verify if this file name already exist
143
- # if the file is already exist, return a new name for this file
144
- # sample: cama_uploader_check_name("my_file/file.txt")
145
- def cama_uploader_check_name(partial_path)
146
- cama_uploader_init_connection()
147
- files = @fog_connection_bucket_dir.files
148
- res = partial_path
149
- if files.head("#{current_site.upload_directory_name}/#{res}".gsub(/(\/){2,}/, "/")).present?
150
- dirname = "#{File.dirname(partial_path)}/" if partial_path.include?("/")
151
- (1..999).each do |i|
152
- res = "#{dirname}#{File.basename(partial_path, File.extname(partial_path))}_#{i}#{File.extname(partial_path)}"
153
- break unless files.head("#{current_site.upload_directory_name}/#{res}".gsub(/(\/){2,}/, "/")).present?
154
- end
155
- end
156
- res.gsub(/(\/){2,}/, "/")
157
- end
158
-
159
- # search a folder by path and return all folders and files
160
- # sample: cama_media_find_folder("test/exit")
161
- def cama_media_find_folder(path = "")
162
- cama_uploader_init_connection(true)
163
-
164
- prefix = "#{current_site.upload_directory_name}/#{path}/".gsub(/(\/){2,}/, "/")
165
- res = {folders: {}, files: []}
166
-
167
- @fog_connection.directories.get(@fog_connection_hook_res[:bucket_name], prefix: prefix).files.each do |file|
168
- res[:files] << cama_uploader_parse_file(file) if file.key =~ %r|#{prefix}[^/]+$| && !file.key.include?('/_tmp.txt')
169
- if file.key =~ %r|#{prefix}([^/]+)/|
170
- folder_name = "#{$~[1]}"
171
- res[:folders][folder_name] = {folders: {}, files: []} unless (folder_name == @fog_connection_hook_res[:thumb_folder_name])
172
- end
173
- end
174
- return res
175
- end
176
-
177
- # search for a file by filename
178
- # sample: cama_media_search_file("")
179
- def cama_media_search_file(filename)
180
- cama_uploader_init_connection(true)
181
-
182
- prefix = current_site.upload_directory_name.gsub(/(\/){2,}/, "/")
183
-
184
- @fog_connection.directories
185
- .get(@fog_connection_hook_res[:bucket_name], prefix: prefix)
186
- .files
187
- .select { |file| file.key.split('/').last.include?(filename) && !file.key.include?('/_tmp.txt') }
188
- .map { |file| cama_uploader_parse_file(file) }
189
- end
190
-
191
- # parse file information of FOG file
192
- def cama_uploader_parse_file(file)
193
- res = {"name"=> File.basename(file.key), "file"=> file.key, "size"=> file.content_length, "url"=> (file.public_url rescue [current_site.get_option("filesystem_s3_endpoint"), file.key ].join("/")), "deleteUrl"=> "" }
194
- ext = File.extname(file.key).sub(".", "").downcase
195
- res["format"] = "unknown"
196
- if "jpg,jpeg,png,gif,bmp,ico".split(",").include?(ext)
197
- if File.extname(res["name"]) == ".gif"
198
- res["thumb"] = res["url"]
199
- else
200
- res["thumb"] = "#{File.dirname(res["url"])}/#{cama_parse_for_thumb_name(file.key)}" rescue ""
201
- end
202
- res["format"] = "image"
203
- end
204
- if "flv,webm,wmv,avi,swf,mp4".split(",").include?(ext)
205
- res["format"] = "video"
206
- end
207
- if "mp3,ogg".split(",").include?(ext)
208
- res["format"] = "audio"
209
- end
210
- if "pdf,xls,xlsx,doc,docx,ppt,pptx,html,txt,xml,json".split(",").include?(ext)
211
- res["format"] = "document"
212
- end
213
- if "zip,7z,rar,tar,bz2,gz,rar2".split(",").include?(ext)
214
- res["format"] = "compress"
215
- end
216
- res["type"] = (MIME::Types.type_for(file.key).first.content_type rescue "")
217
- res
66
+ # generate thumbnail of a existent image
67
+ # key: key of the current file
68
+ # the thumbnail will be saved in my_images/my_img.png => my_images/thumb/my_img.png
69
+ def cama_uploader_generate_thumbnail(uploaded_io, key)
70
+ uploaded_io = File.open(uploaded_io) if uploaded_io.is_a?(String)
71
+ path_thumb = cama_resize_and_crop(uploaded_io.path, cama_uploader.thumb[:w], cama_uploader.thumb[:h])
72
+ thumb = cama_uploader.add_file(path_thumb, cama_uploader.version_path(key), is_thumb: true, same_name: true)
73
+ FileUtils.rm_f(path_thumb)
74
+ thumb
218
75
  end
219
76
 
220
77
  # helper to find an available filename for file_path in that directory
@@ -337,15 +194,16 @@ module CamaleonCms::UploaderHelper
337
194
  tmp_path = args[:path] || Rails.public_path.join("tmp", current_site.id.to_s)
338
195
  FileUtils.mkdir_p(tmp_path) unless Dir.exist?(tmp_path)
339
196
  if uploaded_io.is_a?(String) && (uploaded_io.start_with?("http://") || uploaded_io.start_with?("https://"))
340
- return {error: "#{ct("file_format_error")} (#{args[:formats]})"} unless cama_verify_format(uploaded_io, args[:formats])
341
- name = args[:name] || uploaded_io.split("/").last
197
+ return {error: "#{ct("file_format_error")} (#{args[:formats]})"} unless cama_uploader.class.validate_file_format(uploaded_io, args[:formats])
198
+ uploaded_io = Rails.public_path.join(uploaded_io.sub(current_site.the_url, '')).to_s if uploaded_io.include?(current_site.the_url) # local file
199
+ name = args[:name] || uploaded_io.split("/").last.split('?').first
342
200
  name = "#{File.basename(name, File.extname(name)).underscore}#{File.extname(name)}"
343
201
  path = uploader_verify_name( File.join(tmp_path, name))
344
202
  File.open(path, 'wb'){|file| file.write(open(uploaded_io).read) }
345
203
  path = cama_resize_upload(path, args[:dimension]) if args[:dimension].present?
346
204
  else
347
205
  uploaded_io = File.open(uploaded_io) if uploaded_io.is_a?(String)
348
- return {error: "#{ct("file_format_error")} (#{args[:formats]})"} unless cama_verify_format(uploaded_io.path, args[:formats])
206
+ return {error: "#{ct("file_format_error")} (#{args[:formats]})"} unless cama_uploader.class.validate_file_format(uploaded_io.path, args[:formats])
349
207
  name = args[:name] || uploaded_io.path.split("/").last
350
208
  name = "#{File.basename(name, File.extname(name)).underscore}#{File.extname(name)}"
351
209
  path = uploader_verify_name( File.join(tmp_path, name))
@@ -358,7 +216,7 @@ module CamaleonCms::UploaderHelper
358
216
  # resize image if the format is correct
359
217
  # return resized file path
360
218
  def cama_resize_upload(image_path, dimesion)
361
- if cama_verify_format(image_path, 'image') && dimesion.present?
219
+ if cama_uploader.class.validate_file_format(image_path, 'image') && dimesion.present?
362
220
  r={file: image_path, w: dimesion.split('x')[0], h: dimesion.split('x')[1], w_offset: 0, h_offset: 0, resize: !dimesion.split('x')[2] || dimesion.split('x')[2] == "resize", replace: true, gravity: :north_east}; hooks_run("on_uploader_resize", r)
363
221
  if r[:w].present? && r[:h].present?
364
222
  image_path = cama_resize_and_crop(r[:file], r[:w], r[:h], {overwrite: r[:replace], gravity: r[:gravity] })
@@ -369,29 +227,15 @@ module CamaleonCms::UploaderHelper
369
227
  image_path
370
228
  end
371
229
 
372
- # verify permitted formats (return boolean true | false)
373
- # true: if format is accepted
374
- # false: if format is not accepted
375
- # sample: cama_verify_format(file_path, 'image,audio,docx,xls') => return true if the file extension is in formats
376
- def cama_verify_format(file_path, formats)
377
- return true if formats == "*" || !formats.present?
378
- formats = formats.downcase.split(",")
379
- if formats.include? "image"
380
- formats += "jpg,jpeg,png,gif,bmp,ico".split(',')
381
- end
382
- if formats.include? "video"
383
- formats += "flv,webm,wmv,avi,swf,mp4".split(',')
384
- end
385
- if formats.include? "audio"
386
- formats += "mp3,ogg".split(',')
387
- end
388
- if formats.include? "document"
389
- formats += "pdf,xls,xlsx,doc,docx,ppt,pptx,html,txt,htm,json,xml".split(',')
390
- end
391
- if formats.include?("compress") || formats.include?("compres")
392
- formats += "zip,7z,rar,tar,bz2,gz,rar2".split(',')
230
+ # return the current uploader
231
+ def cama_uploader
232
+ case current_site.get_option("filesystem_type", "local").downcase
233
+ when 's3' || 'aws'
234
+ @cama_uploader ||= CamaleonCmsAwsUploader.new({current_site: current_site})
235
+ else
236
+ @cama_uploader ||= CamaleonCmsLocalUploader.new({current_site: current_site})
393
237
  end
394
- formats.include?(File.extname(file_path).sub(".", "").downcase)
238
+ @cama_uploader
395
239
  end
396
240
 
397
241
  private
@@ -16,11 +16,11 @@ class CamaleonCms::HtmlMailer < ActionMailer::Base
16
16
 
17
17
  # content='', from=nil, attachs=[], url_base='', current_site, template_name, layout_name, extra_data, format, cc_to
18
18
  def sender(email, subject='Hello', data = {})
19
+ data = data.to_sym
19
20
  data[:current_site] = CamaleonCms::Site.main_site.decorate unless data[:current_site].present?
20
21
  data[:current_site] = CamaleonCms::Site.find(data[:current_site]).decorate if data[:current_site].is_a?(Integer)
21
- @current_site = data[:current_site]
22
- current_site = data[:current_site]
23
- data = {cc_to: [], from: current_site.get_option("email"), template_name: 'mailer', layout_name: 'camaleon_cms/mailer', format: 'html'}.merge(data)
22
+ current_site = @current_site = data[:current_site]
23
+ data = {cc_to: current_site.get_option("email_cc", '').split(','), from: current_site.get_option("email_from") || current_site.get_option("email"), template_name: 'mailer', layout_name: 'camaleon_cms/mailer', format: 'html'}.merge(data)
24
24
  @subject = subject
25
25
  @html = data[:content]
26
26
  @url_base = data[:url_base]
@@ -38,8 +38,6 @@ class CamaleonCms::HtmlMailer < ActionMailer::Base
38
38
  authentication: "plain",
39
39
  enable_starttls_auto: true
40
40
  }
41
- data[:cc_to].push(current_site.get_option("email_cc"))
42
- data[:from] = current_site.get_option("email_from", data[:from])
43
41
  end
44
42
  mail_data[:cc] = data[:cc_to].clean_empty.join(",") if data[:cc_to].present?
45
43
  mail_data[:from] = data[:from] if data[:from].present?
@@ -51,9 +49,7 @@ class CamaleonCms::HtmlMailer < ActionMailer::Base
51
49
  theme = current_site.get_theme
52
50
  lookup_context.prefixes.prepend("themes/#{theme.slug}") if theme.settings["gem_mode"]
53
51
  lookup_context.prefixes.prepend("themes/#{theme.slug}/views") unless theme.settings["gem_mode"]
54
- if data[:files].present?
55
- data[:files].each { |attach| attachments["#{File.basename(attach)}"] = File.open(attach, 'rb') { |f| f.read } }
56
- end
52
+ (data[:files] || data[:attachments] || []).each { |attach| attachments["#{File.basename(attach)}"] = File.open(attach, 'rb') { |f| f.read } }
57
53
 
58
54
  layout = data[:layout_name].present? ? data[:layout_name] : false
59
55
  if data[:template_name].present? # render email with template
@@ -26,6 +26,7 @@ class CamaleonCms::CustomFieldGroup < CamaleonCms::CustomField
26
26
  # for select, radio and checkboxes add:
27
27
  # -- multiple_options: [{"title"=>"Option Title", "value"=>"2", "default"=>"1"}, {"title"=>"abcde", "value"=>"3"}]
28
28
  # -- add default for default value
29
+ # -- label_eval: (Boolean, default false), true => will evaluate the label and description of current field using (eval('my_label')) to have translatable|dynamic labels
29
30
  # SAMPLE: my_model.add_field({"name"=>"Sub Title", "slug"=>"subtitle"}, {"field_key"=>"text_box", "translate"=>true, default_value: "Get in Touch"})
30
31
 
31
32
  def add_manual_field(item, options)
@@ -12,12 +12,6 @@ class CamaleonCms::NavMenu < CamaleonCms::TermTaxonomy
12
12
  has_many :children, class_name: "CamaleonCms::NavMenuItem", foreign_key: :parent_id, dependent: :destroy
13
13
  belongs_to :site, :class_name => "CamaleonCms::Site", foreign_key: :parent_id
14
14
 
15
- # add multiple menu items for current menu only used from form
16
- def add_menu_items(menu_data=[])
17
- children.destroy_all
18
- saved_nav_items(self, menu_data) if menu_data.present?
19
- end
20
-
21
15
  # add menu item for current menu
22
16
  # value: (Hash) is a hash object that contains label, type, link
23
17
  # options for type: post | category | post_type | post_tag | external
@@ -26,7 +20,7 @@ class CamaleonCms::NavMenu < CamaleonCms::TermTaxonomy
26
20
  # sample: {label: "my label", type: "category", link: 12}
27
21
  # return item created
28
22
  def append_menu_item (value)
29
- item = children.create({name: value[:label], data_options: {type: value[:type], object_id: value[:link]}})
23
+ item = children.create!({name: value[:label], data_options: {type: value[:type], object_id: value[:link]}})
30
24
  item
31
25
  end
32
26
 
@@ -36,19 +30,6 @@ class CamaleonCms::NavMenu < CamaleonCms::TermTaxonomy
36
30
  end
37
31
 
38
32
  private
39
- def saved_nav_items (nav_menu_item, items)
40
- items.each do |key, value|
41
- item = nav_menu_item.children.new({name: value[:label]})
42
- if item.save!
43
- item.set_meta('_default',{type: value[:type], object_id: value[:link]})
44
- saved_nav_items(item, value[:children]) if value[:children].present?
45
-
46
- # save custom fields for this menu item
47
- item.set_field_values(value[:fields]) if value[:fields].present?
48
- end
49
- end
50
- end
51
-
52
33
  # overwrite termtaxonomy method
53
34
  def destroy_dependencies
54
35
  end