camaleon_cms 2.4.0 → 2.4.1

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/assets/javascripts/camaleon_cms/admin/_custom_fields.js +2 -2
  4. data/app/assets/javascripts/camaleon_cms/admin/_post.js +1 -1
  5. data/app/assets/javascripts/camaleon_cms/admin/form/cropper.min.js +2994 -1
  6. data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js.coffee +72 -33
  7. data/app/controllers/camaleon_cms/admin/media_controller.rb +1 -0
  8. data/app/controllers/camaleon_cms/admin/sessions_controller.rb +2 -2
  9. data/app/controllers/camaleon_cms/admin/user_roles_controller.rb +11 -6
  10. data/app/controllers/camaleon_cms/admin/users_controller.rb +1 -1
  11. data/app/controllers/camaleon_cms/apps/plugins_front_controller.rb +1 -1
  12. data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +1 -1
  13. data/app/decorators/camaleon_cms/site_decorator.rb +1 -1
  14. data/app/decorators/camaleon_cms/user_decorator.rb +1 -1
  15. data/app/decorators/camaleon_cms/user_role_decorator.rb +12 -0
  16. data/app/helpers/camaleon_cms/session_helper.rb +1 -1
  17. data/app/helpers/camaleon_cms/short_code_helper.rb +25 -7
  18. data/app/models/concerns/camaleon_cms/user_methods.rb +0 -7
  19. data/app/uploaders/camaleon_cms_aws_uploader.rb +2 -5
  20. data/app/uploaders/camaleon_cms_uploader.rb +6 -2
  21. data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +1 -1
  22. data/app/views/camaleon_cms/admin/settings/custom_fields/form.html.erb +1 -1
  23. data/app/views/camaleon_cms/admin/user_roles/form.html.erb +5 -9
  24. data/app/views/camaleon_cms/admin/user_roles/index.html.erb +3 -3
  25. data/app/views/camaleon_cms/admin/users/form.html.erb +1 -1
  26. data/app/views/camaleon_cms/admin/users/index.html.erb +2 -2
  27. data/config/locales/camaleon_cms/admin/js.yml +2 -0
  28. data/db/migrate/20161215202255_drop_user_relationship_table.rb +5 -0
  29. data/lib/camaleon_cms/version.rb +1 -1
  30. data/spec/dummy/db/schema.rb +1 -11
  31. data/spec/helpers/short_code_helper_spec.rb +64 -0
  32. metadata +6 -3
  33. data/app/models/camaleon_cms/user_relationship.rb +0 -7
@@ -32,6 +32,10 @@ window["cama_init_media"] = (media_panel) ->
32
32
  media_info.html(tpl)
33
33
  media_info.find(".p_thumb").html(item.find(".thumb").html())
34
34
  if data["format"] == "image"
35
+ if item.find('.edit_item') # add button to edit image
36
+ edit_img = $('<button type="button" class="pull-right btn btn-default" title="Edit"><i class="fa fa-pencil"></i></button>').click ->
37
+ item.find('.edit_item').trigger('click')
38
+ media_info.find('.p_footer').append(edit_img)
35
39
  draw_image = ->
36
40
  ww = parseInt(data['dimension'].split("x")[0])
37
41
  hh = parseInt(data['dimension'].split("x")[1])
@@ -46,7 +50,7 @@ window["cama_init_media"] = (media_panel) ->
46
50
  btn.prop('disabled', false)
47
51
  else
48
52
  media_info.find(".cdimension").css("color", 'red')
49
- cut = $("<button class='btn btn-info pull-right'><i class='fa fa-crop'></i> "+I18n("button.crop_image")+"</button>").click(->
53
+ cut = $("<button class='btn btn-info pull-right'><i class='fa fa-crop'></i> "+I18n("button.auto_crop")+"</button>").click(->
50
54
  crop_name = data["name"].split('.')
51
55
  crop_name[crop_name.length-2] += '_' + media_panel.attr("data-dimension")
52
56
  $.fn.upload_url({url: data["url"], name: crop_name.join('.')})
@@ -74,6 +78,10 @@ window["cama_init_media"] = (media_panel) ->
74
78
  media_panel.on("click", ".file_item", ->
75
79
  show_file($(this))
76
80
  return false
81
+ ).on('dblclick', '.file_item', -> ## auto select on double click
82
+ btn = media_info.find('.insert_btn')
83
+ if btn && !btn.attr('disabled') && !btn.attr('readonly')
84
+ btn.trigger('click')
77
85
  )
78
86
 
79
87
  media_files_panel.scroll(->
@@ -85,7 +93,9 @@ window["cama_init_media"] = (media_panel) ->
85
93
  ########## file uploader
86
94
  p_upload = media_panel.find(".cama_media_fileuploader")
87
95
  customFileData = ->
88
- return cama_media_get_custom_params()
96
+ r = cama_media_get_custom_params()
97
+ r['skip_auto_crop'] = true
98
+ return r
89
99
 
90
100
  p_upload.uploadFile({
91
101
  url: p_upload.attr("data-url"),
@@ -156,8 +166,11 @@ window["cama_init_media"] = (media_panel) ->
156
166
  showLoading()
157
167
  $.getJSON(media_panel.attr("data-url"), media_panel.data('last_req_params'), (res)->
158
168
  if data["paginate"]
159
- last_folder = media_files_panel.children('.folder_item:last')
160
- if last_folder.length ==1 then last_folder.after(res.html) else media_files_panel.append(res.html)
169
+ if media_files_panel.children('.file_item').length > 0
170
+ media_files_panel.append(res.html)
171
+ else
172
+ last_folder = media_files_panel.children('.folder_item:last')
173
+ if last_folder.length ==1 then last_folder.after(res.html) else media_files_panel.append(res.html)
161
174
  else
162
175
  media_files_panel.html(res.html)
163
176
  media_files_panel.attr('data-next-page', res.next_page)
@@ -238,8 +251,10 @@ window["cama_init_media"] = (media_panel) ->
238
251
  cropper_data = null
239
252
 
240
253
  edit_callback = (modal)->
254
+ field_width = modal.find('.export_image .with_image')
255
+ field_height = modal.find('.export_image .height_image')
241
256
  save_image = (name, same_name)->
242
- $.fn.upload_url({url: cropper.cropper('getCroppedCanvas').toDataURL('image/jpeg'), name: name, same_name: same_name, callback: (res)->
257
+ $.fn.upload_url({url: cropper.cropper('getCroppedCanvas', { width: field_width.val(), height: field_height.val() }).toDataURL('image/jpeg'), name: name, same_name: same_name, callback: (res)->
243
258
  modal.modal('hide')
244
259
  })
245
260
 
@@ -260,9 +275,11 @@ window["cama_init_media"] = (media_panel) ->
260
275
  )
261
276
 
262
277
  # save editted image
263
- save_btn = $('<button type="button" class="btn btn-default"><i class="fa fa-save"></i> '+I18n('button.save', 'Save Image')+'</button>').click(->
278
+ save_btn = modal.find('.export_image').submit(->
279
+ unless $(this).valid()
280
+ return false
264
281
  save_buttons = (modal2)->
265
- modal2.find('img.preview').attr('src', cropper.cropper('getCroppedCanvas').toDataURL('image/jpeg'))
282
+ modal2.find('img.preview').attr('src', cropper.cropper('getCroppedCanvas', { width: field_width.val(), height: field_height.val() }).toDataURL('image/jpeg'))
266
283
  modal2.find('.save_btn').click(->
267
284
  save_image(data['name'], true)
268
285
  modal2.modal('hide')
@@ -273,9 +290,16 @@ window["cama_init_media"] = (media_panel) ->
273
290
  modal2.modal('hide')
274
291
  return false
275
292
  })
276
- open_modal({zindex: 999992, id: 'media_preview_editted_image', content: '<div class="text-center" style="overflow: auto;"><img class="preview"></div><br><div class="row"><div class="col-md-4">'+(if link.attr('data-permit-overwrite') then '<button class="btn save_btn btn-default">'+I18n('button.replace_image')+'</button>' else '')+'</div><div class="col-md-8"><form class="input-group"><input type="text" class="form-control file_name required" name="file_name"><div class="input-group-btn"><button class="btn btn-primary" type="submit">'+I18n('button.save_new_image')+'</button></div></form></div></div>', callback: save_buttons})
293
+ open_modal({zindex: 999992, modal_size: 'modal-lg', id: 'media_preview_editted_image', content: '<div class="text-center" style="overflow: auto;"><img class="preview"></div><br><div class="row"><div class="col-md-4"><button class="btn save_btn btn-default">'+I18n('button.replace_image')+'</button></div><div class="col-md-8"><form class="input-group"><input type="text" class="form-control file_name required" name="file_name"><div class="input-group-btn"><button class="btn btn-primary" type="submit">'+I18n('button.save_new_image')+'</button></div></form></div></div>', callback: save_buttons})
294
+ return false
295
+ ).validate()
296
+
297
+ # custom sizes auto calculate aspect ratio
298
+ field_width.change(->
299
+ unless field_width.attr("readonly")
300
+ croper_area = modal.find('.cropper-crop-box')
301
+ field_height.val(parseInt((parseInt($(this).val()) / croper_area.width())*croper_area.height()))
277
302
  )
278
- modal.find('.editor_controls').append(save_btn)
279
303
 
280
304
  # show cropper image
281
305
  showLoading()
@@ -283,26 +307,11 @@ window["cama_init_media"] = (media_panel) ->
283
307
  setTimeout(->
284
308
  label = modal.find('.label_dimension')
285
309
  cropper_data = {data: {}, minContainerHeight: 450, modal: true, crop: (e)->
286
- dim = cropper_data['data']['dim']
287
- r = false
288
- if dim && dim[0].search(/\?/) > -1 && parseFloat(dim[0].match(/\d+/)[0]) < e.width # max width
289
- cropper.cropper('setData', {width: parseFloat(dim[0].match(/\d+/)[0])})
290
- r = true
291
-
292
- if dim && dim[1].search(/\?/) > -1 && parseFloat(dim[1].match(/\d+/)[0]) < e.height # max height
293
- cropper.cropper('setData', {height: parseFloat(dim[1].match(/\d+/)[0])})
294
- r = true
295
-
296
- if dim && dim[0] && dim[0].search(/\?/) == -1 && e.width != parseFloat(dim[0]) # same width
297
- cropper.cropper('setData', {width: parseFloat(dim[0])})
298
- r = true
299
-
300
- if dim && dim[1] && dim[1].search(/\?/) == -1 && e.height != parseFloat(dim[1]) # same width
301
- cropper.cropper('setData', {height: parseFloat(dim[1])})
302
- r = true
303
-
304
- unless r
305
- label.html(Math.round(e.width) + " x "+Math.round(e.height))
310
+ label.html(Math.round(e.width) + " x "+Math.round(e.height))
311
+ unless field_width.attr("readonly")
312
+ field_width.val(Math.round(e.width))
313
+ unless field_height.attr("readonly")
314
+ field_height.val(Math.round(e.height))
306
315
  , built: ()->
307
316
  if modal.find('.cropper-canvas img').attr('crossorigin')
308
317
  modal.find('.modal-body').html('<div class="alert alert-danger">'+I18n('msg.cors_error', 'Please verify the following: <ul><li>If the image exist: %{url_img}</li> <li>Check if cors configuration are defined well, only for external images: S3, cloudfront(if you are using cloudfront).</li></ul><br> More information about CORS: <a href="%{url_blog}" target="_blank">here.</a>', {url_img: data['url'], url_blog: 'http://blog.celingest.com/en/2014/10/02/tutorial-using-cors-with-cloudfront-and-s3/'})+'</div>')
@@ -310,20 +319,50 @@ window["cama_init_media"] = (media_panel) ->
310
319
 
311
320
  if media_panel.attr("data-dimension") # TODO: control dimensions
312
321
  dim = media_panel.attr("data-dimension").split('x')
313
- cropper_data['data']['dim'] = dim
314
322
  if dim[0]
315
323
  cropper_data['data']['width'] = parseFloat(dim[0].match(/\d+/)[0])
324
+ field_width.val(cropper_data['data']['width'])
325
+ if dim[0].search(/\?/) > -1
326
+ field_width.attr('min', cropper_data['data']['width'])
327
+ else
328
+ field_width.prop('readonly', true)
316
329
  if dim[1]
317
330
  cropper_data['data']['height'] = parseFloat(dim[1].match(/\d+/)[0])
331
+ field_height.val(cropper_data['data']['height'])
332
+ if dim[1].search(/\?/) > -1
333
+ field_height.attr('min', cropper_data['data']['height'])
334
+ else
335
+ field_height.prop('readonly', true)
318
336
  if dim[0] && dim[0].search(/\?/) == -1 && dim[1] && dim[1].search(/\?/) == -1
319
337
  cropper_data['cropBoxResizable'] = false
320
- cropper_data['zoomable'] = false
321
338
 
322
339
  cropper = modal.find('img.editable').cropper(cropper_data)
323
340
  hideLoading()
324
341
  , 300)
325
342
  )
326
- open_modal({zindex: 999991, id: 'media_panel_editor_image', title: 'Edit Image - ' + data['name'], content: '<div><div class="editable_wrapper"><img style="max-width: 100%;" class="editable" id="media_editable_image" src="'+data['url']+'"></div><div class="editor_controls btn-group"></div><span class="label label-default pull-right label_dimension"></span></div>', callback: edit_callback, modal_size: 'modal-lg'})
343
+ open_modal({
344
+ zindex: 999991,
345
+ id: 'media_panel_editor_image',
346
+ title: I18n('button.edit_image', 'Edit Image')+' - ' + data['name'] + (if media_panel.attr("data-dimension") then " <small><i>("+media_panel.attr("data-dimension")+")</i></small>" else ''),
347
+ content: '<div>' +
348
+ '<div class="editable_wrapper">' +
349
+ '<img style="max-width: 100%;" class="editable" id="media_editable_image" src="'+data['url']+'">' +
350
+ '</div>' +
351
+ '<div class="row" style="margin-top: 5px;">' +
352
+ '<div class="col-md-8">' +
353
+ '<div class="editor_controls btn-group"></div>' +
354
+ '</div>' +
355
+ '<div class="col-md-4">' +
356
+ '<form class="export_image"> ' +
357
+ '<div class="input-group"><input class="form-control with_image data-error-place-parent required number" placeholder="Width"><span class="input-group-addon">x</span>' +
358
+ '<input class="form-control height_image data-error-place-parent required number" placeholder="Height"> ' +
359
+ '<span class="input-group-btn"><button class="btn btn-primary save_image" type="submit"><i class="fa fa-save"></i> '+I18n('button.save', 'Save Image')+'</button> </span> </div>' +
360
+ '</form>' +
361
+ '</div>' +
362
+ '</div>' +
363
+ '<!--span class="label label-default pull-right label_dimension"></span-->' +
364
+ '</div>',
365
+ callback: edit_callback, modal_size: 'modal-lg'})
327
366
  return false
328
367
  )
329
368
 
@@ -331,7 +370,7 @@ window["cama_init_media"] = (media_panel) ->
331
370
  media_panel.find("#cama_media_external").submit( ->
332
371
  unless $(this).valid()
333
372
  return false
334
- $.fn.upload_url({url: $(this).find("input").val(), callback: ->
373
+ $.fn.upload_url({url: $(this).find("input").val(), skip_auto_crop: true, callback: ->
335
374
  media_panel.find("#cama_media_external")[0].reset();
336
375
  })
337
376
  return false
@@ -78,6 +78,7 @@ class CamaleonCms::Admin::MediaController < CamaleonCms::AdminController
78
78
 
79
79
  # upload files from media uploader
80
80
  def upload(settings = {})
81
+ params[:dimension] = nil if params[:skip_auto_crop].present?
81
82
  f = {error: "File not found."}
82
83
  if params[:file_upload].present?
83
84
  f = upload_file(params[:file_upload], {folder: params[:folder], dimension: params['dimension'], formats: params[:formats], versions: params[:versions], thumb_size: params[:thumb_size]}.merge(settings))
@@ -30,7 +30,7 @@ class CamaleonCms::Admin::SessionsController < CamaleonCms::CamaleonController
30
30
  cama_captcha_reset_attack("login")
31
31
  r={user: @user, redirect_to: params[:format] == 'json' ? false : nil}; hooks_run('after_login', r)
32
32
  login_user(@user, params[:remember_me].present?, r[:redirect_to])
33
- render(json: flash.to_hash) if params[:format] == 'json'
33
+ render(json: flash.discard.to_hash) if params[:format] == 'json'
34
34
  return
35
35
  else
36
36
  flash[:error] = t('camaleon_cms.admin.login.message.email_not_validated')
@@ -47,7 +47,7 @@ class CamaleonCms::Admin::SessionsController < CamaleonCms::CamaleonController
47
47
  @user = current_site.users.new(data_user)
48
48
  login if params[:format] != 'json'
49
49
  end
50
- render(json: flash.to_hash) if params[:format] == 'json'
50
+ render(json: flash.discard.to_hash) if params[:format] == 'json'
51
51
  end
52
52
 
53
53
  def logout
@@ -37,9 +37,11 @@ class CamaleonCms::Admin::UserRolesController < CamaleonCms::AdminController
37
37
  end
38
38
 
39
39
  def update
40
- if @user_role.editable? && @user_role.update(params.require(:user_role).permit!)
41
- @user_role.set_meta("_post_type_#{current_site.id.to_s}", defined?(params[:rol_values][:post_type]) ? params[:rol_values][:post_type] : {})
42
- @user_role.set_meta("_manager_#{current_site.id.to_s}", defined?(params[:rol_values][:post_type]) ? params[:rol_values][:manager] : {})
40
+ if @user_role.update(params.require(:user_role).permit!)
41
+ if @user_role.editable?
42
+ @user_role.set_meta("_post_type_#{current_site.id.to_s}", defined?(params[:rol_values][:post_type]) ? params[:rol_values][:post_type] : {})
43
+ @user_role.set_meta("_manager_#{current_site.id.to_s}", defined?(params[:rol_values][:post_type]) ? params[:rol_values][:manager] : {})
44
+ end
43
45
  flash[:notice] = t('camaleon_cms.admin.users.message.rol_updated')
44
46
  redirect_to action: :edit, id: @user_role.id
45
47
  else
@@ -48,8 +50,11 @@ class CamaleonCms::Admin::UserRolesController < CamaleonCms::AdminController
48
50
  end
49
51
 
50
52
  def destroy
51
- @user_role.destroy
52
- flash[:notice] = t('camaleon_cms.admin.users.message.rol_deleted')
53
+ if @user_role.editable? && @user_role.destroy
54
+ flash[:notice] = t('camaleon_cms.admin.users.message.rol_deleted')
55
+ else
56
+ flash[:error] = t('camaleon_cms.admin.users.message.role_can_not_be_deleted', default: 'This role can not be deleted')
57
+ end
53
58
  redirect_to action: :index
54
59
  end
55
60
 
@@ -60,7 +65,7 @@ class CamaleonCms::Admin::UserRolesController < CamaleonCms::AdminController
60
65
 
61
66
  def set_user_roles
62
67
  begin
63
- @user_role = current_site.user_roles.find(params[:id])
68
+ @user_role = current_site.user_roles.find(params[:id]).decorate
64
69
  rescue
65
70
  flash[:error] = t('camaleon_cms.admin.users.message.rol_error')
66
71
  redirect_to action: :index
@@ -5,7 +5,7 @@ class CamaleonCms::Admin::UsersController < CamaleonCms::AdminController
5
5
 
6
6
  def index
7
7
  add_breadcrumb I18n.t("camaleon_cms.admin.users.list_users")
8
- @users = current_site.users.paginate(:page => params[:page], :per_page => current_site.admin_per_page)
8
+ @users = current_site.users.paginate(:page => params[:page], :per_page => current_site.admin_per_page).decorate
9
9
  end
10
10
 
11
11
  def profile
@@ -8,7 +8,7 @@ class CamaleonCms::Apps::PluginsFrontController < CamaleonCms::FrontendControlle
8
8
  @plugin = current_site.plugins.where(slug: plugin_name).first_or_create
9
9
  unless @plugin.active?
10
10
  flash[:error] = t("camaleon_cms.plugin_not_installed", default: "This plugin is not installed, please contact to the administrator.")
11
- params[:format] == 'json' ? render(json: flash.to_hash) : (redirect_to cama_root_url)
11
+ params[:format] == 'json' ? render(json: flash.discard.to_hash) : (redirect_to cama_root_url)
12
12
  return
13
13
  end
14
14
  if !@plugin.settings["gem_mode"].present?
@@ -56,6 +56,6 @@ module CamaleonCms::FrontendConcern extend ActiveSupport::Concern
56
56
  else
57
57
  flash[:error] = t('camaleon_cms.admin.message.unauthorized')
58
58
  end
59
- params[:format] == 'json' ? render(json: flash.to_hash) : redirect_to(:back)
59
+ params[:format] == 'json' ? render(json: flash.discard.to_hash) : redirect_to(:back)
60
60
  end
61
61
  end
@@ -133,7 +133,7 @@ class CamaleonCms::SiteDecorator < CamaleonCms::TermTaxonomyDecorator
133
133
  # return the role_id of current visitor for this site
134
134
  # if the visitor was not logged in, then return -1
135
135
  def visitor_role
136
- h.signin? ? h.cama_current_user.get_role(object).slug : "-1"
136
+ h.signin? ? h.cama_current_user.role : '-1'
137
137
  end
138
138
 
139
139
  # check if plugin_key is already installed for this site
@@ -14,7 +14,7 @@ class CamaleonCms::UserDecorator < CamaleonCms::ApplicationDecorator
14
14
 
15
15
  # return the role title of this user for current site
16
16
  def the_role
17
- object.get_role(h.current_site).name.titleize
17
+ object.get_role(h.current_site).try(:decorate).try(:the_title) || ''
18
18
  end
19
19
 
20
20
  # return the avatar for this user, default: assets/admin/img/no_image.jpg
@@ -0,0 +1,12 @@
1
+ class CamaleonCms::UserRoleDecorator < CamaleonCms::ApplicationDecorator
2
+ include CamaleonCms::CustomFieldsConcern
3
+ delegate_all
4
+
5
+ def the_title
6
+ object.name.to_s.translate(get_locale)
7
+ end
8
+
9
+ def the_content
10
+ object.description.to_s.translate(get_locale)
11
+ end
12
+ end
@@ -110,7 +110,7 @@ module CamaleonCms::SessionHelper
110
110
  # return the role for current user
111
111
  # if not logged in, then return 'public'
112
112
  def cama_current_role
113
- (cama_sign_in?) ? cama_current_user.role : 'public'
113
+ current_site.visitor_role
114
114
  end
115
115
 
116
116
  # return current user logged in
@@ -10,11 +10,15 @@ module CamaleonCms::ShortCodeHelper
10
10
  Sample: [widget widget_key]")
11
11
 
12
12
  shortcode_add("load_libraries",
13
- lambda{|attrs, args| cama_load_libraries(*attrs["data"].to_s.split(",")); return ""; },
13
+ lambda{|attrs, args|
14
+ return args[:shortcode] unless attrs.present?
15
+ cama_load_libraries(*attrs["data"].to_s.split(",")); return "";
16
+ },
14
17
  "Permit to load libraries on demand, sample: [load_libraries data='datepicker,tinymce']")
15
18
 
16
19
  shortcode_add("asset",
17
20
  lambda{|attrs, args|
21
+ return args[:shortcode] unless attrs.present?
18
22
  url = attrs["as_path"].present? ? ActionController::Base.helpers.asset_url(attrs["file"]) : ActionController::Base.helpers.asset_url(attrs["file"])
19
23
  if attrs["image"].present?
20
24
  ActionController::Base.helpers.image_tag(attrs["file"], class: attrs["class"], style: attrs["style"])
@@ -32,7 +36,7 @@ module CamaleonCms::ShortCodeHelper
32
36
 
33
37
  shortcode_add("data",
34
38
  lambda{|attrs, args|
35
- cama_shortcode_data(attrs, args) rescue ""
39
+ attrs.present? ? (cama_shortcode_data(attrs, args) rescue "") : args[:shortcode]
36
40
  },
37
41
  "Permit to generate specific data of a post.
38
42
  Attributes:
@@ -96,8 +100,7 @@ module CamaleonCms::ShortCodeHelper
96
100
  def do_shortcode(content, args = {})
97
101
  args = {owner: args} unless args.is_a?(Hash)
98
102
  content.scan(/#{cama_reg_shortcode}/) do |item|
99
- shortcode, code, space, attrs = item
100
- content = content.sub(shortcode, _eval_shortcode(code, attrs, args))
103
+ content = _cama_replace_shortcode(content, item, args)
101
104
  end
102
105
  content
103
106
  end
@@ -118,20 +121,35 @@ module CamaleonCms::ShortCodeHelper
118
121
  # render_shortcode("asda dasdasdas[owen a='1'] [bbb] sdasdas dasd as das[owen a=213]", "owen", lambda{|attrs, args| puts attrs; return "my test"; })
119
122
  def render_shortcode(text, key, template = nil)
120
123
  text.scan(/#{cama_reg_shortcode(key)}/).each do |item|
121
- shortcode, code, space, attrs = item
122
- text = text.sub(shortcode, _eval_shortcode(code, attrs, {}, template))
124
+ text = _cama_replace_shortcode(text, item, {}, template)
123
125
  end
124
126
  text
125
127
  end
126
128
 
127
129
  private
130
+ # helper to replace shortcodes adding support for closed shortcodes, sample: [title]my title[/title]
131
+ def _cama_replace_shortcode(content, item, args = {}, template = nil)
132
+ shortcode, code, attrs = item
133
+ close_code = "[/#{code}]"
134
+ if content.include?(close_code)
135
+ shortcode_bk = shortcode
136
+ tmp_content = content[content.index(shortcode)..-1]
137
+ shortcode = tmp_content[0..(tmp_content.index(close_code) + close_code.size - 1)]
138
+ args[:shortcode_content] = shortcode.sub(shortcode_bk, '').sub(close_code, '')
139
+ end
140
+ args[:shortcode] = shortcode
141
+ args[:code] = code
142
+ content.sub(shortcode, _eval_shortcode(code, attrs, args, template))
143
+ end
144
+
128
145
  # create the regexpression for shortcodes
129
146
  # codes: (String) shortcode keys separated by |
130
147
  # sample: load_libraries|asset
131
148
  # if empty, codes will be replaced with all registered shortcodes
132
149
  # Return: (String) reg expression string
133
150
  def cama_reg_shortcode(codes = nil)
134
- "(\\[(#{codes || (@_shortcodes || []).join("|")})(\s|\\]){0}(.*?)\\])"
151
+ # "(\\[(#{codes || (@_shortcodes || []).join("|")})(\s|\\]){0}(.*?)\\])" # doesn't support for similar names, like: [media] and [media_gallery]
152
+ "(\\[(#{codes || (@_shortcodes || []).join("|")})((\s)((?!\\]).)*|)\\])"
135
153
  end
136
154
 
137
155
  # determine the content to replace instead the shortcode
@@ -27,8 +27,6 @@ module CamaleonCms::UserMethods extend ActiveSupport::Concern
27
27
  # relations
28
28
 
29
29
  has_many :metas, ->{ where(object_class: 'User')}, :class_name => "CamaleonCms::Meta", foreign_key: :objectid, dependent: :destroy
30
- has_many :user_relationships, class_name: "CamaleonCms::UserRelationship", foreign_key: :user_id, dependent: :destroy#, inverse_of: :user
31
- has_many :term_taxonomies, foreign_key: :term_taxonomy_id, class_name: "CamaleonCms::TermTaxonomy", through: :user_relationships, :source => :term_taxonomies
32
30
  has_many :all_posts, class_name: "CamaleonCms::Post"
33
31
 
34
32
  #scopes
@@ -86,11 +84,6 @@ module CamaleonCms::UserMethods extend ActiveSupport::Concern
86
84
  end
87
85
  end
88
86
 
89
- # DEPRECATED, please use user.the_role
90
- def roleText
91
- User::ROLE[self.role]
92
- end
93
-
94
87
  def created
95
88
  self.created_at.strftime('%d/%m/%Y %H:%M')
96
89
  end
@@ -21,15 +21,12 @@ class CamaleonCmsAwsUploader < CamaleonCmsUploader
21
21
  objects
22
22
  end
23
23
 
24
- def objects(prefix = '/')
24
+ def objects(prefix = '/', sort = 'created_at')
25
25
  if @aws_settings["inner_folder"].present?
26
26
  prefix = "#{@aws_settings["inner_folder"]}/#{prefix}".gsub('//', '/')
27
27
  prefix = prefix[0..-2] if prefix.end_with?('/')
28
28
  end
29
-
30
- prefix = "/#{prefix}" unless prefix.starts_with?('/')
31
- db = @current_site.get_meta(cache_key, nil) || browser_files
32
- db[prefix.gsub('//', '/')] || {files: {}, folders: {}}
29
+ super(prefix, sort)
33
30
  end
34
31
 
35
32
  # parse an AWS file into custom file_object
@@ -18,10 +18,14 @@ class CamaleonCmsUploader
18
18
  # return all files structure, within folder prefix
19
19
  # return json like:
20
20
  # {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', ...}}}
21
- def objects(prefix = '/')
21
+ # sort: (String, default 'created_at'), accept for: created_at | name | size | type | format
22
+ def objects(prefix = '/', sort = 'created_at')
22
23
  prefix = "/#{prefix}" unless prefix.starts_with?('/')
23
24
  db = @current_site.get_meta(cache_key, nil) || browser_files
24
- db[prefix.gsub('//', '/')] || {files: {}, folders: {}}
25
+ res = db[prefix.gsub('//', '/')] || {files: {}, folders: {}}
26
+ res[:files] = res[:files].sort_by{|k, v| v[sort] }.reverse.to_h
27
+ res[:folders] = res[:folders].sort_by{|k, v| v['name'] }.reverse.to_h
28
+ res
25
29
  end
26
30
 
27
31
  # clean cached of files structure saved into DB