alchemy_cms 4.1.2 → 4.2.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/Bug_report.md +0 -5
- data/.rubocop.yml +4 -1
- data/.travis.yml +3 -3
- data/CHANGELOG.md +29 -10
- data/Gemfile +5 -7
- data/README.md +114 -62
- data/Rakefile +2 -2
- data/alchemy_cms.gemspec +5 -5
- data/app/assets/images/alchemy/icon.svg +1 -1
- data/app/assets/javascripts/alchemy/admin.js +2 -0
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +0 -24
- data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +11 -9
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +7 -24
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +9 -8
- data/app/assets/javascripts/alchemy/alchemy.fixed_elements.js +38 -0
- data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +2 -4
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +1 -1
- data/app/assets/stylesheets/alchemy/_mixins.scss +2 -1
- data/app/assets/stylesheets/alchemy/_variables.scss +7 -2
- data/app/assets/stylesheets/alchemy/admin.scss +2 -1
- data/app/assets/stylesheets/alchemy/archive.scss +18 -4
- data/app/assets/stylesheets/alchemy/buttons.scss +1 -1
- data/app/assets/stylesheets/alchemy/dialogs.scss +1 -1
- data/app/assets/stylesheets/alchemy/elements.scss +154 -90
- data/app/assets/stylesheets/alchemy/filter_field.scss +30 -0
- data/app/assets/stylesheets/alchemy/flatpickr.scss +839 -0
- data/app/assets/stylesheets/alchemy/forms.scss +5 -1
- data/app/assets/stylesheets/alchemy/frame.scss +6 -14
- data/app/assets/stylesheets/alchemy/navigation.scss +109 -98
- data/app/assets/stylesheets/alchemy/search.scss +11 -29
- data/app/assets/stylesheets/alchemy/tables.scss +0 -23
- data/app/assets/stylesheets/alchemy/tags.scss +4 -27
- data/app/assets/stylesheets/alchemy/toolbar.scss +12 -2
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +4 -33
- data/app/controllers/alchemy/admin/attachments_controller.rb +1 -12
- data/app/controllers/alchemy/admin/contents_controller.rb +2 -24
- data/app/controllers/alchemy/admin/elements_controller.rb +11 -49
- data/app/controllers/alchemy/admin/pages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/pictures_controller.rb +1 -14
- data/app/controllers/alchemy/api/contents_controller.rb +1 -1
- data/app/controllers/alchemy/api/elements_controller.rb +1 -1
- data/app/controllers/alchemy/api/pages_controller.rb +1 -1
- data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +20 -0
- data/app/helpers/alchemy/admin/base_helper.rb +8 -18
- data/app/helpers/alchemy/admin/elements_helper.rb +55 -85
- data/app/helpers/alchemy/admin/pictures_helper.rb +0 -23
- data/app/helpers/alchemy/elements_helper.rb +80 -120
- data/app/helpers/alchemy/pages_helper.rb +5 -24
- data/app/models/alchemy/content.rb +0 -1
- data/app/models/alchemy/content/factory.rb +33 -57
- data/app/models/alchemy/element.rb +46 -66
- data/app/models/alchemy/element/element_contents.rb +2 -2
- data/app/models/alchemy/page.rb +34 -4
- data/app/models/alchemy/page/page_elements.rb +30 -122
- data/app/serializers/alchemy/attachment_serializer.rb +0 -2
- data/app/serializers/alchemy/content_serializer.rb +0 -2
- data/app/serializers/alchemy/element_serializer.rb +0 -3
- data/app/serializers/alchemy/essence_boolean_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_date_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_file_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_html_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_link_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_picture_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_richtext_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_select_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_text_serializer.rb +0 -2
- data/app/serializers/alchemy/legacy_element_serializer.rb +0 -3
- data/app/serializers/alchemy/page_serializer.rb +2 -8
- data/app/serializers/alchemy/page_tree_serializer.rb +1 -1
- data/app/serializers/alchemy/picture_serializer.rb +0 -2
- data/app/views/alchemy/admin/clipboard/index.html.erb +2 -2
- data/app/views/alchemy/admin/clipboard/insert.js.erb +9 -12
- data/app/views/alchemy/admin/contents/create.js.erb +4 -30
- data/app/views/alchemy/admin/elements/_element.html.erb +27 -12
- data/app/views/alchemy/admin/elements/_element_toolbar.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_new_element_form.html.erb +0 -10
- data/app/views/alchemy/admin/elements/create.js.erb +12 -12
- data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
- data/app/views/alchemy/admin/elements/index.html.erb +20 -19
- data/app/views/alchemy/admin/elements/publish.js.erb +5 -0
- data/app/views/alchemy/admin/elements/trash.js.erb +4 -1
- data/app/views/alchemy/admin/essence_pictures/assign.js.erb +0 -7
- data/app/views/alchemy/admin/essence_pictures/destroy.js.erb +0 -22
- data/app/views/alchemy/admin/pages/_publication_fields.html.erb +2 -4
- data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pages/index.html.erb +14 -10
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +7 -5
- data/app/views/alchemy/admin/partials/_routes.html.erb +0 -1
- data/app/views/alchemy/admin/partials/_search_form.html.erb +6 -4
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +6 -3
- data/app/views/alchemy/admin/pictures/index.html.erb +1 -1
- data/app/views/alchemy/admin/trash/index.html.erb +8 -7
- data/app/views/alchemy/elements/_editor_not_found.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +4 -19
- data/app/views/layouts/alchemy/admin.html.erb +1 -0
- data/bin/rspec +0 -5
- data/config/alchemy/config.yml +3 -0
- data/config/brakeman.ignore +1 -1
- data/config/locales/alchemy.en.yml +6 -12
- data/config/routes.rb +1 -5
- data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -29
- data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +6 -0
- data/lib/alchemy/admin/locale.rb +1 -1
- data/lib/alchemy/cache_digests/template_tracker.rb +4 -27
- data/lib/alchemy/elements_finder.rb +111 -0
- data/lib/alchemy/errors.rb +0 -4
- data/lib/alchemy/modules.rb +49 -18
- data/lib/alchemy/tasks/tidy.rb +3 -40
- data/lib/alchemy/test_support/controller_requests.rb +1 -1
- data/lib/alchemy/test_support/essence_shared_examples.rb +1 -1
- data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -3
- data/lib/alchemy/test_support/factories/content_factory.rb +4 -4
- data/lib/alchemy/test_support/factories/dummy_user_factory.rb +5 -5
- data/lib/alchemy/test_support/factories/element_factory.rb +12 -7
- data/lib/alchemy/test_support/factories/essence_text_factory.rb +1 -1
- data/lib/alchemy/test_support/factories/language_factory.rb +13 -13
- data/lib/alchemy/test_support/factories/page_factory.rb +18 -17
- data/lib/alchemy/test_support/factories/picture_factory.rb +6 -4
- data/lib/alchemy/test_support/factories/site_factory.rb +6 -6
- data/lib/alchemy/tinymce.rb +1 -1
- data/lib/alchemy/upgrader/four_point_two.rb +68 -0
- data/lib/alchemy/upgrader/tasks/cells_migration.rb +41 -0
- data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +146 -0
- data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +65 -0
- data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +195 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +1 -0
- data/lib/rails/generators/alchemy/elements/elements_generator.rb +1 -0
- data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +0 -3
- data/lib/rails/generators/alchemy/elements/templates/editor.html.haml +0 -3
- data/lib/rails/generators/alchemy/elements/templates/editor.html.slim +0 -3
- data/lib/rails/generators/alchemy/elements/templates/view.html.erb +3 -14
- data/lib/rails/generators/alchemy/elements/templates/view.html.haml +3 -10
- data/lib/rails/generators/alchemy/elements/templates/view.html.slim +3 -10
- data/lib/tasks/alchemy/tidy.rake +1 -23
- data/lib/tasks/alchemy/upgrade.rake +44 -1
- data/vendor/assets/javascripts/flatpickr/flatpickr.min.js +2 -0
- data/vendor/assets/javascripts/tinymce/license.txt +0 -0
- data/vendor/assets/javascripts/tinymce/tinymce.min.js +2 -2
- metadata +25 -31
- data/app/assets/stylesheets/alchemy/jquery.datetimepicker.scss +0 -478
- data/app/models/alchemy/cell.rb +0 -95
- data/app/models/alchemy/page/page_cells.rb +0 -69
- data/app/serializers/alchemy/cell_serializer.rb +0 -19
- data/app/views/alchemy/admin/contents/new.html.erb +0 -11
- data/app/views/alchemy/admin/contents/order.js.erb +0 -3
- data/app/views/alchemy/admin/elements/_add_picture.html.erb +0 -14
- data/app/views/alchemy/admin/elements/_picture_gallery_editor.html.erb +0 -24
- data/bin/spring +0 -16
- data/lib/alchemy/test_support/factories/cell_factory.rb +0 -9
- data/vendor/assets/javascripts/date-formatter.js +0 -161
- data/vendor/assets/javascripts/jquery_plugins/jquery.datetimepicker.full.min.js +0 -2
data/lib/alchemy/admin/locale.rb
CHANGED
@@ -28,7 +28,7 @@ module Alchemy
|
|
28
28
|
|
29
29
|
# Checks if we need to change to locale or not.
|
30
30
|
def locale_change_needed?
|
31
|
-
params[:admin_locale].present? || session[:alchemy_locale].blank?
|
31
|
+
params[:admin_locale].present? || session[:alchemy_locale].blank?
|
32
32
|
end
|
33
33
|
|
34
34
|
# Returns either the most preferred locale that is within the list of available locales or nil
|
@@ -14,19 +14,12 @@ module Alchemy
|
|
14
14
|
def dependencies
|
15
15
|
case @name.to_s
|
16
16
|
when /^alchemy\/pages\/show/
|
17
|
-
PageLayout.all.
|
17
|
+
PageLayout.all.map { |p| "alchemy/page_layouts/_#{p['name']}" }
|
18
18
|
when /^alchemy\/page_layouts\/_(.+)/
|
19
|
-
page_layout =
|
20
|
-
|
21
|
-
page_layout.fetch('cells', []).map { |name| "alchemy/cells/_#{name}" }
|
22
|
-
when /^alchemy\/cells\/_(.+)/
|
23
|
-
element_templates cell_definition($1)
|
19
|
+
page_layout = PageLayout.get($1)
|
20
|
+
page_layout.fetch('elements', []).map { |name| "alchemy/elements/_#{name}_view" }
|
24
21
|
when /alchemy\/elements\/_(.+)_view/
|
25
22
|
essences = essence_types($1)
|
26
|
-
element = element_definition($1)
|
27
|
-
if element && element['picture_gallery']
|
28
|
-
essences += ['EssencePicture']
|
29
|
-
end
|
30
23
|
essences.map { |name| "alchemy/essences/_#{name.underscore}_view" }.uniq
|
31
24
|
else
|
32
25
|
ActionView::DependencyTracker::ERBTracker.call(@name, @template)
|
@@ -35,24 +28,8 @@ module Alchemy
|
|
35
28
|
|
36
29
|
private
|
37
30
|
|
38
|
-
def element_templates(collection)
|
39
|
-
collection.fetch('elements', []).map { |name| "alchemy/elements/_#{name}_view" }
|
40
|
-
end
|
41
|
-
|
42
|
-
def page_layout(name)
|
43
|
-
PageLayout.get(name)
|
44
|
-
end
|
45
|
-
|
46
|
-
def cell_definition(name)
|
47
|
-
Cell.definition_for(name)
|
48
|
-
end
|
49
|
-
|
50
|
-
def element_definition(name)
|
51
|
-
Element.definitions.detect { |e| e['name'] == name }
|
52
|
-
end
|
53
|
-
|
54
31
|
def essence_types(name)
|
55
|
-
element =
|
32
|
+
element = Element.definitions.detect { |e| e['name'] == name }
|
56
33
|
return [] unless element
|
57
34
|
element.fetch('contents', []).collect { |c| c['type'] }
|
58
35
|
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'alchemy/logger'
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
# Loads elements from given page
|
7
|
+
#
|
8
|
+
# Used by {Alchemy::Page#find_elements} and {Alchemy::ElementsHelper#render_elements} helper.
|
9
|
+
#
|
10
|
+
# If you need custom element loading logic in your views you can create your own finder class and
|
11
|
+
# tell the {Alchemy::ElementsHelper#render_elements} helper or {Alchemy::Page#find_elements}
|
12
|
+
# to use that finder instead of this one.
|
13
|
+
#
|
14
|
+
class ElementsFinder
|
15
|
+
# @option options [Array<String>|String] :only
|
16
|
+
# A list of element names to load only.
|
17
|
+
# @option options [Array<String>|String] :except
|
18
|
+
# A list of element names not to load.
|
19
|
+
# @option options [Boolean] :fixed (false)
|
20
|
+
# Return only fixed elements
|
21
|
+
# @option options [Integer] :count
|
22
|
+
# The amount of elements to load
|
23
|
+
# @option options [Integer] :offset
|
24
|
+
# The offset to begin loading elements from
|
25
|
+
# @option options [Boolean] :random (false)
|
26
|
+
# Randomize the output of elements
|
27
|
+
# @option options [Boolean] :reverse (false)
|
28
|
+
# Reverse the load order
|
29
|
+
# @option options [Hash] :fallback
|
30
|
+
# Define elements that are loaded from another page if no element was found on given page.
|
31
|
+
def initialize(options = {})
|
32
|
+
@options = options
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param page [Alchemy::Page|String]
|
36
|
+
# The page the elements are loaded from. You can pass a page_layout String or a {Alchemy::Page} object.
|
37
|
+
# @return [ActiveRecord::Relation]
|
38
|
+
def elements(page:)
|
39
|
+
elements = find_elements(page)
|
40
|
+
|
41
|
+
if fallback_required?(elements)
|
42
|
+
elements = elements.merge(fallback_elements)
|
43
|
+
end
|
44
|
+
|
45
|
+
if options[:reverse]
|
46
|
+
elements = elements.reverse_order
|
47
|
+
end
|
48
|
+
|
49
|
+
if options[:random]
|
50
|
+
elements = elements.reorder(Arel.sql(random_function))
|
51
|
+
end
|
52
|
+
|
53
|
+
elements.offset(options[:offset]).limit(options[:count])
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
attr_reader :page, :options
|
59
|
+
|
60
|
+
def find_elements(page)
|
61
|
+
elements = Alchemy::Element
|
62
|
+
.where(page_id: page_ids(page))
|
63
|
+
.merge(Alchemy::Element.not_nested)
|
64
|
+
.where(fixed: !!options[:fixed])
|
65
|
+
.order(position: :asc)
|
66
|
+
.available
|
67
|
+
|
68
|
+
if options[:only]
|
69
|
+
elements = elements.named(options[:only])
|
70
|
+
end
|
71
|
+
|
72
|
+
if options[:except]
|
73
|
+
elements = elements.excluded(options[:except])
|
74
|
+
end
|
75
|
+
|
76
|
+
elements
|
77
|
+
end
|
78
|
+
|
79
|
+
def page_ids(page)
|
80
|
+
case page
|
81
|
+
when String
|
82
|
+
Alchemy::Language.current.pages.where(
|
83
|
+
page_layout: page,
|
84
|
+
restricted: false
|
85
|
+
).pluck("#{Alchemy::Page.table_name}.id")
|
86
|
+
when Alchemy::Page
|
87
|
+
page.id
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def fallback_required?(elements)
|
92
|
+
options[:fallback] && elements
|
93
|
+
.where(Alchemy::Element.table_name => {name: options[:fallback][:for]})
|
94
|
+
.none?
|
95
|
+
end
|
96
|
+
|
97
|
+
def fallback_elements
|
98
|
+
find_elements(options[:fallback][:from])
|
99
|
+
.named(options[:fallback][:with] || options[:fallback][:for])
|
100
|
+
end
|
101
|
+
|
102
|
+
def random_function
|
103
|
+
case ActiveRecord::Base.connection_config[:adapter]
|
104
|
+
when 'postgresql', 'sqlite3'
|
105
|
+
then 'RANDOM()'
|
106
|
+
else
|
107
|
+
'RAND()'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/alchemy/errors.rb
CHANGED
data/lib/alchemy/modules.rb
CHANGED
@@ -6,25 +6,56 @@ module Alchemy
|
|
6
6
|
|
7
7
|
@@alchemy_modules = YAML.load_file(File.expand_path('../../config/alchemy/modules.yml', __dir__))
|
8
8
|
|
9
|
-
|
10
|
-
base
|
11
|
-
|
9
|
+
class << self
|
10
|
+
def included(base)
|
11
|
+
base.send :helper_method, :alchemy_modules, :module_definition_for
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
14
|
+
# Register a Alchemy module.
|
15
|
+
#
|
16
|
+
# A module is a Hash that must have at least a name and a navigation key
|
17
|
+
# that has a controller and action name.
|
18
|
+
#
|
19
|
+
# == Example:
|
20
|
+
#
|
21
|
+
# name: 'module',
|
22
|
+
# navigation: {
|
23
|
+
# controller: 'admin/controller_name',
|
24
|
+
# action: 'index'
|
25
|
+
# }
|
26
|
+
#
|
27
|
+
def register_module(module_definition)
|
28
|
+
definition_hash = module_definition.deep_stringify_keys
|
29
|
+
|
30
|
+
### Validate controller(s) existence
|
31
|
+
if definition_hash['navigation'].is_a?(Hash)
|
32
|
+
defined_controllers = [definition_hash['navigation']['controller']]
|
33
|
+
|
34
|
+
if definition_hash['navigation']['sub_navigation'].is_a?(Array)
|
35
|
+
defined_controllers.concat(definition_hash['navigation']['sub_navigation'].map{ |x| x['controller'] })
|
36
|
+
end
|
37
|
+
|
38
|
+
validate_controllers_existence(defined_controllers)
|
39
|
+
end
|
40
|
+
|
41
|
+
@@alchemy_modules << definition_hash
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def validate_controllers_existence(controllers)
|
47
|
+
controllers.each do |controller_val|
|
48
|
+
next if controller_val.blank?
|
49
|
+
|
50
|
+
controller_name = "#{controller_val.camelize}Controller"
|
51
|
+
|
52
|
+
begin
|
53
|
+
controller_name.constantize
|
54
|
+
rescue NameError
|
55
|
+
raise "Error in AlchemyCMS module definition: '#{definition_hash['name']}'. Could not find the matching controller class #{controller_name.sub(/^::/, '')} for the specified controller: '#{controller_val}'"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
28
59
|
end
|
29
60
|
|
30
61
|
# Get the module definition for given module name
|
data/lib/alchemy/tasks/tidy.rb
CHANGED
@@ -5,29 +5,12 @@ module Alchemy
|
|
5
5
|
extend Shell
|
6
6
|
|
7
7
|
class << self
|
8
|
-
def create_missing_cells(page_layouts, cells)
|
9
|
-
page_layouts.each do |layout|
|
10
|
-
next if layout['cells'].blank?
|
11
|
-
cells_for_layout = cells.select { |cell| layout['cells'].include? cell['name'] }
|
12
|
-
Alchemy::Page.where(page_layout: layout['name']).each do |page|
|
13
|
-
cells_for_layout.each do |cell_for_layout|
|
14
|
-
cell = Alchemy::Cell.find_or_initialize_by(name: cell_for_layout['name'], page_id: page.id)
|
15
|
-
if cell.new_record?
|
16
|
-
log "Creating cell #{cell.name} for page #{page.name}"
|
17
|
-
else
|
18
|
-
log "Cell #{cell.name} for page #{page.name} already present", :skip
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
8
|
def update_element_positions
|
26
9
|
Alchemy::Page.all.each do |page|
|
27
10
|
if page.elements.any?
|
28
11
|
puts "\n## Updating element positions of page `#{page.name}`"
|
29
12
|
end
|
30
|
-
page.elements.group_by(&:
|
13
|
+
page.elements.group_by(&:parent_element_id).each do |_, elements|
|
31
14
|
elements.each_with_index do |element, idx|
|
32
15
|
position = idx + 1
|
33
16
|
if element.position != position
|
@@ -46,8 +29,7 @@ module Alchemy
|
|
46
29
|
if element.contents.any?
|
47
30
|
puts "\n## Updating content positions of element `#{element.name}`"
|
48
31
|
end
|
49
|
-
element.contents.group_by(&:
|
50
|
-
puts "-> Contents of type `#{essence_type}`"
|
32
|
+
element.contents.group_by(&:element_id).each do |_, contents|
|
51
33
|
contents.each_with_index do |content, idx|
|
52
34
|
position = idx + 1
|
53
35
|
if content.position != position
|
@@ -61,31 +43,12 @@ module Alchemy
|
|
61
43
|
end
|
62
44
|
end
|
63
45
|
|
64
|
-
def remove_orphaned_cells
|
65
|
-
puts "\n## Removing orphaned cells"
|
66
|
-
cells = Alchemy::Cell.unscoped.all
|
67
|
-
if cells.any?
|
68
|
-
orphaned_cells = cells.select do |cell|
|
69
|
-
cell.page.nil? && cell.page_id.present?
|
70
|
-
end
|
71
|
-
if orphaned_cells.any?
|
72
|
-
log "Found #{orphaned_cells.size} orphaned cells"
|
73
|
-
destroy_orphaned_records(orphaned_cells, 'cell')
|
74
|
-
else
|
75
|
-
log "No orphaned cells found", :skip
|
76
|
-
end
|
77
|
-
else
|
78
|
-
log "No cells found", :skip
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
46
|
def remove_orphaned_elements
|
83
47
|
puts "\n## Removing orphaned elements"
|
84
48
|
elements = Alchemy::Element.unscoped.all
|
85
49
|
if elements.any?
|
86
50
|
orphaned_elements = elements.select do |element|
|
87
|
-
element.page.nil? && element.page_id.present?
|
88
|
-
element.cell.nil? && element.cell_id.present?
|
51
|
+
element.page.nil? && element.page_id.present?
|
89
52
|
end
|
90
53
|
if orphaned_elements.any?
|
91
54
|
log "Found #{orphaned_elements.size} orphaned elements"
|
@@ -2,8 +2,10 @@ require 'factory_bot'
|
|
2
2
|
|
3
3
|
FactoryBot.define do
|
4
4
|
factory :alchemy_attachment, class: 'Alchemy::Attachment' do
|
5
|
-
file
|
6
|
-
|
7
|
-
|
5
|
+
file do
|
6
|
+
File.new(Alchemy::Engine.root.join('lib', 'alchemy', 'test_support', 'fixtures', 'image.png'))
|
7
|
+
end
|
8
|
+
name { 'image' }
|
9
|
+
file_name { 'image.png' }
|
8
10
|
end
|
9
11
|
end
|
@@ -3,18 +3,18 @@ require 'alchemy/test_support/factories/essence_text_factory'
|
|
3
3
|
|
4
4
|
FactoryBot.define do
|
5
5
|
factory :alchemy_content, class: 'Alchemy::Content' do
|
6
|
-
name "text"
|
7
|
-
essence_type "Alchemy::EssenceText"
|
6
|
+
name { "text" }
|
7
|
+
essence_type { "Alchemy::EssenceText" }
|
8
8
|
association :essence, factory: :alchemy_essence_text
|
9
9
|
association :element, factory: :alchemy_element
|
10
10
|
|
11
11
|
trait :essence_file do
|
12
|
-
essence_type "Alchemy::EssenceFile"
|
12
|
+
essence_type { "Alchemy::EssenceFile" }
|
13
13
|
association :essence, factory: :alchemy_essence_file
|
14
14
|
end
|
15
15
|
|
16
16
|
trait :essence_picture do
|
17
|
-
essence_type "Alchemy::EssencePicture"
|
17
|
+
essence_type { "Alchemy::EssencePicture" }
|
18
18
|
association :essence, factory: :alchemy_essence_picture
|
19
19
|
end
|
20
20
|
end
|
@@ -3,19 +3,19 @@ require 'factory_bot'
|
|
3
3
|
FactoryBot.define do
|
4
4
|
factory :alchemy_dummy_user, class: 'DummyUser' do
|
5
5
|
sequence(:email) { |n| "john.#{n}@doe.com" }
|
6
|
-
password 's3cr3t'
|
7
|
-
alchemy_roles ['member']
|
6
|
+
password { 's3cr3t' }
|
7
|
+
alchemy_roles { ['member'] }
|
8
8
|
|
9
9
|
trait :as_admin do
|
10
|
-
alchemy_roles ['admin']
|
10
|
+
alchemy_roles { ['admin'] }
|
11
11
|
end
|
12
12
|
|
13
13
|
trait :as_author do
|
14
|
-
alchemy_roles ['author']
|
14
|
+
alchemy_roles { ['author'] }
|
15
15
|
end
|
16
16
|
|
17
17
|
trait :as_editor do
|
18
|
-
alchemy_roles ['editor']
|
18
|
+
alchemy_roles { ['editor'] }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -2,26 +2,31 @@ require 'factory_bot'
|
|
2
2
|
|
3
3
|
FactoryBot.define do
|
4
4
|
factory :alchemy_element, class: 'Alchemy::Element' do
|
5
|
-
name 'article'
|
6
|
-
|
5
|
+
name { 'article' }
|
6
|
+
autogenerate_contents { false }
|
7
7
|
association :page, factory: :alchemy_page
|
8
8
|
|
9
|
+
trait :fixed do
|
10
|
+
fixed { true }
|
11
|
+
name { 'right_column' }
|
12
|
+
end
|
13
|
+
|
9
14
|
trait :unique do
|
10
|
-
unique true
|
11
|
-
name 'header'
|
15
|
+
unique { true }
|
16
|
+
name { 'header' }
|
12
17
|
end
|
13
18
|
|
14
19
|
trait :with_nestable_elements do
|
15
|
-
name 'slider'
|
20
|
+
name { 'slider' }
|
16
21
|
end
|
17
22
|
|
18
23
|
trait :nested do
|
19
24
|
association :parent_element, factory: :alchemy_element, name: 'slider'
|
20
|
-
name 'slide'
|
25
|
+
name { 'slide' }
|
21
26
|
end
|
22
27
|
|
23
28
|
trait :with_contents do
|
24
|
-
|
29
|
+
autogenerate_contents { true }
|
25
30
|
end
|
26
31
|
end
|
27
32
|
end
|