camaleon_cms 2.4.5.5 → 2.4.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/apps/themes/default/views/partials/_comments.html.erb +36 -21
- data/app/apps/themes/default/views/post.html.erb +1 -1
- data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js.coffee +4 -4
- data/app/controllers/camaleon_cms/admin/categories_controller.rb +3 -0
- data/app/controllers/camaleon_cms/admin/media_controller.rb +9 -6
- data/app/controllers/camaleon_cms/admin/sessions_controller.rb +1 -1
- data/app/controllers/camaleon_cms/admin/settings/post_types_controller.rb +2 -0
- data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +17 -13
- data/app/decorators/camaleon_cms/post_decorator.rb +0 -1
- data/app/helpers/camaleon_cms/captcha_helper.rb +1 -1
- data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +1 -0
- data/app/helpers/camaleon_cms/hooks_helper.rb +6 -1
- data/app/helpers/camaleon_cms/site_helper.rb +1 -1
- data/app/helpers/camaleon_cms/uploader_helper.rb +36 -27
- data/app/models/camaleon_cms/custom_fields_relationship.rb +6 -0
- data/app/models/camaleon_cms/media.rb +54 -0
- data/app/models/camaleon_cms/post.rb +1 -0
- data/app/models/camaleon_cms/site.rb +7 -0
- data/app/uploaders/camaleon_cms_aws_uploader.rb +21 -23
- data/app/uploaders/camaleon_cms_local_uploader.rb +20 -26
- data/app/uploaders/camaleon_cms_uploader.rb +17 -45
- data/app/views/camaleon_cms/admin/categories/index.html.erb +2 -2
- data/app/views/camaleon_cms/admin/media/_render_file_item.html.erb +53 -36
- data/app/views/camaleon_cms/admin/media/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/post_tags/index.html.erb +4 -4
- data/app/views/camaleon_cms/admin/posts/index.html.erb +1 -0
- data/app/views/camaleon_cms/admin/settings/_configuration_settings.html.erb +5 -1
- data/app/views/camaleon_cms/admin/settings/post_types/_form.html.erb +1 -1
- data/app/views/camaleon_cms/default_theme/partials/_comments.html.erb +45 -28
- data/app/views/camaleon_cms/default_theme/single.html.erb +1 -1
- data/config/locales/camaleon_cms/admin/es.yml +1 -0
- data/config/locales/camaleon_cms/admin/js.yml +54 -3
- data/config/locales/camaleon_cms/admin/ru.yml +39 -28
- data/db/migrate/20180124132318_create_media.rb +17 -0
- data/lib/camaleon_cms/version.rb +1 -1
- data/lib/ext/string.rb +8 -0
- data/lib/generators/camaleon_cms/gem_plugin_generator.rb +29 -25
- data/lib/plugin_routes.rb +27 -0
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/config/environments/test.rb +2 -0
- data/spec/dummy/db/schema.rb +1 -140
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/post_type.rb +17 -0
- data/spec/factories/site.rb +8 -0
- data/spec/features/{categories_spec.rb → admin/categories_spec.rb} +1 -1
- data/spec/features/{comments_spec.rb → admin/comments_spec.rb} +16 -9
- data/spec/features/{contact_form_spec.rb → admin/contact_form_spec.rb} +16 -9
- data/spec/features/{content_groups_spec.rb → admin/content_groups_spec.rb} +19 -11
- data/spec/features/{custom_fields_spec.rb → admin/custom_fields_spec.rb} +1 -1
- data/spec/features/{languages_spec.rb → admin/languages_spec.rb} +1 -1
- data/spec/features/{media_spec.rb → admin/media_spec.rb} +1 -1
- data/spec/features/{menus_spec.rb → admin/menus_spec.rb} +2 -2
- data/spec/features/{pages_spec.rb → admin/pages_spec.rb} +1 -1
- data/spec/features/{plugins_spec.rb → admin/plugins_spec.rb} +1 -1
- data/spec/features/{posts_spec.rb → admin/posts_spec.rb} +4 -3
- data/spec/features/admin/session_spec.rb +102 -0
- data/spec/features/{settings_spec.rb → admin/settings_spec.rb} +1 -1
- data/spec/features/{shortcodes_spec.rb → admin/shortcodes_spec.rb} +1 -1
- data/spec/features/{sites_spec.rb → admin/sites_spec.rb} +22 -14
- data/spec/features/{tags_spec.rb → admin/tags_spec.rb} +17 -8
- data/spec/features/{themes_spec.rb → admin/themes_spec.rb} +1 -1
- data/spec/features/{user_roles_spec.rb → admin/user_roles_spec.rb} +25 -19
- data/spec/features/{users_spec.rb → admin/users_spec.rb} +2 -2
- data/spec/features/{widgets_spec.rb → admin/widgets_spec.rb} +19 -12
- data/spec/features/frontend/pages_spec.rb +86 -5
- data/spec/features/frontend/post_type_spec.rb +16 -0
- data/spec/helpers/email_helper_spec.rb +1 -1
- data/spec/helpers/uploader_helper_spec.rb +56 -0
- data/spec/mailers/send_mail_spec.rb +3 -3
- data/spec/{decorators/camaleon_cms/post_decorator_spec.rb → models/post_spec.rb} +3 -3
- data/spec/rails_helper.rb +79 -0
- data/spec/spec_helper.rb +25 -56
- data/spec/support/common.rb +10 -24
- data/spec/support/fixtures/rails.png +0 -0
- data/spec/support/fixtures/rails_tmp.png +0 -0
- metadata +64 -50
- data/app/views/camaleon_cms/admin/media/_files_list.html.erb +0 -2
- data/app/views/camaleon_cms/admin/media/_render_folder_item.html.erb +0 -15
- data/spec/decorators/post_type_spec.rb +0 -13
- 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
|
-
|
|
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 =
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
'
|
|
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['
|
|
51
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
89
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
obj
|
|
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(
|
|
43
|
-
"
|
|
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
|
-
"
|
|
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
|
-
'
|
|
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[
|
|
55
|
-
if res['
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
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.
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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|
|
|
2
|
-
<% file['
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<%
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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 %>
|