alchemy_cms 6.1.0 → 6.1.2

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.

Potentially problematic release.


This version of alchemy_cms might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d85d573a2ae43f5152d2ae9082b0548f6cd4611b51f73aee187d796a037fb55e
4
- data.tar.gz: 4d30a22cd1c6945e1fe51fdb68c94d716b623d297c6750643518bb291041fb1a
3
+ metadata.gz: f2f303fbee5eb7ba00c41042f4a2c435e345621eae81768d8c66f86dad04d23d
4
+ data.tar.gz: e2ad0dfb05e0412676eb203c0ac7829d4945c8e8db879c8393748bb40089ce19
5
5
  SHA512:
6
- metadata.gz: a2381b9af6f92c97955d9415f6d79160cd6940edfa01be10c28ddf7e1166416216e009d903ebf680fc6d788edb6b60f1019f6cbfdc252c1cc8b7829c49369607
7
- data.tar.gz: 19a66a2d66bf5d34020a3e59a440baeb7d305dde3bc9681eb609cfef7862b58b7628b258683185f0b3fdb49d3abc89d3a0a4b1b40e4a7480129ca93f09980845
6
+ metadata.gz: 1ec82e1628873bcfb3f1e16826087289ab1dcefe4bb98598ad320bce329c3f1481dc0df28fdbd0570a3fb79f6325de4a9eee510dd4dc6a981f3cc82565bd908b
7
+ data.tar.gz: 10c17180fbff27a83a2c6f052c200a9723858dea973f547206c9ca094e46b18bdc7130f5914e006acd058296b6783b4adafa47bc2bad87fca29ca6774673a973
@@ -82,6 +82,9 @@ jobs:
82
82
  sudo apt update -qq
83
83
  sudo apt install -qq --fix-missing libmysqlclient-dev -o dir::cache::archives="/home/runner/apt/cache"
84
84
  sudo chown -R runner /home/runner/apt/cache
85
+ - uses: actions/setup-node@v3
86
+ with:
87
+ node-version: 16
85
88
  - name: Restore node modules cache
86
89
  id: yarn-cache
87
90
  uses: actions/cache@v2.1.3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.1.2 (2023-02-27)
4
+
5
+ - [6.1] Fix thumbnail writing for multi-concurrent and multi-db setups [#2434](https://github.com/AlchemyCMS/alchemy_cms/pull/2434) ([tvdeyen](https://github.com/tvdeyen))
6
+
7
+ ## 6.1.1 (2023-01-23)
8
+
9
+ - Re-introduce deleted methods [#2422](https://github.com/AlchemyCMS/alchemy_cms/pull/2422) ([tvdeyen](https://github.com/tvdeyen))
10
+ - Add searchable field to page (Alchemy 6.1) [#2420](https://github.com/AlchemyCMS/alchemy_cms/pull/2420) ([kulturbande](https://github.com/kulturbande))
11
+
3
12
  ## 6.1.0 (2023-01-19)
4
13
 
5
14
  ### Features
@@ -166,6 +166,14 @@ module Alchemy
166
166
  render "alchemy/elements/view_not_found", name: element.name
167
167
  end
168
168
 
169
+ # Returns a string for the id attribute of a html element for the given element
170
+ # @deprecated
171
+ def element_dom_id(element)
172
+ element&.dom_id
173
+ end
174
+
175
+ deprecate element_dom_id: "element.dom_id", deprecator: Alchemy::Deprecation
176
+
169
177
  # Renders the HTML tag attributes required for preview mode.
170
178
  def element_preview_code(element)
171
179
  tag_builder.tag_options(element_preview_code_attributes(element))
@@ -6,29 +6,41 @@ module Alchemy
6
6
  #
7
7
  module ElementContents
8
8
  # Find first content from element by given name.
9
+ # @deprecated
9
10
  def content_by_name(name)
10
11
  contents_by_name(name).first
11
12
  end
12
13
 
14
+ deprecate content_by_name: :ingredient_by_role, deprecator: Alchemy::Deprecation
15
+
13
16
  # Find first content from element by given essence type.
17
+ # @deprecated
14
18
  def content_by_type(essence_type)
15
19
  contents_by_type(essence_type).first
16
20
  end
17
21
 
22
+ deprecate content_by_type: :ingredient_by_type, deprecator: Alchemy::Deprecation
23
+
18
24
  # All contents from element by given name.
25
+ # @deprecated
19
26
  def contents_by_name(name)
20
27
  contents.select { |content| content.name == name.to_s }
21
28
  end
22
29
 
30
+ deprecate contents_by_name: :ingredients_by_role, deprecator: Alchemy::Deprecation
31
+
23
32
  alias_method :all_contents_by_name, :contents_by_name
24
33
 
25
34
  # All contents from element by given essence type.
35
+ # @deprecated
26
36
  def contents_by_type(essence_type)
27
37
  contents.select do |content|
28
38
  content.essence_type == Content.normalize_essence_type(essence_type)
29
39
  end
30
40
  end
31
41
 
42
+ deprecate contents_by_type: :ingredients_by_type, deprecator: Alchemy::Deprecation
43
+
32
44
  alias_method :all_contents_by_type, :contents_by_type
33
45
 
34
46
  # Updates all related contents by calling +update_essence+ on each of them.
@@ -48,6 +60,7 @@ module Alchemy
48
60
  # "2" => {link: "https://google.com"}
49
61
  # )
50
62
  #
63
+ # @deprecated
51
64
  def update_contents(contents_attributes)
52
65
  return true if contents_attributes.nil?
53
66
 
@@ -58,13 +71,18 @@ module Alchemy
58
71
  errors.blank?
59
72
  end
60
73
 
74
+ deprecate :update_contents, deprecator: Alchemy::Deprecation
75
+
61
76
  # Copy current content's contents to given target element
77
+ # @deprecated
62
78
  def copy_contents_to(element)
63
79
  contents.map do |content|
64
80
  Content.copy(content, element_id: element.id)
65
81
  end
66
82
  end
67
83
 
84
+ deprecate :copy_contents_to, deprecator: Alchemy::Deprecation
85
+
68
86
  # Returns the content that is marked as rss title.
69
87
  #
70
88
  # Mark a content as rss title in your +elements.yml+ file:
@@ -75,10 +93,13 @@ module Alchemy
75
93
  # type: EssenceText
76
94
  # rss_title: true
77
95
  #
96
+ # @deprecated
78
97
  def content_for_rss_title
79
98
  content_for_rss_meta("title")
80
99
  end
81
100
 
101
+ deprecate :content_for_rss_title, deprecator: Alchemy::Deprecation
102
+
82
103
  # Returns the content that is marked as rss description.
83
104
  #
84
105
  # Mark a content as rss description in your +elements.yml+ file:
@@ -89,18 +110,25 @@ module Alchemy
89
110
  # type: EssenceRichtext
90
111
  # rss_description: true
91
112
  #
113
+ # @deprecated
92
114
  def content_for_rss_description
93
115
  content_for_rss_meta("description")
94
116
  end
95
117
 
118
+ deprecate :content_for_rss_description, deprecator: Alchemy::Deprecation
119
+
96
120
  # Returns the array with the hashes for all element contents in the elements.yml file
121
+ # @deprecated
97
122
  def content_definitions
98
123
  return nil if definition.blank?
99
124
 
100
125
  definition["contents"]
101
126
  end
102
127
 
128
+ deprecate content_definitions: :ingredient_definitions, deprecator: Alchemy::Deprecation
129
+
103
130
  # Returns the definition for given content_name
131
+ # @deprecated
104
132
  def content_definition_for(content_name)
105
133
  if content_definitions.blank?
106
134
  log_warning "Element #{name} is missing the content definition for #{content_name}"
@@ -110,10 +138,13 @@ module Alchemy
110
138
  end
111
139
  end
112
140
 
141
+ deprecate content_definition_for: :ingredient_definition_for, deprecator: Alchemy::Deprecation
142
+
113
143
  # Returns an array of all EssenceRichtext contents ids from elements
114
144
  #
115
145
  # This is used to re-initialize the TinyMCE editor in the element editor.
116
146
  #
147
+ # @deprecated
117
148
  def richtext_contents_ids
118
149
  # This is not very efficient SQL wise I know, but we need to iterate
119
150
  # recursivly through all descendent elements and I don't know how to do this
@@ -126,16 +157,24 @@ module Alchemy
126
157
  ids.flatten
127
158
  end
128
159
 
160
+ deprecate richtext_contents_ids: :richtext_ingredients_ids, deprecator: Alchemy::Deprecation
161
+
129
162
  # True, if any of the element's contents has essence validations defined.
163
+ # @deprecated
130
164
  def has_validations?
131
165
  !contents.detect(&:has_validations?).blank?
132
166
  end
133
167
 
168
+ deprecate :has_validations?, deprecator: Alchemy::Deprecation
169
+
134
170
  # All element contents where the essence validation has failed.
171
+ # @deprecated
135
172
  def contents_with_errors
136
173
  contents.select(&:essence_validation_failed?)
137
174
  end
138
175
 
176
+ deprecate contents_with_errors: :ingredients_with_errors, deprecator: Alchemy::Deprecation
177
+
139
178
  private
140
179
 
141
180
  def content_for_rss_meta(type)
@@ -7,7 +7,7 @@ module Alchemy
7
7
  def ingredient(name)
8
8
  ing = ingredient_by_role(name)
9
9
  if ing
10
- Alchemy::Deprecation.warn <<~WARN
10
+ Alchemy::Deprecation.warn(<<~WARN)
11
11
  Using `element.ingredient` to get the value of an ingredient is deprecated and will change in Alchemy 6.1
12
12
  If you want to read the value of an elements ingredient please use `element.value_for(:ingredient_role)` instead.
13
13
  The next version of Alchemy will return a `Alchemy::Ingredient` record instead.
@@ -23,9 +23,11 @@ module Alchemy
23
23
 
24
24
  # True if the element has a content for given name,
25
25
  # that has an essence value (aka. ingredient) that is not blank.
26
+ # @deprecated
26
27
  def has_ingredient?(name)
27
28
  ingredient(name).present?
28
29
  end
30
+
29
31
  deprecate has_ingredient?: :has_value_for?, deprecator: Alchemy::Deprecation
30
32
 
31
33
  # Returns all essence errors in the format of:
@@ -39,6 +41,7 @@ module Alchemy
39
41
  #
40
42
  # Get translated error messages with +Element#essence_error_messages+
41
43
  #
44
+ # @deprecated
42
45
  def essence_errors
43
46
  essence_errors = {}
44
47
  contents.each do |content|
@@ -49,6 +52,8 @@ module Alchemy
49
52
  essence_errors
50
53
  end
51
54
 
55
+ deprecate :essence_errors, deprecator: Alchemy::Deprecation
56
+
52
57
  # Essence validation errors
53
58
  #
54
59
  # == Error messages are translated via I18n
@@ -103,6 +108,7 @@ module Alchemy
103
108
  # invalid: %{field} has wrong format
104
109
  # blank: %{field} can't be blank
105
110
  #
111
+ # @deprecated
106
112
  def essence_error_messages
107
113
  messages = []
108
114
  essence_errors.each do |content_name, errors|
@@ -120,6 +126,8 @@ module Alchemy
120
126
  end
121
127
  messages
122
128
  end
129
+
130
+ deprecate essence_error_messages: :ingredient_error_messages, deprecator: Alchemy::Deprecation
123
131
  end
124
132
  end
125
133
  end
@@ -37,6 +37,13 @@ module Alchemy
37
37
  ingredients_by_type(type).first
38
38
  end
39
39
 
40
+ # All ingredients from element by given role.
41
+ def ingredients_by_role(role)
42
+ ingredients.select do |ingredient|
43
+ ingredient.role == Ingredient.normalize_type(role)
44
+ end
45
+ end
46
+
40
47
  # All ingredients from element by given type.
41
48
  def ingredients_by_type(type)
42
49
  ingredients.select do |ingredient|
@@ -61,6 +61,8 @@ module Alchemy
61
61
 
62
62
  has_many :contents, dependent: :destroy, inverse_of: :element
63
63
 
64
+ deprecate contents: :ingredients, deprecator: Alchemy::Deprecation
65
+
64
66
  before_destroy :delete_all_nested_elements
65
67
 
66
68
  has_many :all_nested_elements,
@@ -103,6 +105,7 @@ module Alchemy
103
105
  scope :published, -> { where(public: true) }
104
106
  scope :hidden, -> { where(public: false) }
105
107
  scope :not_restricted, -> { joins(:page).merge(Page.not_restricted) }
108
+ scope :available, -> { published }
106
109
  scope :named, ->(names) { where(name: names) }
107
110
  scope :excluded, ->(names) { where.not(name: names) }
108
111
  scope :fixed, -> { where(fixed: true) }
@@ -189,6 +192,8 @@ module Alchemy
189
192
 
190
193
  all_from_clipboard(clipboard).where(name: parent_element.definition["nestable_elements"])
191
194
  end
195
+
196
+ deprecate available: :published, deprecator: Alchemy::Deprecation
192
197
  end
193
198
 
194
199
  # Returns next public element from same page.
@@ -79,6 +79,7 @@ module Alchemy
79
79
  :restricted,
80
80
  :robot_index,
81
81
  :robot_follow,
82
+ :searchable,
82
83
  :sitemap,
83
84
  :tag_list,
84
85
  :title,
@@ -3,7 +3,7 @@
3
3
  module Alchemy
4
4
  class Picture < BaseRecord
5
5
  class Url
6
- attr_reader :variant
6
+ attr_reader :variant, :thumb
7
7
 
8
8
  # @param [Alchemy::PictureVariant]
9
9
  #
@@ -31,14 +31,23 @@ module Alchemy
31
31
 
32
32
  def uid
33
33
  signature = PictureThumb::Signature.call(variant)
34
- thumb = variant.picture.thumbs.detect { |t| t.signature == signature }
35
- if thumb
36
- uid = thumb.uid
34
+ if find_thumb_by(signature)
35
+ thumb.uid
37
36
  else
38
37
  uid = PictureThumb::Uid.call(signature, variant)
39
- PictureThumb.generator_class.call(variant, signature, uid)
38
+ ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do
39
+ PictureThumb.generator_class.call(variant, signature, uid)
40
+ end
41
+ uid
40
42
  end
41
- uid
43
+ end
44
+
45
+ def find_thumb_by(signature)
46
+ @thumb = if variant.picture.thumbs.loaded?
47
+ variant.picture.thumbs.find { |t| t.signature == signature }
48
+ else
49
+ variant.picture.thumbs.find_by(signature: signature)
50
+ end
42
51
  end
43
52
  end
44
53
  end
@@ -19,11 +19,10 @@ module Alchemy
19
19
 
20
20
  # create the thumb before storing
21
21
  # to prevent db race conditions
22
- thumb = Alchemy::PictureThumb.create!(
23
- picture: variant.picture,
24
- signature: signature,
25
- uid: uid,
26
- )
22
+ @thumb = Alchemy::PictureThumb.create_or_find_by!(signature: signature) do |thumb|
23
+ thumb.picture = variant.picture
24
+ thumb.uid = uid
25
+ end
27
26
  begin
28
27
  # process the image
29
28
  image = variant.image
@@ -32,7 +31,7 @@ module Alchemy
32
31
  rescue RuntimeError => e
33
32
  ErrorTracking.notification_handler.call(e)
34
33
  # destroy the thumb if processing or storing fails
35
- thumb&.destroy
34
+ @thumb&.destroy
36
35
  end
37
36
  end
38
37
 
@@ -19,6 +19,15 @@
19
19
  <%= f.input :title,
20
20
  input_html: {'data-alchemy-char-counter' => 60} %>
21
21
 
22
+ <% if Alchemy.enable_searchable %>
23
+ <div class="input check_boxes">
24
+ <label class="control-label"><%= Alchemy.t(:fulltext_search) %></label>
25
+ <div class="control_group">
26
+ <%= page_status_checkbox(@page, :searchable) %>
27
+ </div>
28
+ </div>
29
+ <% end %>
30
+
22
31
  <div class="input check_boxes">
23
32
  <label class="control-label"><%= Alchemy.t(:search_engines) %></label>
24
33
  <div class="control_group">
@@ -594,6 +594,7 @@ en:
594
594
  saved_link: "Link saved."
595
595
  search: "search"
596
596
  search_engines: "Search engines"
597
+ fulltext_search: "Fulltext search"
597
598
  select_element: "Select element"
598
599
  seperate_tags_with_comma: "Seperate tags with comma"
599
600
  show_element_content: "Show content of this element."
@@ -879,6 +880,7 @@ en:
879
880
  page_layout: "Page type"
880
881
  public: "public"
881
882
  restricted: "restricted"
883
+ searchable: "show in search"
882
884
  robot_follow: "robot may follow links"
883
885
  robot_index: "allow robot to index"
884
886
  sitemap: "visible in sitemap"
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddSearchableToAlchemyPages < ActiveRecord::Migration[6.0]
4
+ def change
5
+ return if column_exists?(:alchemy_pages, :searchable)
6
+
7
+ add_column :alchemy_pages, :searchable, :boolean, default: true, null: false
8
+ end
9
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Alchemy
3
- Deprecation = ActiveSupport::Deprecation.new("6.1", "Alchemy")
3
+ Deprecation = ActiveSupport::Deprecation.new("7.0", "Alchemy")
4
4
  end
@@ -15,10 +15,10 @@ module Alchemy::Upgrader::Tasks
15
15
  Alchemy::Page.transaction do
16
16
  page.versions.create!(
17
17
  public_on: page.legacy_public_on,
18
- public_until: page.legacy_public_until,
18
+ public_until: page.legacy_public_until
19
19
  ).tap do |version|
20
20
  # We must not use .find_each here to not mess up the order of elements
21
- page.draft_version.elements.not_nested.published.each do |element|
21
+ page.draft_version.elements.not_nested.available.each do |element|
22
22
  Alchemy::Element.copy(element, page_version_id: version.id)
23
23
  end
24
24
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "6.1.0"
4
+ VERSION = "6.1.2"
5
5
 
6
6
  def self.version
7
7
  VERSION
data/lib/alchemy.rb CHANGED
@@ -84,4 +84,17 @@ module Alchemy
84
84
  def self.publish_targets
85
85
  @_publish_targets ||= Set.new
86
86
  end
87
+
88
+ # Enable full text search configuration
89
+ #
90
+ # It enables a searchable checkbox in the page form to toggle
91
+ # the searchable field. These information can used in a search
92
+ # plugin (e.g. https://github.com/AlchemyCMS/alchemy-pg_search).
93
+ #
94
+ # == Example
95
+ #
96
+ # # config/initializers/alchemy.rb
97
+ # Alchemy.enable_searchable = true
98
+ #
99
+ mattr_accessor :enable_searchable, default: false
87
100
  end
@@ -19,7 +19,7 @@
19
19
  <%- end -%>
20
20
  <%- end -%>
21
21
  <%- if @element['nestable_elements'].present? -%>
22
- <%%= render <%= @element_name %>.nested_elements.published %>
22
+ <%%= render <%= @element_name %>.nested_elements.available %>
23
23
  <%- end -%>
24
24
  <%%- end -%>
25
25
  <%%- end -%>
@@ -18,5 +18,5 @@
18
18
  <%- end -%>
19
19
  <%- end -%>
20
20
  <%- if @element['nestable_elements'].present? -%>
21
- = render <%= @element_name -%>.nested_elements.published
21
+ = render <%= @element_name -%>.nested_elements.available
22
22
  <%- end -%>
@@ -18,5 +18,5 @@
18
18
  <%- end -%>
19
19
  <%- end -%>
20
20
  <%- if @element['nestable_elements'].present? -%>
21
- = render <%= @element_name -%>.nested_elements.published
21
+ = render <%= @element_name -%>.nested_elements.available
22
22
  <%- end -%>
@@ -46,7 +46,7 @@ namespace :alchemy do
46
46
  ingredient_pictures = Alchemy::Ingredients::Picture.
47
47
  joins(:element).
48
48
  preload({ related_object: :thumbs }).
49
- merge(Alchemy::Element.published)
49
+ merge(Alchemy::Element.available)
50
50
 
51
51
  if ENV["ELEMENTS"].present?
52
52
  ingredient_pictures = ingredient_pictures.merge(
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alchemy_cms/admin",
3
- "version": "6.1.0",
3
+ "version": "6.1.2",
4
4
  "description": "AlchemyCMS",
5
5
  "browser": "package/admin.js",
6
6
  "files": [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.0
4
+ version: 6.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas von Deyen
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2023-01-19 00:00:00.000000000 Z
16
+ date: 2023-02-27 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: actionmailer
@@ -1305,6 +1305,7 @@ files:
1305
1305
  - db/migrate/20210508091432_create_alchemy_ingredients.rb
1306
1306
  - db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb
1307
1307
  - db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb
1308
+ - db/migrate/20230123112425_add_searchable_to_alchemy_pages.rb
1308
1309
  - lib/alchemy.rb
1309
1310
  - lib/alchemy/ability_helper.rb
1310
1311
  - lib/alchemy/admin/locale.rb
@@ -1537,7 +1538,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1537
1538
  version: '0'
1538
1539
  requirements:
1539
1540
  - ImageMagick (libmagick), v6.6 or greater.
1540
- rubygems_version: 3.3.26
1541
+ rubygems_version: 3.4.6
1541
1542
  signing_key:
1542
1543
  specification_version: 4
1543
1544
  summary: A powerful, userfriendly and flexible CMS for Rails