camaleon_cms 2.4.5.5 → 2.4.5.7

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/app/apps/themes/default/views/partials/_comments.html.erb +36 -21
  3. data/app/apps/themes/default/views/post.html.erb +1 -1
  4. data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js.coffee +4 -4
  5. data/app/controllers/camaleon_cms/admin/categories_controller.rb +3 -0
  6. data/app/controllers/camaleon_cms/admin/media_controller.rb +9 -6
  7. data/app/controllers/camaleon_cms/admin/sessions_controller.rb +1 -1
  8. data/app/controllers/camaleon_cms/admin/settings/post_types_controller.rb +2 -0
  9. data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +17 -13
  10. data/app/decorators/camaleon_cms/post_decorator.rb +0 -1
  11. data/app/helpers/camaleon_cms/captcha_helper.rb +1 -1
  12. data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +1 -0
  13. data/app/helpers/camaleon_cms/hooks_helper.rb +6 -1
  14. data/app/helpers/camaleon_cms/site_helper.rb +1 -1
  15. data/app/helpers/camaleon_cms/uploader_helper.rb +36 -27
  16. data/app/models/camaleon_cms/custom_fields_relationship.rb +6 -0
  17. data/app/models/camaleon_cms/media.rb +54 -0
  18. data/app/models/camaleon_cms/post.rb +1 -0
  19. data/app/models/camaleon_cms/site.rb +7 -0
  20. data/app/uploaders/camaleon_cms_aws_uploader.rb +21 -23
  21. data/app/uploaders/camaleon_cms_local_uploader.rb +20 -26
  22. data/app/uploaders/camaleon_cms_uploader.rb +17 -45
  23. data/app/views/camaleon_cms/admin/categories/index.html.erb +2 -2
  24. data/app/views/camaleon_cms/admin/media/_render_file_item.html.erb +53 -36
  25. data/app/views/camaleon_cms/admin/media/index.html.erb +1 -1
  26. data/app/views/camaleon_cms/admin/post_tags/index.html.erb +4 -4
  27. data/app/views/camaleon_cms/admin/posts/index.html.erb +1 -0
  28. data/app/views/camaleon_cms/admin/settings/_configuration_settings.html.erb +5 -1
  29. data/app/views/camaleon_cms/admin/settings/post_types/_form.html.erb +1 -1
  30. data/app/views/camaleon_cms/default_theme/partials/_comments.html.erb +45 -28
  31. data/app/views/camaleon_cms/default_theme/single.html.erb +1 -1
  32. data/config/locales/camaleon_cms/admin/es.yml +1 -0
  33. data/config/locales/camaleon_cms/admin/js.yml +54 -3
  34. data/config/locales/camaleon_cms/admin/ru.yml +39 -28
  35. data/db/migrate/20180124132318_create_media.rb +17 -0
  36. data/lib/camaleon_cms/version.rb +1 -1
  37. data/lib/ext/string.rb +8 -0
  38. data/lib/generators/camaleon_cms/gem_plugin_generator.rb +29 -25
  39. data/lib/plugin_routes.rb +27 -0
  40. data/spec/dummy/config/application.rb +1 -0
  41. data/spec/dummy/config/environments/test.rb +2 -0
  42. data/spec/dummy/db/schema.rb +1 -140
  43. data/spec/dummy/db/test.sqlite3 +0 -0
  44. data/spec/dummy/public/favicon.ico +0 -0
  45. data/spec/factories/post_type.rb +17 -0
  46. data/spec/factories/site.rb +8 -0
  47. data/spec/features/{categories_spec.rb → admin/categories_spec.rb} +1 -1
  48. data/spec/features/{comments_spec.rb → admin/comments_spec.rb} +16 -9
  49. data/spec/features/{contact_form_spec.rb → admin/contact_form_spec.rb} +16 -9
  50. data/spec/features/{content_groups_spec.rb → admin/content_groups_spec.rb} +19 -11
  51. data/spec/features/{custom_fields_spec.rb → admin/custom_fields_spec.rb} +1 -1
  52. data/spec/features/{languages_spec.rb → admin/languages_spec.rb} +1 -1
  53. data/spec/features/{media_spec.rb → admin/media_spec.rb} +1 -1
  54. data/spec/features/{menus_spec.rb → admin/menus_spec.rb} +2 -2
  55. data/spec/features/{pages_spec.rb → admin/pages_spec.rb} +1 -1
  56. data/spec/features/{plugins_spec.rb → admin/plugins_spec.rb} +1 -1
  57. data/spec/features/{posts_spec.rb → admin/posts_spec.rb} +4 -3
  58. data/spec/features/admin/session_spec.rb +102 -0
  59. data/spec/features/{settings_spec.rb → admin/settings_spec.rb} +1 -1
  60. data/spec/features/{shortcodes_spec.rb → admin/shortcodes_spec.rb} +1 -1
  61. data/spec/features/{sites_spec.rb → admin/sites_spec.rb} +22 -14
  62. data/spec/features/{tags_spec.rb → admin/tags_spec.rb} +17 -8
  63. data/spec/features/{themes_spec.rb → admin/themes_spec.rb} +1 -1
  64. data/spec/features/{user_roles_spec.rb → admin/user_roles_spec.rb} +25 -19
  65. data/spec/features/{users_spec.rb → admin/users_spec.rb} +2 -2
  66. data/spec/features/{widgets_spec.rb → admin/widgets_spec.rb} +19 -12
  67. data/spec/features/frontend/pages_spec.rb +86 -5
  68. data/spec/features/frontend/post_type_spec.rb +16 -0
  69. data/spec/helpers/email_helper_spec.rb +1 -1
  70. data/spec/helpers/uploader_helper_spec.rb +56 -0
  71. data/spec/mailers/send_mail_spec.rb +3 -3
  72. data/spec/{decorators/camaleon_cms/post_decorator_spec.rb → models/post_spec.rb} +3 -3
  73. data/spec/rails_helper.rb +79 -0
  74. data/spec/spec_helper.rb +25 -56
  75. data/spec/support/common.rb +10 -24
  76. data/spec/support/fixtures/rails.png +0 -0
  77. data/spec/support/fixtures/rails_tmp.png +0 -0
  78. metadata +64 -50
  79. data/app/views/camaleon_cms/admin/media/_files_list.html.erb +0 -2
  80. data/app/views/camaleon_cms/admin/media/_render_folder_item.html.erb +0 -15
  81. data/spec/decorators/post_type_spec.rb +0 -13
  82. data/spec/features/session_spec.rb +0 -74
@@ -12,10 +12,16 @@ class CamaleonCms::CustomFieldsRelationship < ActiveRecord::Base
12
12
  validates :custom_field_id, presence: true # error on clone model
13
13
 
14
14
  after_save :set_parent_slug
15
+ after_save :update_model_owner # TODO: convert this model into polymorphic
15
16
 
16
17
  private
17
18
 
18
19
  def set_parent_slug
19
20
  # self.update_column('custom_field_slug', self.custom_fields.slug)
20
21
  end
22
+
23
+ # touch owner model
24
+ def update_model_owner
25
+ "CamaleonCms::#{object_class}".constantize.find(objectid).touch rescue nil # owner model
26
+ end
21
27
  end
@@ -0,0 +1,54 @@
1
+ class CamaleonCms::Media < ActiveRecord::Base
2
+ self.table_name = "#{PluginRoutes.static_system_info['db_prefix']}media"
3
+ belongs_to :site, class_name: 'CamaleonCms::Site'
4
+ validates :name, uniqueness: {
5
+ scope: [:site_id, :is_folder, :folder_path],
6
+ message: 'Duplicates not allowed'
7
+ }
8
+ scope :only_folder, ->{ where(is_folder: true) }
9
+ scope :only_file, ->{ where(is_folder: false) }
10
+ default_scope { order(is_folder: :asc, name: :asc) }
11
+ before_save :create_parent_folders
12
+ before_destroy :delete_folder_items
13
+
14
+ def self.search(search_expression = '', folder = nil)
15
+ if search_expression.blank?
16
+ where(folder_path: folder)
17
+ else
18
+ where('name like ?', "%#{search_expression}%")
19
+ end
20
+ end
21
+
22
+ # search file or folder by key
23
+ def self.find_by_key(key)
24
+ key = key.cama_fix_media_key
25
+ if key == '/'
26
+ where(folder_path: File.dirname(key))
27
+ else
28
+ where(folder_path: File.dirname(key), name: File.basename(key))
29
+ end
30
+ end
31
+
32
+ # return all items of current folder
33
+ def items
34
+ coll = is_public ? site.public_media : site.private_media
35
+ coll.where(folder_path: "#{folder_path}/#{name}".cama_fix_media_key)
36
+ end
37
+
38
+ private
39
+ # recover folder or file format
40
+ def create_parent_folders
41
+ coll = is_public ? site.public_media : site.private_media
42
+ _p = []
43
+ folder_path.split('/').each do |f_name|
44
+ _path = ('/'+_p.join('/')).cama_fix_media_key
45
+ coll.only_folder.where(name: f_name, folder_path: _path).first_or_create!() if "#{_path}/#{f_name}".cama_fix_media_key != '/'
46
+ _p.push(f_name)
47
+ end
48
+ end
49
+
50
+ # return all children items
51
+ def delete_folder_items
52
+ items.destroy_all if is_folder
53
+ end
54
+ end
@@ -152,6 +152,7 @@ class CamaleonCms::Post < CamaleonCms::PostDefault
152
152
  # check if the post can be commented
153
153
  # sample: @post.can_commented?
154
154
  # return Boolean (true/false)
155
+ # to enable comments for current post, use this: post.set_meta('has_comments', '1'). Note: Parent PostType should be enabled for comments too: post_type.set_option('has_comments', true)
155
156
  def can_commented?
156
157
  manage_comments? && get_meta('has_comments').to_s == "1"
157
158
  end
@@ -16,6 +16,8 @@ class CamaleonCms::Site < CamaleonCms::TermTaxonomy
16
16
  has_many :posts, through: :post_types, :source => :posts
17
17
  has_many :plugins, :class_name => "CamaleonCms::Plugin", foreign_key: :parent_id, dependent: :destroy
18
18
  has_many :themes, :class_name => "CamaleonCms::Theme", foreign_key: :parent_id, dependent: :destroy
19
+ has_many :public_media, ->{ where(is_public: true) }, class_name: 'CamaleonCms::Media', foreign_key: :site_id, dependent: :destroy
20
+ has_many :private_media, ->{ where(is_public: false) }, class_name: 'CamaleonCms::Media', foreign_key: :site_id, dependent: :destroy
19
21
 
20
22
  after_create :default_settings
21
23
  after_create :set_default_user_roles
@@ -107,6 +109,11 @@ class CamaleonCms::Site < CamaleonCms::TermTaxonomy
107
109
  def security_user_register_captcha_enabled?
108
110
  get_option('security_captcha_user_register', false) == true
109
111
  end
112
+
113
+ # check if current site permit capctha for anonymous comments
114
+ def is_enable_captcha_for_comments?
115
+ get_option('enable_captcha_for_comments', false)
116
+ end
110
117
 
111
118
  def need_validate_email?
112
119
  get_option('need_validate_email', false) == true
@@ -12,15 +12,13 @@ class CamaleonCmsAwsUploader < CamaleonCmsUploader
12
12
 
13
13
  # recover all files from AWS and parse it to save into DB as cache
14
14
  def browser_files
15
- objects = {}
16
- objects['/'] = {files: {}, folders: {}}
17
15
  bucket.objects(@aws_settings["inner_folder"].present? ? {prefix: @aws_settings["inner_folder"]} : nil).each do |file|
18
- cache_item(file_parse(file), objects)
16
+ next if File.dirname(file.key).split('/').pop == 'thumb'
17
+ cache_item(file_parse(file))
19
18
  end
20
- @current_site.set_meta(cache_key, objects)
21
- objects
22
19
  end
23
20
 
21
+ # load media files from a specific folder path
24
22
  def objects(prefix = '/', sort = 'created_at')
25
23
  if @aws_settings["inner_folder"].present?
26
24
  prefix = "#{@aws_settings["inner_folder"]}/#{prefix}".gsub('//', '/')
@@ -32,23 +30,21 @@ class CamaleonCmsAwsUploader < CamaleonCmsUploader
32
30
  # parse an AWS file into custom file_object
33
31
  def file_parse(s3_file)
34
32
  key = s3_file.is_a?(String) ? s3_file : s3_file.key
35
- key = "/#{key}" unless key.starts_with?('/')
33
+ key = key.cama_fix_media_key
36
34
  is_dir = s3_file.is_a?(String) || File.extname(key) == ''
37
35
  res = {
38
36
  "name" => File.basename(key),
39
- "key" => key,
37
+ "folder_path" => File.dirname(key),
40
38
  "url" => is_dir ? '' : (@cloudfront.present? ? File.join(@cloudfront, key) : s3_file.public_url),
41
39
  "is_folder" => is_dir,
42
- "size" => is_dir ? 0 : s3_file.size.round(2),
43
- "format" => is_dir ? 'folder' : self.class.get_file_format(key),
44
- "deleteUrl" => '',
40
+ "file_size" => is_dir ? 0 : s3_file.size.round(2),
45
41
  "thumb" => '',
46
- 'type' => is_dir ? '' : (s3_file.content_type rescue (MIME::Types.type_for(key).first.content_type rescue "")),
42
+ 'file_type' => is_dir ? '' : self.class.get_file_format(key),
47
43
  'created_at' => is_dir ? '' : s3_file.last_modified,
48
44
  'dimension' => ''
49
45
  }.with_indifferent_access
50
- res["thumb"] = version_path(res['url']) if res['format'] == 'image' && File.extname(res['name']).downcase != '.gif'
51
- # if res['format'] == 'image' # TODO: Recover image dimension (suggestion: save dimesion as metadata)
46
+ res["thumb"] = version_path(res['url']).sub('.svg', '.jpg') if res['file_type'] == 'image' && File.extname(res['name']).downcase != '.gif'
47
+ res['key'] = File.join(res['folder_path'], res['name'])
52
48
  @aws_settings[:aws_file_read_settings].call(res, s3_file)
53
49
  end
54
50
 
@@ -60,14 +56,15 @@ class CamaleonCmsAwsUploader < CamaleonCmsUploader
60
56
  def add_file(uploaded_io_or_file_path, key, args = {})
61
57
  args, res = {same_name: false, is_thumb: false}.merge(args), nil
62
58
  key = "#{@aws_settings["inner_folder"]}/#{key}" if @aws_settings["inner_folder"].present? && !args[:is_thumb]
59
+ key = key.cama_fix_media_key
63
60
  key = search_new_key(key) unless args[:same_name]
64
-
61
+
65
62
  if @instance # private hook to upload files by different way, add file data into result_data
66
63
  _args={result_data: nil, file: uploaded_io_or_file_path, key: key, args: args, klass: self}; @instance.hooks_run('uploader_aws_before_upload', _args)
67
64
  return _args[:result_data] if _args[:result_data].present?
68
65
  end
69
-
70
- s3_file = bucket.object(key.split('/').clean_empty.join('/'))
66
+
67
+ s3_file = bucket.object(key.slice(1..-1))
71
68
  s3_file.upload_file(uploaded_io_or_file_path.is_a?(String) ? uploaded_io_or_file_path : uploaded_io_or_file_path.path, @aws_settings[:aws_file_upload_settings].call({acl: 'public-read'}))
72
69
  res = cache_item(file_parse(s3_file)) unless args[:is_thumb]
73
70
  res
@@ -76,26 +73,27 @@ class CamaleonCmsAwsUploader < CamaleonCmsUploader
76
73
  # add new folder to AWS with :key
77
74
  def add_folder(key)
78
75
  key = "#{@aws_settings["inner_folder"]}/#{key}" if @aws_settings["inner_folder"].present?
79
- s3_file = bucket.object(key.split('/').clean_empty.join('/') << '/')
76
+ key = key.cama_fix_media_key
77
+ s3_file = bucket.object(key.slice(1..-1) << '/')
80
78
  s3_file.put(body: nil)
81
79
  cache_item(file_parse(s3_file))
82
- s3_file
83
80
  end
84
81
 
85
82
  # delete a folder in AWS with :key
86
83
  def delete_folder(key)
87
84
  key = "#{@aws_settings["inner_folder"]}/#{key}" if @aws_settings["inner_folder"].present?
88
- bucket.objects(prefix: key.split('/').clean_empty.join('/') << '/').delete
89
- reload
85
+ key = key.cama_fix_media_key
86
+ bucket.objects(prefix: key.slice(1..-1) << '/').delete
87
+ get_media_collection.find_by_key(key).take.destroy
90
88
  end
91
89
 
92
90
  # delete a file in AWS with :key
93
91
  def delete_file(key)
94
92
  key = "#{@aws_settings["inner_folder"]}/#{key}" if @aws_settings["inner_folder"].present?
95
- bucket.object(key.split('/').clean_empty.join('/')).delete rescue ''
93
+ key = key.cama_fix_media_key
94
+ bucket.object(key.slice(1..-1)).delete rescue ''
96
95
  @instance.hooks_run('after_delete', key)
97
-
98
- reload
96
+ get_media_collection.find_by_key(key).take.destroy
99
97
  end
100
98
 
101
99
  # initialize a bucket with AWS configurations
@@ -1,18 +1,13 @@
1
1
  class CamaleonCmsLocalUploader < CamaleonCmsUploader
2
2
  PRIVATE_DIRECTORY = 'private'
3
3
  def browser_files(prefix = '/', objects = {})
4
- objects[prefix] = {files: {}, folders: {}}
5
4
  path = File.join(@root_folder, prefix)
6
5
  Dir.entries(path).each do |f_name|
7
6
  next if f_name == '..' || f_name == '.' || f_name == 'thumb'
8
- f_path = File.join(path, f_name)
9
- key = parse_key(f_path)
10
- obj = get_file(key) || file_parse(key)
11
- cache_item(obj, objects)
12
- browser_files(File.join(prefix, obj['name']), objects) if obj['format'] == 'folder'
7
+ obj = file_parse(File.join(path, f_name).sub(@root_folder, '').cama_fix_media_key)
8
+ cache_item(obj)
9
+ browser_files(File.join(prefix, obj['name'])) if obj['is_folder']
13
10
  end
14
- @current_site.set_meta(cache_key, objects) if prefix == '/'
15
- objects
16
11
  end
17
12
 
18
13
  # return the full file path for private file with key
@@ -39,36 +34,35 @@ class CamaleonCmsLocalUploader < CamaleonCmsUploader
39
34
  file_path = File.join(@root_folder, key)
40
35
  url_path, is_dir = file_path.sub(Rails.root.join('public').to_s, ''), File.directory?(file_path)
41
36
  res = {
42
- "name" => File.basename(file_path),
43
- "key" => parse_key(file_path),
37
+ "name" => File.basename(key),
38
+ "folder_path" => File.dirname(key),
44
39
  "url" => is_dir ? '' : (is_private_uploader? ? url_path.sub("#{@root_folder}/", '') : File.join(@current_site.decorate.the_url(as_path: true, locale: false, skip_relative_url_root: true), url_path)),
45
40
  "is_folder" => is_dir,
46
- "size" => is_dir ? 0 : File.size(file_path).round(2),
47
- "format" => is_dir ? 'folder' : self.class.get_file_format(file_path),
48
- "deleteUrl" => '',
41
+ "file_size" => is_dir ? 0 : File.size(file_path).round(2),
49
42
  "thumb" => '',
50
- 'type' => (MIME::Types.type_for(file_path).first.content_type rescue ""),
51
- 'created_at' => File.mtime(file_path),
43
+ 'file_type' => self.class.get_file_format(file_path),
52
44
  'dimension' => ''
53
45
  }.with_indifferent_access
54
- res["thumb"] = version_path(res['url']) if res['format'] == 'image' && File.extname(file_path).downcase != '.gif'
55
- if res['format'] == 'image'
46
+ res['key'] = File.join(res['folder_path'], res['name'])
47
+ res["thumb"] = (is_private_uploader? ? '/admin/media/download_private_file?file=' + version_path(key).slice(1..-1) : version_path(res['url'])) if res['file_type'] == 'image' && File.extname(file_path).downcase != '.gif'
48
+ if res['file_type'] == 'image'
49
+ res["thumb"].sub! '.svg', '.jpg'
56
50
  im = MiniMagick::Image.open(file_path)
57
51
  res['dimension'] = "#{im[:width]}x#{im[:height]}"
58
52
  end
59
53
  res
60
54
  end
61
55
 
62
- #
56
+ # save a file into local folder
63
57
  def add_file(uploaded_io_or_file_path, key, args = {})
64
58
  args, res = {same_name: false, is_thumb: false}.merge(args), nil
65
59
  key = search_new_key(key) unless args[:same_name]
66
-
60
+
67
61
  if @instance # private hook to upload files by different way, add file data into result_data
68
62
  _args={result_data: nil, file: uploaded_io_or_file_path, key: key, args: args, klass: self}; @instance.hooks_run('uploader_local_before_upload', _args)
69
63
  return _args[:result_data] if _args[:result_data].present?
70
64
  end
71
-
65
+
72
66
  add_folder(File.dirname(key)) if File.dirname(key).present?
73
67
  upload_io = uploaded_io_or_file_path.is_a?(String) ? File.open(uploaded_io_or_file_path) : uploaded_io_or_file_path
74
68
  File.open(File.join(@root_folder, key), 'wb'){|file| file.write(upload_io.read) }
@@ -76,6 +70,7 @@ class CamaleonCmsLocalUploader < CamaleonCmsUploader
76
70
  res
77
71
  end
78
72
 
73
+ # create a new folder into local directory
79
74
  def add_folder(key)
80
75
  d, is_new_folder = File.join(@root_folder, key).to_s, false
81
76
  unless Dir.exist?(d)
@@ -87,24 +82,23 @@ class CamaleonCmsLocalUploader < CamaleonCmsUploader
87
82
  f
88
83
  end
89
84
 
85
+ # remove an existent folder
90
86
  def delete_folder(key)
91
87
  folder = File.join(@root_folder, key)
92
88
  FileUtils.rm_rf(folder) if Dir.exist? folder
93
- reload
89
+ get_media_collection.find_by_key(key).take.destroy
94
90
  end
95
91
 
92
+ # remove an existent file
96
93
  def delete_file(key)
97
94
  file = File.join(@root_folder, key)
98
95
  FileUtils.rm(file) if File.exist? file
99
96
  @instance.hooks_run('after_delete', key)
100
-
101
- reload
97
+ get_media_collection.find_by_key(key).take.destroy
102
98
  end
103
99
 
104
100
  # convert a real file path into file key
105
101
  def parse_key(file_path)
106
- r = file_path.sub(@root_folder, '')
107
- r = "/#{r}" unless r.starts_with?('/')
108
- r
102
+ file_path.sub(@root_folder, '').cama_fix_media_key
109
103
  end
110
104
  end
@@ -16,44 +16,28 @@ class CamaleonCmsUploader
16
16
 
17
17
  end
18
18
 
19
- # return all files structure, within folder prefix
20
- # return json like:
21
- # {files: {'file_name': {'name'=> 'a.jpg', key: '/test/a.jpg', url: '', url: '', size: '', format: '', thumb: 'thumb_url', type: '', created_at: '', dimension: '120x120'}}, folders: {'folder name' => {name: 'folder name', key: '/folder name', ...}}}
22
- # sort: (String, default 'created_at'), accept for: created_at | name | size | type | format
19
+ # load media files from a specific folder path
23
20
  def objects(prefix = '/', sort = 'created_at')
24
- prefix = prefix.cama_fix_slash
25
- prefix = "/#{prefix}" unless prefix.starts_with?('/')
26
- db = @current_site.get_meta(cache_key, nil) || browser_files
27
- res = db[prefix] || {files: {}, folders: {}}
28
-
21
+ prefix = prefix.cama_fix_media_key
22
+ browser_files unless get_media_collection.any?
23
+ res = ['/', ''].include?(prefix) ? get_media_collection.where(folder_path: '/') : get_media_collection.find_by_key(prefix).take.try(:items)
29
24
  # Private hook to recover custom files to include in current list where data can be modified to add custom{files, folders}
30
25
  # Note: this hooks doesn't have access to public vars like params. requests, ...
31
26
  if @instance
32
27
  args={data: res, prefix: prefix}; @instance.hooks_run('uploader_list_objects', args)
33
28
  res = args[:data]
34
29
  end
35
-
36
- res[:files] = res[:files].sort_by{|k, v| v[sort] }.reverse.to_h
37
- res[:folders] = res[:folders].sort_by{|k, v| v['name'] }.reverse.to_h
38
30
  res
39
31
  end
40
32
 
41
33
  # clean cached of files structure saved into DB
42
34
  def clear_cache
43
- @current_site.set_meta(cache_key, nil)
35
+ get_media_collection.destroy_all
44
36
  end
45
37
 
46
38
  # search for folders or files that includes search_text in their names
47
39
  def search(search_text)
48
- res = {files: {}, folders: {}}
49
- (@current_site.get_meta(cache_key, nil) || browser_files).each do |folder_key, object|
50
- res[:folders][folder_key] = get_file(folder_key) if !['', '/'].include?(folder_key) && folder_key.split('/').last.include?(search_text)
51
- object[:files].each do |file_key, obj|
52
- res[:files][file_key] = obj if file_key.include?(search_text)
53
- end
54
- res
55
- end
56
- res
40
+ get_media_collection.search(search_text)
57
41
  end
58
42
 
59
43
  # reload cache files structure
@@ -65,23 +49,17 @@ class CamaleonCmsUploader
65
49
  # file_parsed: (HASH) File parsed object
66
50
  # objects_db: HASH Object where to add the current object (optional)
67
51
  def cache_item(file_parsed, _objects_db = nil, custom_cache_key = nil)
68
- _cache_key = custom_cache_key || cache_key
69
- objects_db = _objects_db || @current_site.get_meta(_cache_key, {}) || {}
70
- prefix = File.dirname(file_parsed['key'])
71
-
72
- s = prefix.split('/').clean_empty
73
- return file_parsed if s.last == 'thumb'
74
- s.each_with_index{|_s, i| k = "/#{File.join(s.slice(0, i), _s)}".cama_fix_slash; cache_item(file_parse(k), objects_db) unless objects_db[k].present? } unless ['/', '', '.'].include?(prefix)
75
-
76
- objects_db[prefix] = {files: {}, folders: {}} if objects_db[prefix].nil?
77
- if file_parsed['format'] == 'folder'
78
- objects_db[prefix][:folders][file_parsed['name']] = file_parsed
79
- else
80
- objects_db[prefix][:files][file_parsed['name']] = file_parsed
52
+ unless get_media_collection.where(name: file_parsed['name'], folder_path: file_parsed['folder_path']).any?
53
+ a = get_media_collection.new(file_parsed.except('key'))
54
+ a.save!
81
55
  end
82
- @current_site.set_meta(_cache_key, objects_db) if _objects_db.nil?
83
56
  file_parsed
84
57
  end
58
+
59
+ # return the media collection for current situation
60
+ def get_media_collection
61
+ is_private_uploader? ? @current_site.public_media : @current_site.private_media
62
+ end
85
63
 
86
64
 
87
65
  # convert current string path into file version_path, sample:
@@ -144,10 +122,10 @@ class CamaleonCmsUploader
144
122
  # sample: search_new_key("my_file/file.txt")
145
123
  def search_new_key(key)
146
124
  _key = key
147
- if get_file(key).present?
125
+ if get_media_collection.find_by_key(key).any?
148
126
  (1..999).each do |i|
149
127
  _key = key.cama_add_postfix_file_name("_#{i}")
150
- break unless get_file(_key).present?
128
+ break unless get_media_collection.find_by_key(_key).any?
151
129
  end
152
130
  end
153
131
  _key
@@ -155,12 +133,7 @@ class CamaleonCmsUploader
155
133
 
156
134
  # check if file with :key exist and return parsed_file, else return nil
157
135
  def get_file(key, use_cache = true)
158
- if use_cache
159
- db = (@current_site.get_meta(cache_key) || {})[File.dirname(key)] || {}
160
- else
161
- db = objects(File.dirname(key)) unless use_cache
162
- end
163
- (db[:files][File.basename(key)] || db[:folders][File.basename(key)]) rescue nil
136
+ # deprecated
164
137
  end
165
138
 
166
139
  private
@@ -168,5 +141,4 @@ class CamaleonCmsUploader
168
141
  "cama_media_cache#{'_private' if is_private_uploader?}"
169
142
  end
170
143
  def is_private_uploader?() end
171
-
172
144
  end
@@ -16,7 +16,7 @@
16
16
  </h4>
17
17
  </div>
18
18
  <div class="panel-body">
19
- <table class="table table-responsive table-hover table-striped">
19
+ <table class="table table-responsive table-hover table-striped" id="categories-table-list">
20
20
  <thead>
21
21
  <tr>
22
22
  <th><%= t('camaleon_cms.admin.table.name')%></th>
@@ -31,7 +31,7 @@
31
31
  <%
32
32
  def _item_html(item, pos = 0) item = item.decorate
33
33
  %>
34
- <tr data-id="<%= item.id %>">
34
+ <tr data-id="<%= item.id %>" data-parent="<%= item.parent_id %>">
35
35
  <td><%= raw('—' * pos) %> <%= item.the_title %></td>
36
36
  <td><%= item.the_content %></td>
37
37
  <td><%= item.the_slug %></td>
@@ -1,40 +1,57 @@
1
- <% files.each do |file| next if @media_formats.present? && !@media_formats.include?(file["format"]) && !@media_formats.include?(file["url"].split('.').last) %>
2
- <% file['url'] = download_private_file_cama_admin_media_url(file: file[:url]) if params[:private].present? %>
3
- <div class="media_item file_item <%= file["format"] %>_format" data-key="<%= file["name"] %>">
4
- <div class="thumb">
5
- <% case file["format"] %>
6
- <% when "image" %>
7
- <img src="<%= file["thumb"] %>" alt="">
8
- <% when "audio" %>
9
- <i class="fa fa-file-audio-o"></i>
10
- <% when "video" %>
11
- <i class="fa fa-film"></i>
12
- <% when "compress" %>
13
- <i class="fa fa-file-archive-o"></i>
14
- <% when "doc" %>
15
- <% when "document" %>
16
- <i class="fa fa-file-text-o"></i>
17
- <% else %>
18
- <i class="fa fa-file-o"></i>
19
- <% end %>
1
+ <% files.each do |file| key = params[:search] ? File.join(file["folder_path"], file["name"]) : file["name"] %>
2
+ <% if file['is_folder'] %>
3
+ <div class="media_item folder_item" data-key="<%= key %>">
4
+ <div class="thumb">
5
+ <i class="fa fa-folder"></i>
6
+ </div>
7
+ <div class="label_thumb">
8
+ <%= file['name'] %>
9
+ </div>
10
+ <% if @show_file_actions %>
11
+ <div class="actions">
12
+ <a href="#" class="del_folder"><i class="fa fa-trash"></i></a>
13
+ </div>
14
+ <% end %>
20
15
  </div>
21
- <div class="label_thumb">
22
- <%= file["name"] %>
23
- </div>
24
- <textarea class="hidden data_value"><%= raw file.to_json %></textarea>
25
- <div class="actions">
26
- <% if file['format'] == 'image' && File.extname(file['name']).downcase != '.gif' %>
27
- <% args = {res: true, file: file}; hooks_run('file_manager_edit_file', args) %>
28
- <% if args[:res] %>
29
- <a href="#" class="edit_item btn btn-primary btn-xs" <%= 'data-permit-overwrite="true"' if @show_file_actions %>><i class="fa fa-pencil"></i></a>
16
+ <% else %>
17
+ <% next if @media_formats.present? && !@media_formats.include?(file["file_type"]) && !@media_formats.include?(file["url"].split('.').last) %>
18
+ <% file['url'] = download_private_file_cama_admin_media_url(file: file[:url]) if params[:private].present? %>
19
+ <div class="media_item file_item <%= file["file_type"] %>_format" data-key="<%= key %>">
20
+ <div class="thumb">
21
+ <% case file["file_type"] %>
22
+ <% when "image" %>
23
+ <img src="<%= file["thumb"] %>" alt="">
24
+ <% when "audio" %>
25
+ <i class="fa fa-file-audio-o"></i>
26
+ <% when "video" %>
27
+ <i class="fa fa-film"></i>
28
+ <% when "compress" %>
29
+ <i class="fa fa-file-archive-o"></i>
30
+ <% when "doc" %>
31
+ <% when "document" %>
32
+ <i class="fa fa-file-text-o"></i>
33
+ <% else %>
34
+ <i class="fa fa-file-o"></i>
30
35
  <% end %>
31
- <% end %>
32
- <% if @show_file_actions %>
33
- <% args = {res: true, file: file}; hooks_run('file_manager_del_file', args) %>
34
- <% if args[:res] %>
35
- <a href="#" class="del_item btn btn-danger btn-xs"><i class="fa fa-trash"></i></a>
36
+ </div>
37
+ <div class="label_thumb">
38
+ <%= file["name"] %>
39
+ </div>
40
+ <textarea class="hidden data_value"><%= raw file.to_json %></textarea>
41
+ <div class="actions">
42
+ <% if file['file_type'] == 'image' && File.extname(file['name']).downcase != '.gif' %>
43
+ <% args = {res: true, file: file}; hooks_run('file_manager_edit_file', args) %>
44
+ <% if args[:res] %>
45
+ <a href="#" class="edit_item btn btn-primary btn-xs" <%= 'data-permit-overwrite="true"' if @show_file_actions %>><i class="fa fa-pencil"></i></a>
46
+ <% end %>
36
47
  <% end %>
37
- <% end %>
38
- </div>
39
- </div>
48
+ <% if @show_file_actions %>
49
+ <% args = {res: true, file: file}; hooks_run('file_manager_del_file', args) %>
50
+ <% if args[:res] %>
51
+ <a href="#" class="del_item btn btn-danger btn-xs"><i class="fa fa-trash"></i></a>
52
+ <% end %>
53
+ <% end %>
54
+ </div>
55
+ </div>
56
+ <% end %>
40
57
  <% end %>