camaleon_cms 2.1.1 → 2.1.1.4

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 (180) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +35 -1
  3. data/app/apps/plugins/attack/config/locales/translation.yml +20 -1
  4. data/app/apps/plugins/contact_form/config/locales/translation.yml +106 -1
  5. data/app/apps/plugins/contact_form/contact_form_helper.rb +44 -27
  6. data/app/apps/plugins/front_cache/config/locales/translation.yml +21 -1
  7. data/app/apps/plugins/front_cache/front_cache_helper.rb +1 -1
  8. data/app/apps/plugins/visibility_post/assets/js/form.js +1 -3
  9. data/app/apps/plugins/visibility_post/visibility_post_helper.rb +2 -4
  10. data/app/assets/images/camaleon_cms/language/de.png +0 -0
  11. data/app/assets/images/camaleon_cms/language/en.png +0 -0
  12. data/app/assets/images/camaleon_cms/language/es.png +0 -0
  13. data/app/assets/images/camaleon_cms/language/fr.png +0 -0
  14. data/app/assets/images/camaleon_cms/language/it.png +0 -0
  15. data/app/assets/images/camaleon_cms/language/nl.png +0 -0
  16. data/app/assets/images/camaleon_cms/language/pl.png +0 -0
  17. data/app/assets/images/camaleon_cms/language/pt.png +0 -0
  18. data/app/assets/images/camaleon_cms/language/pt_br.png +0 -0
  19. data/app/assets/images/camaleon_cms/language/ru.png +0 -0
  20. data/app/assets/images/camaleon_cms/language/zh.png +0 -0
  21. data/app/assets/javascripts/camaleon_cms/admin/_custom_fields.js +3 -11
  22. data/app/assets/javascripts/camaleon_cms/admin/_data.js +2 -6
  23. data/app/assets/javascripts/camaleon_cms/admin/_libraries.js +11 -229
  24. data/app/assets/javascripts/camaleon_cms/admin/_modal.js +11 -37
  25. data/app/assets/javascripts/camaleon_cms/admin/_post.js +27 -22
  26. data/app/assets/javascripts/camaleon_cms/admin/_translator.js +2 -1
  27. data/app/assets/javascripts/camaleon_cms/admin/admin-manifest.js +6 -2
  28. data/app/assets/javascripts/camaleon_cms/admin/bootstrap-datepicker.js +2557 -1689
  29. data/app/assets/javascripts/camaleon_cms/admin/jquery.validate.js +119 -1361
  30. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/nl.js +33 -0
  31. data/app/assets/javascripts/camaleon_cms/admin/momentjs/_moment.js +3606 -0
  32. data/app/assets/javascripts/camaleon_cms/admin/momentjs/ar.js +136 -0
  33. data/app/assets/javascripts/camaleon_cms/admin/momentjs/ca.js +79 -0
  34. data/app/assets/javascripts/camaleon_cms/admin/momentjs/de.js +76 -0
  35. data/app/assets/javascripts/camaleon_cms/admin/momentjs/es.js +79 -0
  36. data/app/assets/javascripts/camaleon_cms/admin/momentjs/fr.js +62 -0
  37. data/app/assets/javascripts/camaleon_cms/admin/momentjs/it.js +70 -0
  38. data/app/assets/javascripts/camaleon_cms/admin/momentjs/ja.js +65 -0
  39. data/app/assets/javascripts/camaleon_cms/admin/momentjs/nl.js +71 -0
  40. data/app/assets/javascripts/camaleon_cms/admin/momentjs/pl.js +105 -0
  41. data/app/assets/javascripts/camaleon_cms/admin/momentjs/pt.js +64 -0
  42. data/app/assets/javascripts/camaleon_cms/admin/momentjs/pt_br.js +60 -0
  43. data/app/assets/javascripts/camaleon_cms/admin/momentjs/ru.js +166 -0
  44. data/app/assets/javascripts/camaleon_cms/admin/momentjs/zh.js +127 -0
  45. data/app/assets/javascripts/camaleon_cms/admin/nav-menu.js +15 -25
  46. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/nl.js +219 -0
  47. data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js.coffee +82 -19
  48. data/app/assets/javascripts/camaleon_cms/admin/user_profile.js +8 -8
  49. data/app/assets/stylesheets/camaleon_cms/admin/_custom_admin.css.scss +19 -2
  50. data/app/assets/stylesheets/camaleon_cms/admin/admin-manifest.css +0 -4
  51. data/app/assets/stylesheets/camaleon_cms/admin/bootstrap-datepicker.css.scss +315 -414
  52. data/app/assets/stylesheets/camaleon_cms/admin/uploader/_uploadfile.css.scss +7 -3
  53. data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +9 -5
  54. data/app/controllers/camaleon_cms/admin/categories_controller.rb +5 -0
  55. data/app/controllers/camaleon_cms/admin/media_controller.rb +27 -10
  56. data/app/controllers/camaleon_cms/admin/posts_controller.rb +9 -19
  57. data/app/controllers/camaleon_cms/admin/sessions_controller.rb +3 -10
  58. data/app/controllers/camaleon_cms/admin/settings/custom_fields_controller.rb +0 -1
  59. data/app/controllers/camaleon_cms/admin/settings/sites_controller.rb +6 -1
  60. data/app/controllers/camaleon_cms/admin/users_controller.rb +1 -8
  61. data/app/controllers/camaleon_cms/admin_controller.rb +5 -4
  62. data/app/controllers/camaleon_cms/apps/plugins_front_controller.rb +0 -8
  63. data/app/controllers/camaleon_cms/camaleon_controller.rb +6 -1
  64. data/app/controllers/camaleon_cms/frontend_controller.rb +11 -8
  65. data/app/decorators/camaleon_cms/category_decorator.rb +2 -1
  66. data/app/decorators/camaleon_cms/post_decorator.rb +28 -1
  67. data/app/decorators/camaleon_cms/post_tag_decorator.rb +1 -0
  68. data/app/decorators/camaleon_cms/post_type_decorator.rb +17 -0
  69. data/app/decorators/camaleon_cms/site_decorator.rb +22 -7
  70. data/app/decorators/camaleon_cms/user_decorator.rb +1 -0
  71. data/app/helpers/camaleon_cms/admin/application_helper.rb +3 -2
  72. data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +13 -25
  73. data/app/helpers/camaleon_cms/admin/post_type_helper.rb +27 -2
  74. data/app/helpers/camaleon_cms/camaleon_helper.rb +0 -16
  75. data/app/helpers/camaleon_cms/captcha_helper.rb +9 -3
  76. data/app/helpers/camaleon_cms/email_helper.rb +27 -8
  77. data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +21 -17
  78. data/app/helpers/camaleon_cms/frontend/seo_helper.rb +5 -3
  79. data/app/helpers/camaleon_cms/html_helper.rb +2 -2
  80. data/app/helpers/camaleon_cms/site_helper.rb +10 -14
  81. data/app/helpers/camaleon_cms/uploader_helper.rb +119 -31
  82. data/app/mailers/camaleon_cms/html_mailer.rb +26 -20
  83. data/app/models/camaleon_cms/custom_field.rb +1 -0
  84. data/app/models/camaleon_cms/custom_field_group.rb +2 -1
  85. data/app/models/camaleon_cms/nav_menu.rb +6 -7
  86. data/app/models/camaleon_cms/nav_menu_item.rb +2 -1
  87. data/app/models/camaleon_cms/post.rb +29 -2
  88. data/app/models/camaleon_cms/post_type.rb +20 -1
  89. data/app/models/camaleon_cms/site.rb +19 -19
  90. data/app/models/camaleon_cms/term_taxonomy.rb +1 -1
  91. data/app/models/concerns/camaleon_cms/custom_fields_read.rb +6 -4
  92. data/app/models/concerns/camaleon_cms/metas.rb +5 -4
  93. data/app/views/camaleon_cms/admin/appearances/nav_menus/_custom_fields.html.erb +4 -2
  94. data/app/views/camaleon_cms/admin/appearances/nav_menus/_external_menu.html.erb +1 -1
  95. data/app/views/camaleon_cms/admin/appearances/nav_menus/index.html.erb +3 -6
  96. data/app/views/camaleon_cms/admin/categories/index.html.erb +1 -0
  97. data/app/views/camaleon_cms/admin/media/_files_list.html.erb +3 -3
  98. data/app/views/camaleon_cms/admin/media/_render_file_item.html.erb +3 -2
  99. data/app/views/camaleon_cms/admin/media/index.html.erb +31 -4
  100. data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +10 -1
  101. data/app/views/camaleon_cms/admin/posts/form.html.erb +6 -2
  102. data/app/views/camaleon_cms/admin/posts/index.html.erb +4 -4
  103. data/app/views/camaleon_cms/admin/search.html.erb +5 -3
  104. data/app/views/camaleon_cms/admin/settings/_file_system_settings.html.erb +5 -5
  105. data/app/views/camaleon_cms/admin/settings/custom_fields/_get_items.html.erb +2 -1
  106. data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +1 -1
  107. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_date.html.erb +3 -4
  108. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_image.html.erb +1 -1
  109. data/app/views/camaleon_cms/admin/settings/custom_fields/form.html.erb +2 -2
  110. data/app/views/camaleon_cms/admin/settings/post_types/_form.html.erb +11 -1
  111. data/app/views/camaleon_cms/admin/settings/post_types/index.html.erb +1 -0
  112. data/app/views/camaleon_cms/admin/users/form.html.erb +30 -55
  113. data/app/views/camaleon_cms/html_mailer/mailer.html.erb +1 -1
  114. data/app/views/camaleon_cms/html_mailer/password_reset.html.erb +3 -0
  115. data/app/views/layouts/camaleon_cms/admin.html.erb +4 -1
  116. data/app/views/layouts/camaleon_cms/admin/_ajax.html.erb +3 -1
  117. data/app/views/layouts/camaleon_cms/admin/_footer.html.erb +1 -1
  118. data/app/views/layouts/camaleon_cms/admin/_header.html.erb +1 -1
  119. data/config/initializers/assets.rb +4 -2
  120. data/config/initializers/model_alias.rb +11 -0
  121. data/config/locales/camaleon_cms/admin/en.yml +2 -0
  122. data/config/locales/camaleon_cms/admin/es.yml +2 -1
  123. data/config/locales/camaleon_cms/admin/it.yml +1 -0
  124. data/config/locales/camaleon_cms/admin/js.yml +42 -1
  125. data/config/locales/camaleon_cms/admin/nl.yml +659 -0
  126. data/config/locales/camaleon_cms/admin/pt_br.yml +1 -0
  127. data/config/locales/camaleon_cms/admin/ru.yml +659 -0
  128. data/config/locales/camaleon_cms/common.yml +127 -0
  129. data/config/locales/camaleon_cms/languages.yml +16 -0
  130. data/config/locales/camaleon_cms/routes.yml +8 -0
  131. data/config/locales/nl.yml +209 -0
  132. data/config/routes.rb +1 -1
  133. data/config/routes/admin.rb +5 -4
  134. data/config/routes/frontend.rb +16 -3
  135. data/config/system.json +2 -3
  136. data/lib/camaleon_cms/engine.rb +5 -1
  137. data/lib/camaleon_cms/version.rb +1 -1
  138. data/lib/ext/array.rb +5 -0
  139. data/lib/generators/camaleon_cms/gem_plugin_generator.rb +1 -1
  140. data/lib/generators/camaleon_cms/gem_plugin_template/app/models/plugins/my_plugin/my_plugin.rb +1 -2
  141. data/lib/generators/camaleon_cms/gem_plugin_template/config/{custom_models.rb → initializers/custom_models.rb} +0 -0
  142. data/lib/plugin_routes.rb +38 -63
  143. data/lib/tasks/camaleon_cms/camaleon_tasks.rake +18 -0
  144. data/lib/tasks/camaleon_cms/rspec_test.rake +7 -4
  145. metadata +43 -54
  146. data/app/assets/javascripts/camaleon_cms/admin/bootstrap-datetimepicker.min.js +0 -26
  147. data/app/assets/javascripts/camaleon_cms/admin/plugins.js +0 -637
  148. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-cool.gif +0 -0
  149. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-cry.gif +0 -0
  150. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-embarassed.gif +0 -0
  151. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif +0 -0
  152. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-frown.gif +0 -0
  153. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-innocent.gif +0 -0
  154. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-kiss.gif +0 -0
  155. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-laughing.gif +0 -0
  156. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-money-mouth.gif +0 -0
  157. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-sealed.gif +0 -0
  158. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-smile.gif +0 -0
  159. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-surprised.gif +0 -0
  160. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-tongue-out.gif +0 -0
  161. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-undecided.gif +0 -0
  162. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-wink.gif +0 -0
  163. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-yell.gif +0 -0
  164. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/visualblocks/css/visualblocks.css +0 -135
  165. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/content.min.css.scss +0 -4
  166. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce-small.eot +0 -0
  167. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce-small.svg +0 -62
  168. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce-small.ttf +0 -0
  169. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce-small.woff +0 -0
  170. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce.eot +0 -0
  171. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce.svg +0 -83
  172. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce.ttf +0 -0
  173. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce.woff +0 -0
  174. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/img/anchor.gif +0 -0
  175. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/img/loader.gif +0 -0
  176. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/img/object.gif +0 -0
  177. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/img/trans.gif +0 -0
  178. data/app/assets/javascripts/camaleon_cms/admin/tinymce/themes/modern/theme.min.js +0 -1
  179. data/app/assets/javascripts/camaleon_cms/admin/tinymce/tinymce.min.js +0 -11
  180. data/app/assets/stylesheets/camaleon_cms/admin/bootstrap-datetimepicker.css.scss +0 -339
@@ -43,11 +43,13 @@ module CamaleonCms::Frontend::SeoHelper
43
43
  # create seo attributes with options + default attributes
44
44
  def cama_build_seo(options = {})
45
45
  options[:image] = current_site.get_option("screenshot", current_site.the_logo) unless options[:image].present?
46
- options[:title] = I18n.transliterate(options[:title].present? ? options[:title] : current_site.the_title)
47
- options[:description] = I18n.transliterate(options[:description].present? ? options[:description].to_s : current_site.the_option("seo_description"))
46
+ options[:title] = current_site.the_title unless options[:title].present?
47
+ options[:description] = current_site.the_option("seo_description") unless options[:description].present?
48
48
  options[:url] = request.original_url
49
+ options[:keywords] = current_site.the_option("keywords") unless options[:keywords].present?
50
+
49
51
  s = {
50
- keywords: I18n.transliterate(options[:keywords].present? ? options[:keywords] : current_site.the_option("keywords")),
52
+ keywords: options[:keywords],
51
53
  author: current_site.get_option('seo_author'),
52
54
  icon: current_site.the_icon,
53
55
  og: {
@@ -119,8 +119,8 @@ module CamaleonCms::HtmlHelper
119
119
  return @_cama_assets_libraries if @_cama_assets_libraries.present?
120
120
  libs = {}
121
121
  libs[:colorpicker] = {js: ['camaleon_cms/admin/bootstrap-colorpicker'], css: ["camaleon_cms/admin/colorpicker.css"]}
122
- libs[:datepicker] = {js: ['camaleon_cms/admin/bootstrap-datepicker']}
123
- libs[:datetimepicker] = {js: ['camaleon_cms/admin/bootstrap-datetimepicker.min']}
122
+ libs[:datepicker] = {js: []}
123
+ libs[:datetimepicker] = {js: [], css: []}
124
124
  libs[:tinymce] = {js: ['camaleon_cms/admin/tinymce/tinymce.min', "camaleon_cms/admin/tinymce/plugins/filemanager/plugin.min"], css: ["camaleon_cms/admin/tinymce/skins/lightgray/content.min"]}
125
125
  libs[:form_builder] = {css:['camaleon_cms/admin/form-builder/formbuilder'],js: ['camaleon_cms/admin/form-builder/vendor', 'camaleon_cms/admin/form-builder/formbuilder' ]}
126
126
  libs[:form_ajax] = {js: ['camaleon_cms/admin/form/jquery.form']}
@@ -15,25 +15,21 @@ module CamaleonCms::SiteHelper
15
15
  if PluginRoutes.get_sites.size == 1
16
16
  site = CamaleonCms::Site.first.decorate
17
17
  else
18
- host = request.original_url.to_s.parse_domain
19
- if host == PluginRoutes.system_info["base_domain"]
20
- site = CamaleonCms::Site.first.decorate rescue nil
21
- else
22
- s = [host]
23
- s << request.subdomain if request.subdomain.present?
24
- site = CamaleonCms::Site.where(slug: s).first.decorate rescue nil
25
- end
18
+ host = [request.original_url.to_s.parse_domain]
19
+ host << request.subdomain if request.subdomain.present?
20
+ site = CamaleonCms::Site.where(slug: host).first.decorate rescue nil
26
21
  end
27
- puts "============================ Please define the $current_site = CamaleonCms::Site.first.decorate " unless site.present?
28
- @current_site = site
22
+ r = {site: site, request: request};
23
+ cama_current_site_helper(r) rescue nil
24
+ puts "============================ Please define the $current_site = CamaleonCms::Site.first.decorate " unless r[:site].present?
25
+ @current_site = r[:site]
29
26
  end
30
27
 
31
28
  # check if current site exist, if not, this will be redirected to main domain
32
29
  def cama_site_check_existence()
33
30
  if !current_site.present?
34
- if (PluginRoutes.main_site).present?
35
- base_domain = PluginRoutes.system_info["base_domain"]
36
- redirect_to cama_root_url(host: base_domain.split(":").first, port: (base_domain.split(":")[1] rescue nil))
31
+ if Cama::Site.main_site.present?
32
+ redirect_to Cama::Site.main_site.decorate.the_url
37
33
  else
38
34
  redirect_to cama_admin_installers_path
39
35
  end
@@ -113,7 +109,7 @@ module CamaleonCms::SiteHelper
113
109
  # load all custom models customized by plugins or templates in custom_models.rb
114
110
  def site_load_custom_models(site)
115
111
  PluginRoutes.enabled_apps(site).each{ |app|
116
- next unless app["path"].present?
112
+ next if !app.present? || !app["path"].present?
117
113
  s = File.join(app["path"], "config", "custom_models.rb")
118
114
  eval(File.read(s)) if File.exist?(s)
119
115
  }
@@ -13,6 +13,7 @@ module CamaleonCms::UploaderHelper
13
13
  # sample: temporal => will save in /rails_path/public/temporal
14
14
  # generate_thumb: true, # generate thumb image if this is image format (default true)
15
15
  # maximum: maximum bytes permitted to upload (default: 1000MG)
16
+ # dimension: dimension for the image (sample: 30x30 | x30 | 30x)
16
17
  # formats: extensions permitted, sample: jpg,png,... or generic: images | videos | audios | documents (default *)
17
18
  # remove_source: Boolean (delete source file after saved if this is true, default false)
18
19
  # same_name: Boolean (save the file with the same name if defined true, else search for a non used name)
@@ -26,8 +27,12 @@ module CamaleonCms::UploaderHelper
26
27
  return {error: "File is empty", file: nil, size: nil}
27
28
  end
28
29
  uploaded_io = File.open(uploaded_io) if uploaded_io.is_a?(String)
30
+
31
+ uploaded_io = File.open(cama_resize_upload(uploaded_io.path, settings[:dimension])) if settings[:dimension].present? # resize file into specific dimensions
32
+
29
33
  cama_uploader_init_connection(true)
30
34
  settings = settings.to_sym
35
+ settings[:uploaded_io] = uploaded_io
31
36
  settings = {
32
37
  folder: "",
33
38
  maximum: 100.megabytes,
@@ -39,29 +44,12 @@ module CamaleonCms::UploaderHelper
39
44
  remove_source: false,
40
45
  same_name: false
41
46
  }.merge(settings)
47
+ hooks_run("before_upload", settings)
42
48
 
43
49
  res = {error: nil}
44
50
 
45
51
  # formats validations
46
- if settings[:formats] != "*"
47
- case settings[:formats]
48
- when "images"
49
- settings[:formats] = "jpg,jpeg,png,gif,bmp"
50
- when "videos"
51
- settings[:formats] = "flv,webm,wmv,avi,swf,mp4"
52
- when "audios"
53
- settings[:formats] = "mp3,ogg"
54
- when "documents"
55
- settings[:formats] = "pdf,xls,xlsx,doc,docx,ppt,pptx,html,txt"
56
- when "compresed"
57
- settings[:formats] = "zip,7z,rar,tar,bz2,gz,rar2"
58
- end
59
-
60
- unless settings[:formats].downcase.split(",").include?(File.extname(settings[:filename]).sub(".", "").downcase)
61
- res[:error] = ct("file_format_error")
62
- return res
63
- end
64
- end
52
+ return {error: "#{ct("file_format_error")} (#{settings[:formats]})"} unless cama_verify_format(uploaded_io.path, settings[:formats])
65
53
 
66
54
  # file size validations
67
55
  if settings[:maximum] < settings[:file_size]
@@ -69,6 +57,8 @@ module CamaleonCms::UploaderHelper
69
57
  return res
70
58
  end
71
59
 
60
+ File.chmod(0644, uploaded_io.path) # fix reading permission (Fix Fog-Local)
61
+
72
62
  # save file
73
63
  if settings[:same_name]
74
64
  partial_path = "#{current_site.upload_directory_name}/#{"#{settings[:folder]}/" if settings[:folder].present?}#{settings[:filename]}"
@@ -90,14 +80,20 @@ module CamaleonCms::UploaderHelper
90
80
 
91
81
  # generate thumb
92
82
  if settings[:generate_thumb] && res["format"] == "image" && File.extname(file.key) != ".gif"
93
- thumb_name = cama_parse_for_thumb_name(file.key)
94
- path_thumb = cama_resize_and_crop(uploaded_io.path, @fog_connection_hook_res[:thumb][:w], @fog_connection_hook_res[:thumb][:h], {overwrite: false, output_name: thumb_name.split("/").last})
95
- thumb_res = upload_file(path_thumb, {generate_thumb: false, same_name: true, remove_source: true, folder: settings[:folder].split("/").push(@fog_connection_hook_res[:thumb_folder_name]).join("/")})
83
+
84
+ cama_uploader_generate_thumbnail(uploaded_io.path, file.key, settings[:folder].split("/").push(@fog_connection_hook_res[:thumb_folder_name]).join("/"))
96
85
  end
97
86
  FileUtils.rm_f(uploaded_io.path) if settings[:remove_source]
98
87
  res
99
88
  end
100
89
 
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
+
101
97
  # destroy file from fog
102
98
  # sample: "owen/campaign-date-picker_1.png"
103
99
  def cama_uploader_destroy_file(file_path, destroy_thumb = true)
@@ -123,9 +119,9 @@ module CamaleonCms::UploaderHelper
123
119
  # add a new folder in fog
124
120
  def cama_uploader_add_folder(folder)
125
121
  cama_uploader_init_connection(true)
126
- key = "#{current_site.upload_directory_name}/#{folder}/".split("/").clean_empty.join("/")
127
- key += '/_tmp.txt' unless @fog_connection.class.name.include?("AWS")
128
- @fog_connection_bucket_dir.files.create({:key => key, content: "", :public => 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")
129
125
  end
130
126
 
131
127
  # initialize fog uploader and trigger hook to customize fog storage
@@ -178,6 +174,20 @@ module CamaleonCms::UploaderHelper
178
174
  return res
179
175
  end
180
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
+
181
191
  # parse file information of FOG file
182
192
  def cama_uploader_parse_file(file)
183
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"=> "" }
@@ -197,8 +207,8 @@ module CamaleonCms::UploaderHelper
197
207
  if "mp3,ogg".split(",").include?(ext)
198
208
  res["format"] = "audio"
199
209
  end
200
- if "pdf,xls,xlsx,doc,docx,ppt,pptx,html,txt".split(",").include?(ext)
201
- res["format"] = "doc"
210
+ if "pdf,xls,xlsx,doc,docx,ppt,pptx,html,txt,xml,json".split(",").include?(ext)
211
+ res["format"] = "document"
202
212
  end
203
213
  if "zip,7z,rar,tar,bz2,gz,rar2".split(",").include?(ext)
204
214
  res["format"] = "compress"
@@ -245,15 +255,19 @@ module CamaleonCms::UploaderHelper
245
255
  # (true => resize the image to this dimension)
246
256
  # (false => crop the image with this dimension)
247
257
  # replace: Boolean (replace current image or create another file)
248
- def cama_crop_image(file_path, w, h, w_offset, h_offset, resize = nil , replace: true)
258
+ def cama_crop_image(file_path, w=nil, h=nil, w_offset = 0, h_offset = 0, resize = false , replace = true)
259
+ force = ""
260
+ force = "!" if w.present? && h.present? && !w.include?("?") && !h.include?("?")
249
261
  image = MiniMagick::Image.open(file_path)
262
+ w = image[:width].to_f > w.sub('?', '').to_i ? w.sub('?', "") : image[:width] if w.present? && w.to_s.include?('?')
263
+ h = image[:height].to_f > h.sub('?', '').to_i ? h.sub('?', "") : image[:height] if h.present? && h.to_s.include?('?')
250
264
  image.combine_options do |i|
251
- i.resize(resize) if resize.present?
252
- i.crop "#{w.to_i}x#{h.to_i}+#{w_offset}+#{h_offset}!"
265
+ i.resize("#{w if w.present?}x#{h if h.present?}#{force}") if resize
266
+ i.crop "#{w if w.present?}x#{h if h.present?}+#{w_offset}+#{h_offset}#{force}" unless resize
253
267
  end
254
268
 
255
269
  res = file_path
256
- if replace
270
+ unless replace
257
271
  ext = File.extname(file_path)
258
272
  res = file_path.gsub(ext, "_crop#{ext}")
259
273
  end
@@ -275,7 +289,11 @@ module CamaleonCms::UploaderHelper
275
289
  def cama_resize_and_crop(file, w, h, settings = {})
276
290
  settings = {gravity: :north_east, overwrite: true, output_name: ""}.merge(settings)
277
291
  img = MiniMagick::Image.open(file)
292
+ w = img[:width].to_f > w.sub('?', '').to_i ? w.sub('?', "") : img[:width] if w.present? && w.to_s.include?('?')
293
+ h = img[:height].to_f > h.sub('?', '').to_i ? h.sub('?', "") : img[:height] if h.present? && h.to_s.include?('?')
278
294
  w_original, h_original = [img[:width].to_f, img[:height].to_f]
295
+ w = w.to_i if w.present?
296
+ h = h.to_i if h.present?
279
297
 
280
298
  # check proportions
281
299
  if w_original * h < h_original * w
@@ -306,6 +324,76 @@ module CamaleonCms::UploaderHelper
306
324
  file
307
325
  end
308
326
 
327
+ # upload tmp file
328
+ # support for url and local path
329
+ # sample:
330
+ # cama_tmp_upload('http://camaleon.tuzitio.com/media/132/logo2.png') ==> /var/rails/my_project/public/tmp/1/logo2.png
331
+ # cama_tmp_upload('/var/www/media/132/logo 2.png') ==> /var/rails/my_project/public/tmp/1/logo-2.png
332
+ # accept args:
333
+ # name: to indicate the name to use, sample: cama_tmp_upload('/var/www/media/132/logo 2.png', {name: 'owen.png', formats: 'images'})
334
+ # formats: extensions permitted, sample: jpg,png,... or generic: images | videos | audios | documents (default *)
335
+ # dimension: 20x30
336
+ def cama_tmp_upload(uploaded_io, args = {})
337
+ tmp_path = args[:path] || Rails.public_path.join("tmp", current_site.id.to_s)
338
+ FileUtils.mkdir_p(tmp_path) unless Dir.exist?(tmp_path)
339
+ 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
342
+ name = "#{File.basename(name, File.extname(name)).underscore}#{File.extname(name)}"
343
+ path = uploader_verify_name( File.join(tmp_path, name))
344
+ File.open(path, 'wb'){|file| file.write(open(uploaded_io).read) }
345
+ path = cama_resize_upload(path, args[:dimension]) if args[:dimension].present?
346
+ else
347
+ 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])
349
+ name = args[:name] || uploaded_io.path.split("/").last
350
+ name = "#{File.basename(name, File.extname(name)).underscore}#{File.extname(name)}"
351
+ path = uploader_verify_name( File.join(tmp_path, name))
352
+ File.open(path, "wb"){|f| f.write(uploaded_io.read) }
353
+ path = cama_resize_upload(path, args[:dimension]) if args[:dimension].present?
354
+ end
355
+ {file_path: path, error: nil}
356
+ end
357
+
358
+ # resize image if the format is correct
359
+ # return resized file path
360
+ def cama_resize_upload(image_path, dimesion)
361
+ if cama_verify_format(image_path, 'image') && dimesion.present?
362
+ 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
+ if r[:w].present? && r[:h].present?
364
+ image_path = cama_resize_and_crop(r[:file], r[:w], r[:h], {overwrite: r[:replace], gravity: r[:gravity] })
365
+ else
366
+ image_path = cama_crop_image(r[:file], r[:w], r[:h], r[:w_offset], r[:h_offset], r[:resize] , r[:replace])
367
+ end
368
+ end
369
+ image_path
370
+ end
371
+
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(',')
393
+ end
394
+ formats.include?(File.extname(file_path).sub(".", "").downcase)
395
+ end
396
+
309
397
  private
310
398
  # helper for resize and crop method
311
399
  def cama_crop_offsets_by_gravity(gravity, original_dimensions, cropped_dimensions)
@@ -14,19 +14,21 @@ class CamaleonCms::HtmlMailer < ActionMailer::Base
14
14
  default from: "Camaleon CMS <owenperedo@gmail.com>"
15
15
  after_action :set_delivery_options
16
16
 
17
- def sender(email, subject='Hello', content='', from=nil, attachs=[], url_base='', current_site, template_name, layout_name, extra_data)
17
+ # content='', from=nil, attachs=[], url_base='', current_site, template_name, layout_name, extra_data, format, cc_to
18
+ def sender(email, subject='Hello', data = {})
19
+ data[:current_site] = CamaleonCms::Site.main_site.decorate unless data[:current_site].present?
20
+ 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)
18
24
  @subject = subject
19
- @html = content
20
- @url_base = url_base
21
- @current_site = current_site
22
- @extra_data = extra_data
25
+ @html = data[:content]
26
+ @url_base = data[:url_base]
27
+ @extra_data = data[:extra_data]
28
+ data[:cc_to] = [data[:cc_to]] if data[:cc_to].is_a?(String) || !data[:cc_to].present?
23
29
 
24
30
  mail_data = {to: email, subject: subject}
25
- mail_data[:from] = from if from.present?
26
-
27
31
  if current_site.get_option("mailer_enabled") == 1
28
- mail_data[:from] = current_site.get_option("email_from")
29
- mail_data[:cc] = current_site.get_option("email_cc")
30
32
  mail_data[:delivery_method] = :smtp
31
33
  mail_data[:delivery_method_options] = {user_name: current_site.get_option("email_username"),
32
34
  password: current_site.get_option("email_pass"),
@@ -36,7 +38,11 @@ class CamaleonCms::HtmlMailer < ActionMailer::Base
36
38
  authentication: "plain",
37
39
  enable_starttls_auto: true
38
40
  }
41
+ data[:cc_to].push(current_site.get_option("email_cc"))
42
+ data[:from] = current_site.get_option("email_from", data[:from])
39
43
  end
44
+ mail_data[:cc] = data[:cc_to].clean_empty.join(",") if data[:cc_to].present?
45
+ mail_data[:from] = data[:from] if data[:from].present?
40
46
 
41
47
  views_dir = "app/apps/"
42
48
  self.prepend_view_path(File.join($camaleon_engine_dir, views_dir).to_s)
@@ -45,19 +51,19 @@ class CamaleonCms::HtmlMailer < ActionMailer::Base
45
51
  theme = current_site.get_theme
46
52
  lookup_context.prefixes.prepend("themes/#{theme.slug}") if theme.settings["gem_mode"]
47
53
  lookup_context.prefixes.prepend("themes/#{theme.slug}/views") unless theme.settings["gem_mode"]
48
-
49
- # run hook "email" to customize values
50
- r = {template_name: template_name, layout_name: layout_name, mail_data: mail_data, files: attachs, format: "html"}
51
- hooks_run("email", r)
52
-
53
- if r[:files].present?
54
- r[:files].each { |attach| attachments["#{File.basename(attach)}"] = File.open(attach, 'rb') { |f| f.read } }
54
+ if data[:files].present?
55
+ data[:files].each { |attach| attachments["#{File.basename(attach)}"] = File.open(attach, 'rb') { |f| f.read } }
55
56
  end
56
57
 
57
- mail(r[:mail_data]) { |format| format.html { render r[:template_name], layout: r[:layout_name] } } if r[:format] == "html"
58
- mail(r[:mail_data]) { |format| format.text { render r[:template_name], layout: r[:layout_name] } } if r[:format] == "txt"
59
- mail(r[:mail_data]) unless r[:format].present?
60
-
58
+ layout = data[:layout_name].present? ? data[:layout_name] : false
59
+ if data[:template_name].present? # render email with template
60
+ mail(mail_data) { |format| format.html { render data[:template_name], layout: layout } } if data[:format] == "html"
61
+ mail(mail_data) { |format| format.text { render data[:template_name], layout: layout } } if data[:format] == "txt"
62
+ else # inline render content
63
+ mail(mail_data) { |format| format.html { render inline: @html, layout: layout } } if data[:format] == "html"
64
+ mail(mail_data) { |format| format.text { render inline: @html, layout: layout } } if data[:format] == "txt"
65
+ end
66
+ mail(mail_data) unless data[:format].present?
61
67
  end
62
68
 
63
69
  private
@@ -7,6 +7,7 @@
7
7
  See the GNU Affero General Public License (GPLv3) for more details.
8
8
  =end
9
9
  class CamaleonCms::CustomField < ActiveRecord::Base
10
+ self.primary_key = :id
10
11
  include CamaleonCms::Metas
11
12
  has_many :metas, ->{ where(object_class: 'CustomField')}, :class_name => "CamaleonCms::Meta", foreign_key: :objectid, dependent: :destroy
12
13
  self.table_name = "#{PluginRoutes.static_system_info["db_prefix"]}custom_fields"
@@ -7,6 +7,7 @@
7
7
  See the GNU Affero General Public License (GPLv3) for more details.
8
8
  =end
9
9
  class CamaleonCms::CustomFieldGroup < CamaleonCms::CustomField
10
+ self.primary_key = :id
10
11
  # attrs required: name, slug, description
11
12
  default_scope { where.not(object_class: '_fields').reorder("#{CamaleonCms::CustomField.table_name}.field_order ASC") }
12
13
 
@@ -68,7 +69,7 @@ class CamaleonCms::CustomFieldGroup < CamaleonCms::CustomField
68
69
  end
69
70
  end
70
71
  ids_deletes = ids_old - ids_saved
71
- self.fields.where(id: ids_deletes).destroy_all if ids_deletes.present?
72
+ self.fields.where(id: ids_deletes).destroy_all if ids_deletes.any?
72
73
  end
73
74
 
74
75
  # generate the caption for this group
@@ -7,7 +7,7 @@
7
7
  See the GNU Affero General Public License (GPLv3) for more details.
8
8
  =end
9
9
  class CamaleonCms::NavMenu < CamaleonCms::TermTaxonomy
10
- default_scope { where(taxonomy: :nav_menu) }
10
+ default_scope { where(taxonomy: :nav_menu).order(id: :asc) }
11
11
  has_many :metas, ->{ where(object_class: 'NavMenu')}, :class_name => "CamaleonCms::Meta", foreign_key: :objectid, dependent: :destroy
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
@@ -44,13 +44,12 @@ class CamaleonCms::NavMenu < CamaleonCms::TermTaxonomy
44
44
  saved_nav_items(item, value[:children]) if value[:children].present?
45
45
 
46
46
  # save custom fields for this menu item
47
- if value[:fields].present?
48
- value[:fields].each do |k, v|
49
- item.save_field_value(k, v)
50
- end
51
- end
52
-
47
+ item.set_field_values(value[:fields]) if value[:fields].present?
53
48
  end
54
49
  end
55
50
  end
51
+
52
+ # overwrite termtaxonomy method
53
+ def destroy_dependencies
54
+ end
56
55
  end
@@ -7,7 +7,7 @@
7
7
  See the GNU Affero General Public License (GPLv3) for more details.
8
8
  =end
9
9
  class CamaleonCms::NavMenuItem < CamaleonCms::TermTaxonomy
10
- default_scope { where(taxonomy: :nav_menu_item) }
10
+ default_scope { where(taxonomy: :nav_menu_item).order(id: :asc) }
11
11
  has_many :metas, ->{ where(object_class: 'NavMenuItem')}, :class_name => "CamaleonCms::Meta", foreign_key: :objectid, dependent: :destroy
12
12
  belongs_to :parent, class_name: "CamaleonCms::NavMenu"
13
13
  belongs_to :parent_item, class_name: "CamaleonCms::NavMenuItem", foreign_key: :parent_id
@@ -15,6 +15,7 @@ class CamaleonCms::NavMenuItem < CamaleonCms::TermTaxonomy
15
15
 
16
16
  after_create :update_count
17
17
  #before_destroy :update_count
18
+ alias_attribute :site_id, :term_group
18
19
 
19
20
  # return the main menu
20
21
  def main_menu