solidus_core 3.1.6 → 3.2.0

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.
Files changed (96) 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 +23 -10
  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_taxation.rb +6 -4
  16. data/app/models/spree/order_updater.rb +4 -3
  17. data/app/models/spree/payment_method.rb +11 -0
  18. data/app/models/spree/price.rb +1 -1
  19. data/app/models/spree/product/scopes.rb +21 -3
  20. data/app/models/spree/product.rb +1 -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 +8 -4
  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/reimbursement.rb +2 -2
  33. data/app/models/spree/return_item.rb +1 -2
  34. data/app/models/spree/stock/allocator/on_hand_first.rb +2 -2
  35. data/app/models/spree/stock/quantifier.rb +12 -8
  36. data/app/models/spree/stock/simple_coordinator.rb +2 -1
  37. data/app/models/spree/tax/item_tax.rb +3 -2
  38. data/app/models/spree/tax/order_tax.rb +3 -1
  39. data/app/models/spree/tax/tax_location.rb +4 -7
  40. data/app/models/spree/tax_rate.rb +2 -0
  41. data/app/models/spree/variant.rb +1 -1
  42. data/app/subscribers/spree/mailer_subscriber.rb +4 -0
  43. data/app/subscribers/spree/order_mailer_subscriber.rb +35 -0
  44. data/config/i18n-tasks.yml +134 -0
  45. data/config/locales/en.yml +391 -257
  46. data/db/migrate/20201127212108_add_type_before_removal_to_spree_payment_methods.rb +7 -0
  47. data/db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb +20 -0
  48. data/lib/generators/solidus/install/install_generator/bundler_context.rb +97 -0
  49. data/lib/generators/solidus/install/install_generator/install_frontend.rb +53 -0
  50. data/lib/generators/solidus/install/install_generator/support_solidus_frontend_extraction.rb +48 -0
  51. data/lib/generators/solidus/install/install_generator.rb +58 -50
  52. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +6 -16
  53. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/backend/all.js +2 -2
  54. data/lib/spree/app_configuration.rb +43 -0
  55. data/lib/spree/bus.rb +20 -0
  56. data/lib/spree/core/controller_helpers/auth.rb +9 -1
  57. data/lib/spree/core/controller_helpers/current_host.rb +1 -3
  58. data/lib/spree/core/controller_helpers/order.rb +10 -10
  59. data/lib/spree/core/controller_helpers/search.rb +1 -1
  60. data/lib/spree/core/engine.rb +39 -8
  61. data/lib/spree/core/state_machines/order.rb +1 -1
  62. data/lib/spree/core/stock_configuration.rb +18 -0
  63. data/lib/spree/core/validators/email.rb +3 -1
  64. data/lib/spree/core/version.rb +2 -2
  65. data/lib/spree/core.rb +20 -0
  66. data/lib/spree/event/subscriber_registry.rb +4 -6
  67. data/lib/spree/event.rb +1 -1
  68. data/lib/spree/migrations.rb +1 -1
  69. data/lib/spree/permission_sets/default_customer.rb +8 -1
  70. data/lib/spree/permitted_attributes.rb +4 -4
  71. data/lib/spree/preferences/configuration.rb +34 -12
  72. data/lib/spree/preferences/preferable_class_methods.rb +1 -1
  73. data/lib/spree/preferences/preference_differentiator.rb +2 -1
  74. data/lib/spree/preferences/static_model_preferences.rb +0 -2
  75. data/lib/spree/rails_compatibility.rb +99 -0
  76. data/lib/spree/testing_support/bus_helpers.rb +101 -0
  77. data/lib/spree/testing_support/common_rake.rb +47 -19
  78. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/backend/all.js +1 -1
  79. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/frontend/all.js +1 -1
  80. data/lib/spree/testing_support/dummy_app.rb +6 -2
  81. data/lib/spree/testing_support/factories/address_factory.rb +7 -2
  82. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
  83. data/lib/spree/testing_support/factories/order_factory.rb +8 -4
  84. data/lib/spree/testing_support/factories/product_factory.rb +4 -1
  85. data/lib/spree/testing_support/factories/store_credit_factory.rb +4 -4
  86. data/lib/spree/testing_support/factories/user_factory.rb +6 -0
  87. data/lib/spree/testing_support/factory_bot.rb +1 -1
  88. data/lib/spree/testing_support/order_walkthrough.rb +5 -4
  89. data/lib/spree/testing_support/silence_deprecations.rb +9 -0
  90. data/lib/tasks/payment_method.rake +29 -0
  91. data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +2 -2
  92. data/lib/tasks/solidus/split_promotions_with_any_match_policy.rake +33 -0
  93. data/solidus_core.gemspec +7 -2
  94. metadata +90 -24
  95. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -10
  96. data/lib/generators/solidus/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -9
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddTypeBeforeRemovalToSpreePaymentMethods < ActiveRecord::Migration[5.2]
4
+ def change
5
+ add_column :spree_payment_methods, :type_before_removal, :string
6
+ end
7
+ end
@@ -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,53 @@
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
+ unless auth_present?(installer_adds_auth)
42
+ BundlerContext.bundle_cleanly { `bundle add solidus_auth_devise` }
43
+ @generator_context.generate('solidus:auth:install --auto-run-migrations')
44
+ end
45
+ `LOCATION="https://raw.githubusercontent.com/solidusio/solidus_starter_frontend/main/template.rb" bin/rails app:template`
46
+ end
47
+
48
+ def auth_present?(installer_adds_auth)
49
+ installer_adds_auth || @bundler_context.component_in_gemfile?(:auth_devise)
50
+ end
51
+ end
52
+ end
53
+ 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