solidus_core 3.1.5 → 3.2.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/products_helper.rb +1 -1
  3. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +26 -11
  4. data/app/models/concerns/spree/active_storage_adapter.rb +1 -1
  5. data/app/models/concerns/spree/user_address_book.rb +11 -1
  6. data/app/models/concerns/spree/user_methods.rb +20 -1
  7. data/app/models/spree/adjustment.rb +1 -0
  8. data/app/models/spree/carton.rb +1 -1
  9. data/app/models/spree/log_entry.rb +74 -1
  10. data/app/models/spree/option_value.rb +9 -0
  11. data/app/models/spree/order.rb +68 -29
  12. data/app/models/spree/order_contents.rb +2 -1
  13. data/app/models/spree/order_inventory.rb +1 -1
  14. data/app/models/spree/order_merger.rb +2 -2
  15. data/app/models/spree/order_shipping.rb +6 -9
  16. data/app/models/spree/order_taxation.rb +6 -4
  17. data/app/models/spree/order_updater.rb +4 -3
  18. data/app/models/spree/payment_method.rb +11 -0
  19. data/app/models/spree/product/scopes.rb +21 -3
  20. data/app/models/spree/product.rb +2 -1
  21. data/app/models/spree/promotion/actions/create_adjustment.rb +4 -0
  22. data/app/models/spree/promotion/actions/create_item_adjustments.rb +5 -6
  23. data/app/models/spree/promotion/rules/product.rb +20 -8
  24. data/app/models/spree/promotion/rules/store.rb +4 -0
  25. data/app/models/spree/promotion/rules/taxon.rb +4 -0
  26. data/app/models/spree/promotion/rules/user.rb +4 -0
  27. data/app/models/spree/promotion.rb +34 -23
  28. data/app/models/spree/promotion_action.rb +4 -0
  29. data/app/models/spree/promotion_code.rb +10 -6
  30. data/app/models/spree/promotion_handler/cart.rb +26 -6
  31. data/app/models/spree/promotion_rule.rb +5 -0
  32. data/app/models/spree/refund.rb +8 -0
  33. data/app/models/spree/reimbursement.rb +2 -2
  34. data/app/models/spree/return_item.rb +1 -2
  35. data/app/models/spree/stock/allocator/on_hand_first.rb +2 -2
  36. data/app/models/spree/stock/quantifier.rb +12 -8
  37. data/app/models/spree/stock/simple_coordinator.rb +2 -1
  38. data/app/models/spree/store_credit.rb +8 -0
  39. data/app/models/spree/tax/item_tax.rb +3 -2
  40. data/app/models/spree/tax/order_tax.rb +3 -1
  41. data/app/models/spree/tax/tax_location.rb +4 -7
  42. data/app/models/spree/tax_rate.rb +2 -0
  43. data/app/models/spree/variant.rb +1 -1
  44. data/app/subscribers/spree/mailer_subscriber.rb +4 -0
  45. data/app/subscribers/spree/order_mailer_subscriber.rb +35 -0
  46. data/config/locales/en.yml +9 -2
  47. data/db/migrate/20201127212108_add_type_before_removal_to_spree_payment_methods.rb +7 -0
  48. data/db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb +20 -0
  49. data/lib/generators/solidus/install/install_generator/bundler_context.rb +97 -0
  50. data/lib/generators/solidus/install/install_generator/install_frontend.rb +50 -0
  51. data/lib/generators/solidus/install/install_generator/support_solidus_frontend_extraction.rb +48 -0
  52. data/lib/generators/solidus/install/install_generator.rb +58 -50
  53. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +6 -16
  54. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/backend/all.js +2 -2
  55. data/lib/spree/app_configuration.rb +43 -0
  56. data/lib/spree/bus.rb +20 -0
  57. data/lib/spree/core/controller_helpers/auth.rb +9 -1
  58. data/lib/spree/core/controller_helpers/current_host.rb +1 -3
  59. data/lib/spree/core/controller_helpers/order.rb +10 -10
  60. data/lib/spree/core/controller_helpers/search.rb +1 -1
  61. data/lib/spree/core/engine.rb +39 -8
  62. data/lib/spree/core/state_machines/order.rb +1 -1
  63. data/lib/spree/core/stock_configuration.rb +18 -0
  64. data/lib/spree/core/validators/email.rb +3 -1
  65. data/lib/spree/core/version.rb +1 -1
  66. data/lib/spree/core.rb +20 -0
  67. data/lib/spree/event/subscriber_registry.rb +4 -6
  68. data/lib/spree/event.rb +1 -1
  69. data/lib/spree/migrations.rb +1 -1
  70. data/lib/spree/permission_sets/default_customer.rb +8 -1
  71. data/lib/spree/permitted_attributes.rb +4 -4
  72. data/lib/spree/preferences/configuration.rb +34 -12
  73. data/lib/spree/preferences/preferable_class_methods.rb +1 -1
  74. data/lib/spree/preferences/preference_differentiator.rb +2 -1
  75. data/lib/spree/preferences/static_model_preferences.rb +0 -2
  76. data/lib/spree/rails_compatibility.rb +99 -0
  77. data/lib/spree/testing_support/bus_helpers.rb +101 -0
  78. data/lib/spree/testing_support/common_rake.rb +47 -19
  79. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/backend/all.js +1 -1
  80. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/frontend/all.js +1 -1
  81. data/lib/spree/testing_support/dummy_app.rb +6 -1
  82. data/lib/spree/testing_support/factories/address_factory.rb +7 -2
  83. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
  84. data/lib/spree/testing_support/factories/order_factory.rb +8 -4
  85. data/lib/spree/testing_support/factories/product_factory.rb +4 -1
  86. data/lib/spree/testing_support/factories/store_credit_factory.rb +4 -4
  87. data/lib/spree/testing_support/factories/user_factory.rb +6 -0
  88. data/lib/spree/testing_support/factory_bot.rb +1 -1
  89. data/lib/spree/testing_support/order_walkthrough.rb +5 -4
  90. data/lib/spree/testing_support/silence_deprecations.rb +9 -0
  91. data/lib/tasks/payment_method.rake +29 -0
  92. data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +2 -2
  93. data/lib/tasks/solidus/split_promotions_with_any_match_policy.rake +33 -0
  94. data/solidus_core.gemspec +7 -2
  95. metadata +88 -23
  96. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -10
  97. data/lib/generators/solidus/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -9
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SetPromotionsWithAnyPolicyToAllIfPossible < ActiveRecord::Migration[5.2]
4
+ def up
5
+ Spree::Promotion.where(match_policy: :any).includes(:promotion_rules).all.each do |promotion|
6
+ if promotion.promotion_rules.length <= 1
7
+ promotion.update!(match_policy: :all)
8
+ else
9
+ raise StandardError, <<~MSG
10
+ You have promotions with a match policy of any and more than one rule. Please
11
+ run `bundle exec rake solidus:split_promotions_with_any_match_policy`.
12
+ MSG
13
+ end
14
+ end
15
+ end
16
+
17
+ def down
18
+ # No-Op
19
+ end
20
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solidus
4
+ class InstallGenerator < Rails::Generators::Base
5
+ # Bundler context during the install process.
6
+ #
7
+ # This class gives access to information about the bundler context in which
8
+ # the install generator is run. I.e., which solidus components are present
9
+ # in the user's Gemfile. It also allows modifying the Gemfile to add or
10
+ # remove gems.
11
+ #
12
+ # @api private
13
+ class BundlerContext
14
+ # Write and remove into and from a Gemfile
15
+ #
16
+ # This custom injector fixes support for path, git and custom sources,
17
+ # which is missing in bundler's upstream injector for a dependency fetched
18
+ # with `Bundled.locked_gems.dependencies`.
19
+ #
20
+ # @api private
21
+ class InjectorWithPathSupport < Bundler::Injector
22
+ private def build_gem_lines(conservative_versioning)
23
+ @deps.map do |d|
24
+ name = d.name.dump
25
+ is_local = d.source.instance_of?(Bundler::Source::Path)
26
+ is_git = d.source.instance_of?(Bundler::Source::Git)
27
+
28
+ requirement = if is_local
29
+ ", path: \"#{d.source.path}\""
30
+ elsif is_git
31
+ ", git: \"#{d.git}\"".yield_self { |g| d.ref ? g + ", ref: \"#{d.ref}\"" : g }
32
+ elsif conservative_versioning
33
+ ", \"#{conservative_version(@definition.specs[d.name][0])}\""
34
+ else
35
+ ", #{d.requirement.as_list.map(&:dump).join(", ")}"
36
+ end
37
+
38
+ source = ", :source => \"#{d.source.remotes.join(",")}\"" unless is_local || is_git || d.source.nil?
39
+
40
+ %(gem #{name}#{requirement}#{source})
41
+ end.join("\n")
42
+ end
43
+ end
44
+
45
+ attr_reader :dependencies, :injector
46
+
47
+ def self.bundle_cleanly(&block)
48
+ Bundler.respond_to?(:with_unbundled_env) ? Bundler.with_unbundled_env(&block) : Bundler.with_clean_env(&block)
49
+ end
50
+
51
+ def initialize
52
+ @dependencies = Bundler.locked_gems.dependencies
53
+ @injector = InjectorWithPathSupport
54
+ end
55
+
56
+ def solidus_in_gemfile?
57
+ !solidus_dependency.nil?
58
+ end
59
+
60
+ def component_in_gemfile?(name)
61
+ !@dependencies["solidus_#{name}"].nil?
62
+ end
63
+
64
+ def break_down_components(components)
65
+ raise <<~MSG unless solidus_in_gemfile?
66
+ solidus meta gem needs to be present in the Gemfile to build the component dependency
67
+ MSG
68
+
69
+ @injector.inject(
70
+ components.map { |component| dependency_for_component(component) }
71
+ )
72
+ end
73
+
74
+ def remove(*args, **kwargs, &block)
75
+ @injector.remove(*args, **kwargs, &block)
76
+ end
77
+
78
+ private
79
+
80
+ def dependency_for_component(component)
81
+ Bundler::Dependency.new(
82
+ "solidus_#{component}",
83
+ solidus_dependency.requirement,
84
+ {
85
+ "source" => solidus_dependency.source,
86
+ "git" => solidus_dependency.source.try(:uri),
87
+ "ref" => solidus_dependency.source.try(:ref)
88
+ }
89
+ )
90
+ end
91
+
92
+ def solidus_dependency
93
+ @dependencies['solidus']
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solidus
4
+ class InstallGenerator < Rails::Generators::Base
5
+ class InstallFrontend
6
+ attr_reader :bundler_context,
7
+ :generator_context
8
+
9
+ def initialize(bundler_context:, generator_context:)
10
+ @bundler_context = bundler_context
11
+ @generator_context = generator_context
12
+ end
13
+
14
+ def call(frontend, installer_adds_auth:)
15
+ case frontend
16
+ when 'solidus_frontend'
17
+ install_solidus_frontend
18
+ when 'solidus_starter_frontend'
19
+ install_solidus_starter_frontend(installer_adds_auth)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def install_solidus_frontend
26
+ unless @bundler_context.component_in_gemfile?(:frontend)
27
+ BundlerContext.bundle_cleanly do
28
+ `bundle add solidus_frontend`
29
+ `bundle install`
30
+ end
31
+ end
32
+
33
+ @generator_context.generate('solidus_frontend:install')
34
+ end
35
+
36
+ def install_solidus_starter_frontend(installer_adds_auth)
37
+ @bundler_context.remove(['solidus_frontend']) if @bundler_context.component_in_gemfile?(:frontend)
38
+
39
+ # TODO: Move installation of solidus_auth_devise to the
40
+ # solidus_starter_frontend template
41
+ BundlerContext.bundle_cleanly { `bundle add solidus_auth_devise` } unless auth_present?(installer_adds_auth)
42
+ `LOCATION="https://raw.githubusercontent.com/solidusio/solidus_starter_frontend/main/template.rb" bin/rails app:template`
43
+ end
44
+
45
+ def auth_present?(installer_adds_auth)
46
+ installer_adds_auth || @bundler_context.component_in_gemfile?(:auth_devise)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solidus
4
+ class InstallGenerator < Rails::Generators::Base
5
+ # Helper for extracting solidus_frontend from solidus meta-gem
6
+ #
7
+ # We're recommending users use newer solidus_starter_frontend. However,
8
+ # we're still shipping solidus_frontend as part of the solidus meta-gem. The
9
+ # reason is that we don't want users updating previous versions to see its
10
+ # storefront gone suddenly.
11
+ #
12
+ # In future solidus releases, solidus_frontend won't be a component anymore.
13
+ # However, until that happens:
14
+ #
15
+ # - For users of the new frontend, we need to prevent pulling
16
+ # solidus_frontend.
17
+ # - For users of the legacy frontend, we need to prevent Bundler from
18
+ # resolving it from the mono-repo while it's still there.
19
+ #
20
+ # This class is a needed companion during the deprecation
21
+ # path. It'll modify the user's Gemfile, breaking the solidus gem down into
22
+ # its components but solidus_frontend.
23
+ class SupportSolidusFrontendExtraction
24
+ attr_reader :bundler_context
25
+
26
+ def initialize(bundler_context:)
27
+ @bundler_context = bundler_context
28
+ end
29
+
30
+ def call
31
+ return unless needs_to_break_down_solidus_meta_gem?
32
+
33
+ break_down_solidus_meta_gem
34
+ end
35
+
36
+ private
37
+
38
+ def break_down_solidus_meta_gem
39
+ @bundler_context.break_down_components(%w[core backend api sample])
40
+ @bundler_context.remove(['solidus'])
41
+ end
42
+
43
+ def needs_to_break_down_solidus_meta_gem?
44
+ @bundler_context.solidus_in_gemfile?
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,21 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rails/generators'
4
+ require 'rails/version'
5
+ require_relative 'install_generator/bundler_context'
6
+ require_relative 'install_generator/support_solidus_frontend_extraction'
7
+ require_relative 'install_generator/install_frontend'
4
8
 
5
9
  module Solidus
6
10
  # @private
7
11
  class InstallGenerator < Rails::Generators::Base
8
12
  CORE_MOUNT_ROUTE = "mount Spree::Core::Engine"
9
13
 
10
- PAYMENT_METHODS = {
11
- 'paypal' => 'solidus_paypal_commerce_platform',
12
- 'none' => nil,
13
- }
14
+ LEGACY_FRONTEND = 'solidus_frontend'
15
+ DEFAULT_FRONTEND = 'solidus_starter_frontend'
16
+ FRONTENDS = [
17
+ DEFAULT_FRONTEND,
18
+ LEGACY_FRONTEND,
19
+ 'none'
20
+ ].freeze
14
21
 
15
22
  class_option :migrate, type: :boolean, default: true, banner: 'Run Solidus migrations'
16
23
  class_option :seed, type: :boolean, default: true, banner: 'Load seed data (migrations must be run)'
17
24
  class_option :sample, type: :boolean, default: true, banner: 'Load sample data (migrations must be run)'
18
- class_option :active_storage, type: :boolean, default: true, banner: 'Install ActiveStorage as image attachments handler for products and taxons'
25
+ class_option :active_storage, type: :boolean, default: Rails.gem_version >= Gem::Version.new("6.1.0"), banner: 'Install ActiveStorage as image attachments handler for products and taxons'
19
26
  class_option :auto_accept, type: :boolean
20
27
  class_option :user_class, type: :string
21
28
  class_option :admin_email, type: :string
@@ -23,11 +30,11 @@ module Solidus
23
30
  class_option :lib_name, type: :string, default: 'spree'
24
31
  class_option :with_authentication, type: :boolean, default: true
25
32
  class_option :enforce_available_locales, type: :boolean, default: nil
26
- class_option :payment_method,
33
+ class_option :frontend,
27
34
  type: :string,
28
- enum: PAYMENT_METHODS.keys,
29
- default: PAYMENT_METHODS.keys.first,
30
- desc: "Indicates which payment method to install."
35
+ enum: FRONTENDS,
36
+ default: nil,
37
+ desc: "Indicates which frontend to install."
31
38
 
32
39
  def self.source_paths
33
40
  paths = superclass.source_paths
@@ -83,16 +90,10 @@ module Solidus
83
90
  empty_directory 'app/assets/images'
84
91
 
85
92
  %w{javascripts stylesheets images}.each do |path|
86
- empty_directory "vendor/assets/#{path}/spree/frontend" if defined? Spree::Frontend || Rails.env.test?
87
- empty_directory "vendor/assets/#{path}/spree/backend" if defined? Spree::Backend || Rails.env.test?
93
+ empty_directory "vendor/assets/#{path}/spree/backend" if defined?(Spree::Backend) || Rails.env.test?
88
94
  end
89
95
 
90
- if defined? Spree::Frontend || Rails.env.test?
91
- template "vendor/assets/javascripts/spree/frontend/all.js"
92
- template "vendor/assets/stylesheets/spree/frontend/all.css"
93
- end
94
-
95
- if defined? Spree::Backend || Rails.env.test?
96
+ if defined?(Spree::Backend) || Rails.env.test?
96
97
  template "vendor/assets/javascripts/spree/backend/all.js"
97
98
  template "vendor/assets/stylesheets/spree/backend/all.css"
98
99
  end
@@ -103,17 +104,6 @@ module Solidus
103
104
  end
104
105
 
105
106
  def configure_application
106
- application <<-RUBY
107
- # Load application's model / class decorators
108
- initializer 'spree.decorators' do |app|
109
- config.to_prepare do
110
- Dir.glob(Rails.root.join('app/**/*_decorator*.rb')) do |path|
111
- require_dependency(path)
112
- end
113
- end
114
- end
115
- RUBY
116
-
117
107
  if !options[:enforce_available_locales].nil?
118
108
  application <<-RUBY
119
109
  # Prevent this deprecation message: https://github.com/svenfuchs/i18n/commit/3b6e56e
@@ -132,6 +122,9 @@ module Solidus
132
122
  Solidus has a default authentication extension that uses Devise.
133
123
  You can find more info at https://github.com/solidusio/solidus_auth_devise.
134
124
 
125
+ Regardless of what you answer here, it'll be installed if you choose
126
+ solidus_starter_frontend as your storefront in a later step.
127
+
135
128
  Would you like to install it? (Y/n)"))
136
129
 
137
130
  @plugins_to_be_installed << 'solidus_auth_devise'
@@ -139,25 +132,6 @@ module Solidus
139
132
  end
140
133
  end
141
134
 
142
- def install_payment_method
143
- name = options[:payment_method]
144
-
145
- unless options[:auto_accept]
146
- available_names = PAYMENT_METHODS.keys
147
-
148
- name = ask("
149
- You can select a payment method to be included in the installation process.
150
- Please select a payment method name:", limited_to: available_names, default: available_names.first)
151
- end
152
-
153
- gem_name = PAYMENT_METHODS.fetch(name)
154
-
155
- if gem_name
156
- @plugins_to_be_installed << gem_name
157
- @plugin_generators_to_run << "#{gem_name}:install"
158
- end
159
- end
160
-
161
135
  def include_seed_data
162
136
  append_file "db/seeds.rb", <<-RUBY.strip_heredoc
163
137
 
@@ -181,7 +155,7 @@ module Solidus
181
155
  gem plugin_name
182
156
  end
183
157
 
184
- bundle_cleanly{ run "bundle install" } if @plugins_to_be_installed.any?
158
+ BundlerContext.bundle_cleanly { run "bundle install" } if @plugins_to_be_installed.any?
185
159
  run "spring stop" if defined?(Spring)
186
160
 
187
161
  @plugin_generators_to_run.each do |plugin_generator_name|
@@ -189,6 +163,22 @@ module Solidus
189
163
  end
190
164
  end
191
165
 
166
+ def install_frontend
167
+ return if options[:frontend] == 'none'
168
+
169
+ bundler_context = BundlerContext.new
170
+
171
+ frontend = detect_frontend_to_install(bundler_context)
172
+
173
+ support_solidus_frontend_extraction(bundler_context) unless frontend == LEGACY_FRONTEND
174
+
175
+ say_status :installing, frontend
176
+
177
+ InstallFrontend.
178
+ new(bundler_context: bundler_context, generator_context: self).
179
+ call(frontend, installer_adds_auth: @plugins_to_be_installed.include?('solidus_auth_devise'))
180
+ end
181
+
192
182
  def run_migrations
193
183
  if @run_migrations
194
184
  say_status :running, "migrations"
@@ -257,8 +247,26 @@ module Solidus
257
247
 
258
248
  private
259
249
 
260
- def bundle_cleanly(&block)
261
- Bundler.respond_to?(:with_unbundled_env) ? Bundler.with_unbundled_env(&block) : Bundler.with_clean_env(&block)
250
+ def detect_frontend_to_install(bundler_context)
251
+ ENV['FRONTEND'] ||
252
+ options[:frontend] ||
253
+ (bundler_context.component_in_gemfile?(:frontend) && LEGACY_FRONTEND) ||
254
+ (options[:auto_accept] && DEFAULT_FRONTEND) ||
255
+ ask(<<~MSG.indent(8), limited_to: FRONTENDS, default: DEFAULT_FRONTEND)
256
+
257
+ Which frontend would you like to use? solidus_starter_frontend is
258
+ recommended. However, some extensions are still only compatible with
259
+ the now deprecated solidus_frontend.
260
+
261
+ MSG
262
+ end
263
+
264
+ def support_solidus_frontend_extraction(bundler_context)
265
+ say_status "break down", "solidus"
266
+
267
+ SupportSolidusFrontendExtraction.
268
+ new(bundler_context: bundler_context).
269
+ call
262
270
  end
263
271
  end
264
272
  end
@@ -31,16 +31,6 @@ Spree.config do |config|
31
31
  # to a custom users role:
32
32
  # config.roles.assign_permissions :role_name, ['Spree::PermissionSets::CustomPermissionSet']
33
33
 
34
-
35
- # Frontend:
36
-
37
- # Custom logo for the frontend
38
- # config.logo = "logo/solidus.svg"
39
-
40
- # Template to use when rendering layout
41
- # config.layout = "spree/layouts/spree_application"
42
-
43
-
44
34
  # Admin:
45
35
 
46
36
  # Custom logo for the admin
@@ -62,12 +52,6 @@ Spree.config do |config|
62
52
  # )
63
53
  end
64
54
 
65
- <% if defined?(Spree::Frontend::Engine) -%>
66
- Spree::Frontend::Config.configure do |config|
67
- config.locale = 'en'
68
- end
69
- <% end -%>
70
-
71
55
  <% if defined?(Spree::Backend::Engine) -%>
72
56
  Spree::Backend::Config.configure do |config|
73
57
  config.locale = 'en'
@@ -80,6 +64,12 @@ Spree::Backend::Config.configure do |config|
80
64
  # 'icon-name',
81
65
  # url: 'https://solidus.io/'
82
66
  # )
67
+
68
+ # Custom frontend product path
69
+ #
70
+ # config.frontend_product_path = ->(template_context, product) {
71
+ # template_context.spree.product_path(product)
72
+ # }
83
73
  end
84
74
  <% end -%>
85
75
 
@@ -1,10 +1,10 @@
1
1
  // This is a manifest file that'll be compiled into including all the files listed below.
2
- // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
2
+ // Add new JavaScript code in separate files in this directory and they'll automatically
3
3
  // be included in the compiled file accessible from http://example.com/assets/application.js
4
4
  // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
5
  // the compiled file.
6
6
  //
7
- //= require jquery
7
+ //= require jquery3
8
8
  //= require rails-ujs
9
9
  //= require spree/backend
10
10
  //= require_tree .
@@ -60,6 +60,11 @@ module Spree
60
60
  # @return [Boolean] When false, customers must create an account to complete an order (default: +true+)
61
61
  preference :allow_guest_checkout, :boolean, default: true
62
62
 
63
+ # @!attribute [rw] allow_promotions_any_match_policy
64
+ # @return [Boolean] When false, admins cannot create promotions with an "any" match policy (default: +false+)
65
+ # Create individual, separate promotions for each of your rules instead.
66
+ preference :allow_promotions_any_match_policy, :boolean, default: false
67
+
63
68
  # @!attribute [rw] guest_token_cookie_options
64
69
  # @return [Hash] Add additional guest_token cookie options here (ie. domain or path)
65
70
  preference :guest_token_cookie_options, :hash, default: {}
@@ -145,6 +150,10 @@ module Spree
145
150
  # @return [String] Two-letter ISO code of a {Spree::Country} to assumed as the country of an unidentified customer (default: "US")
146
151
  preference :default_country_iso, :string, default: 'US'
147
152
 
153
+ # @!attribute [rw] default_email_regexp
154
+ # @return [Regexp] Regex to be used in email validations, for example in Spree::EmailValidator
155
+ preference :default_email_regexp, :regexp, default: URI::MailTo::EMAIL_REGEXP
156
+
148
157
  # @!attribute [rw] generate_api_key_for_all_roles
149
158
  # @return [Boolean] Allow generating api key automatically for user
150
159
  # at role_user creation for all roles. (default: +false+)
@@ -165,6 +174,22 @@ module Spree
165
174
  # @return [String] URL of logo used on frontend (default: +'logo/solidus.svg'+)
166
175
  preference :logo, :string, default: 'logo/solidus.svg'
167
176
 
177
+ # @!attribute [rw] log_entry_permitted_classes
178
+ # @return [Array<String>] An array of extra classes that are allowed to be
179
+ # loaded from a serialized YAML as details in {Spree::LogEntry}
180
+ # (defaults to a non-frozen empty array, so that extensions can add
181
+ # their own classes).
182
+ # @example
183
+ # config.log_entry_permitted_classes = ['Date']
184
+ preference :log_entry_permitted_classes, :array, default: []
185
+
186
+ # @!attribute [rw] log_entry_allow_aliases
187
+ # @return [Boolean] Whether YAML aliases are allowed when loading
188
+ # serialized data in {Spree::LogEntry}. It defaults to true. Depending
189
+ # on the source of your data, you may consider disabling it to prevent
190
+ # entity expansion attacks.
191
+ preference :log_entry_allow_aliases, :boolean, default: true
192
+
168
193
  # @!attribute [rw] mails_from
169
194
  # @return [String] Email address used as +From:+ field in transactional emails.
170
195
  preference :mails_from, :string, default: 'solidus@example.com'
@@ -263,6 +288,13 @@ module Spree
263
288
  # @return [] Track on_hand values for variants / products. (default: true)
264
289
  preference :track_inventory_levels, :boolean, default: true
265
290
 
291
+ # @!attribute [rw] use_legacy_events
292
+ # Before v3.2, Solidus used a custom pub/sub implementation based on
293
+ # ActiveSupport::Notifications. Now, we internally use and recommend
294
+ # [Omnes](https://github.com/nebulab/omnes). This preference allows falling
295
+ # back to the old system.
296
+ # @return [Boolean]
297
+ versioned_preference :use_legacy_events, :boolean, initial_value: true, boundaries: { "3.2.0.alpha" => false }
266
298
 
267
299
  # Other configurations
268
300
 
@@ -525,6 +557,17 @@ module Spree
525
557
  # Enumerable of taxons adhering to the present_taxon_class interface
526
558
  class_name_attribute :taxon_attachment_module, default: 'Spree::Taxon::ActiveStorageAttachment'
527
559
 
560
+ # Configures the absolute path that contains the Solidus engine
561
+ # migrations. This will be checked at app boot to confirm that all Solidus
562
+ # migrations are installed.
563
+ #
564
+ # @!attribute [rw] migration_path
565
+ # @return [Pathname] the configured path. (default: `Rails.root.join('db', 'migrate')`)
566
+ attr_writer :migration_path
567
+ def migration_path
568
+ @migration_path ||= ::Rails.root.join('db', 'migrate')
569
+ end
570
+
528
571
  # Allows providing your own class instance for generating order numbers.
529
572
  #
530
573
  # @!attribute [rw] order_number_generator
data/lib/spree/bus.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'omnes'
2
+
3
+ module Spree
4
+ # Global [Omnes](https://github.com/nebulab/omnes) bus.
5
+ #
6
+ # This is used for internal events, while host applications are also able to
7
+ # use it.
8
+ #
9
+ # It has some modifications to support internal usage of the legacy event
10
+ # system {see Spree::AppConfiguration#use_legacy_events}.
11
+ Bus = Omnes::Bus.new
12
+ Bus.define_singleton_method(:publish) do |*args, **kwargs, &block|
13
+ if Spree::Config.use_legacy_events
14
+ Spree::Event.fire(*args, **kwargs, &block)
15
+ else
16
+ # Override caller_location to point to the actual event publisher
17
+ super(*args, **kwargs, caller_location: caller_locations(1)[0], &block)
18
+ end
19
+ end
20
+ end
@@ -18,6 +18,7 @@ module Spree
18
18
  included do
19
19
  before_action :set_guest_token
20
20
  helper_method :try_spree_current_user
21
+ helper_method :spree_current_user
21
22
 
22
23
  class_attribute :unauthorized_redirect
23
24
  self.unauthorized_redirect = -> do
@@ -32,7 +33,7 @@ module Spree
32
33
 
33
34
  # Needs to be overriden so that we use Spree's Ability rather than anyone else's.
34
35
  def current_ability
35
- @current_ability ||= Spree::Ability.new(try_spree_current_user)
36
+ @current_ability ||= Spree::Ability.new(spree_current_user)
36
37
  end
37
38
 
38
39
  def redirect_back_or_default(default)
@@ -53,6 +54,11 @@ module Spree
53
54
  Spree::UserLastUrlStorer.new(self).store_location
54
55
  end
55
56
 
57
+ # Auth extensions are expected to define it, otherwise it's a no-op
58
+ def spree_current_user
59
+ defined?(super) ? super : nil
60
+ end
61
+
56
62
  # proxy method to *possible* spree_current_user method
57
63
  # Authentication extensions (such as spree_auth_devise) are meant to provide spree_current_user
58
64
  def try_spree_current_user
@@ -65,6 +71,8 @@ module Spree
65
71
  current_spree_user
66
72
  end
67
73
  end
74
+
75
+ deprecate try_spree_current_user: :spree_current_user, deprecator: Spree::Deprecation
68
76
  end
69
77
  end
70
78
  end
@@ -7,9 +7,7 @@ module Spree
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
- before_action do
11
- ActiveStorage::Current.host = request.base_url
12
- end
10
+ Spree::RailsCompatibility.active_storage_set_current(self)
13
11
  end
14
12
  end
15
13
  end
@@ -24,9 +24,9 @@ module Spree
24
24
 
25
25
  if should_build && (@current_order.nil? || @current_order.completed?)
26
26
  @current_order = Spree::Order.new(new_order_params)
27
- @current_order.user ||= try_spree_current_user
27
+ @current_order.user ||= spree_current_user
28
28
  # See issue https://github.com/spree/spree/issues/3346 for reasons why this line is here
29
- @current_order.created_by ||= try_spree_current_user
29
+ @current_order.created_by ||= spree_current_user
30
30
  @current_order.save! if should_create
31
31
  end
32
32
 
@@ -38,15 +38,15 @@ module Spree
38
38
 
39
39
  def associate_user
40
40
  @order ||= current_order
41
- if try_spree_current_user && @order
42
- @order.associate_user!(try_spree_current_user) if @order.user.blank? || @order.email.blank?
41
+ if spree_current_user && @order
42
+ @order.associate_user!(spree_current_user) if @order.user.blank? || @order.email.blank?
43
43
  end
44
44
  end
45
45
 
46
46
  def set_current_order
47
- if try_spree_current_user && current_order
48
- try_spree_current_user.orders.by_store(current_store).incomplete.where('id != ?', current_order.id).each do |order|
49
- current_order.merge!(order, try_spree_current_user)
47
+ if spree_current_user && current_order
48
+ spree_current_user.orders.by_store(current_store).incomplete.where('id != ?', current_order.id).each do |order|
49
+ current_order.merge!(order, spree_current_user)
50
50
  end
51
51
  end
52
52
  end
@@ -58,11 +58,11 @@ module Spree
58
58
  private
59
59
 
60
60
  def last_incomplete_order
61
- @last_incomplete_order ||= try_spree_current_user.last_incomplete_spree_order(store: current_store)
61
+ @last_incomplete_order ||= spree_current_user.last_incomplete_spree_order(store: current_store)
62
62
  end
63
63
 
64
64
  def current_order_params
65
- { currency: current_pricing_options.currency, guest_token: cookies.signed[:guest_token], store_id: current_store.id, user_id: try_spree_current_user.try(:id) }
65
+ { currency: current_pricing_options.currency, guest_token: cookies.signed[:guest_token], store_id: current_store.id, user_id: spree_current_user.try(:id) }
66
66
  end
67
67
 
68
68
  def new_order_params
@@ -76,7 +76,7 @@ module Spree
76
76
  order = Spree::Order.incomplete.lock(should_lock).find_by(current_order_params)
77
77
 
78
78
  # Find any incomplete orders for the current user
79
- if order.nil? && try_spree_current_user
79
+ if order.nil? && spree_current_user
80
80
  order = last_incomplete_order
81
81
  end
82
82
 
@@ -6,7 +6,7 @@ module Spree
6
6
  module Search
7
7
  def build_searcher(params)
8
8
  Spree::Config.searcher_class.new(params).tap do |searcher|
9
- searcher.current_user = try_spree_current_user
9
+ searcher.current_user = spree_current_user
10
10
  searcher.pricing_options = current_pricing_options
11
11
  end
12
12
  end