spree_core 4.5.0 → 4.7.3

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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/app/finders/spree/countries/find.rb +1 -1
  3. data/app/finders/spree/option_values/find_available.rb +1 -1
  4. data/app/finders/spree/product_properties/find_available.rb +1 -1
  5. data/app/finders/spree/products/find.rb +21 -13
  6. data/app/finders/spree/taxons/find.rb +7 -10
  7. data/app/helpers/spree/base_helper.rb +3 -7
  8. data/app/helpers/spree/products_helper.rb +3 -3
  9. data/app/models/concerns/spree/metadata.rb +7 -2
  10. data/app/models/concerns/spree/named_type.rb +1 -1
  11. data/app/models/concerns/spree/product_scopes.rb +27 -23
  12. data/app/models/concerns/spree/translatable_resource.rb +25 -0
  13. data/app/models/concerns/spree/translatable_resource_scopes.rb +24 -0
  14. data/app/models/concerns/spree/translatable_resource_slug.rb +15 -0
  15. data/app/models/concerns/spree/user_roles.rb +3 -3
  16. data/app/models/spree/address.rb +6 -4
  17. data/app/models/spree/asset.rb +1 -1
  18. data/app/models/spree/base.rb +6 -1
  19. data/app/models/spree/calculator/default_tax.rb +1 -1
  20. data/app/models/spree/cms/sections/image_gallery.rb +1 -7
  21. data/app/models/spree/cms/sections/side_by_side_images.rb +1 -7
  22. data/app/models/spree/cms_page.rb +2 -2
  23. data/app/models/spree/cms_section.rb +1 -1
  24. data/app/models/spree/country.rb +2 -2
  25. data/app/models/spree/credit_card.rb +1 -1
  26. data/app/models/spree/customer_return.rb +2 -2
  27. data/app/models/spree/data_feed/google.rb +15 -0
  28. data/app/models/spree/data_feed.rb +40 -0
  29. data/app/models/spree/digital_link.rb +5 -1
  30. data/app/models/spree/image.rb +2 -2
  31. data/app/models/spree/legacy_user.rb +3 -3
  32. data/app/models/spree/line_item.rb +1 -1
  33. data/app/models/spree/log_entry.rb +5 -1
  34. data/app/models/spree/menu.rb +1 -1
  35. data/app/models/spree/option_type.rb +6 -2
  36. data/app/models/spree/option_value.rb +5 -1
  37. data/app/models/spree/order/store_credit.rb +8 -0
  38. data/app/models/spree/order.rb +9 -9
  39. data/app/models/spree/order_contents.rb +31 -0
  40. data/app/models/spree/payment.rb +7 -15
  41. data/app/models/spree/payment_method.rb +1 -1
  42. data/app/models/spree/payment_source.rb +1 -1
  43. data/app/models/spree/preference.rb +5 -1
  44. data/app/models/spree/price.rb +1 -1
  45. data/app/models/spree/product.rb +64 -25
  46. data/app/models/spree/product_property.rb +13 -4
  47. data/app/models/spree/promotion.rb +2 -2
  48. data/app/models/spree/property.rb +8 -2
  49. data/app/models/spree/prototype.rb +1 -1
  50. data/app/models/spree/refund.rb +1 -1
  51. data/app/models/spree/reimbursement.rb +1 -1
  52. data/app/models/spree/return_authorization.rb +1 -1
  53. data/app/models/spree/return_item.rb +5 -1
  54. data/app/models/spree/role.rb +1 -1
  55. data/app/models/spree/shipment.rb +5 -5
  56. data/app/models/spree/shipping_category.rb +1 -1
  57. data/app/models/spree/shipping_method.rb +1 -1
  58. data/app/models/spree/stock/estimator.rb +1 -1
  59. data/app/models/spree/stock/splitter/weight.rb +1 -1
  60. data/app/models/spree/stock_item.rb +1 -1
  61. data/app/models/spree/stock_location.rb +1 -1
  62. data/app/models/spree/stock_transfer.rb +3 -3
  63. data/app/models/spree/store.rb +22 -3
  64. data/app/models/spree/store_credit.rb +2 -2
  65. data/app/models/spree/taxon.rb +47 -7
  66. data/app/models/spree/taxon_image.rb +2 -2
  67. data/app/models/spree/taxonomy.rb +5 -1
  68. data/app/models/spree/variant.rb +6 -9
  69. data/app/models/spree/wishlist.rb +6 -2
  70. data/app/models/spree/zone.rb +2 -2
  71. data/app/services/spree/data_feeds/google/optional_attributes.rb +23 -0
  72. data/app/services/spree/data_feeds/google/optional_sub_attributes.rb +21 -0
  73. data/app/services/spree/data_feeds/google/products_list.rb +14 -0
  74. data/app/services/spree/data_feeds/google/required_attributes.rb +67 -0
  75. data/app/services/spree/data_feeds/google/rss.rb +107 -0
  76. data/app/services/spree/locales/set_fallback_locale_for_store.rb +16 -0
  77. data/app/services/spree/seeds/countries.rb +12 -27
  78. data/app/services/spree/seeds/states.rb +8 -17
  79. data/app/services/spree/stock_locations/stock_items/create.rb +12 -18
  80. data/app/sorters/spree/products/sort.rb +23 -0
  81. data/app/validators/db_maximum_length_validator.rb +2 -6
  82. data/brakeman.ignore +326 -18
  83. data/config/initializers/friendly_id.rb +2 -0
  84. data/config/initializers/mobility.rb +16 -0
  85. data/config/initializers/rails61_fixes.rb +1 -3
  86. data/config/locales/en.yml +7 -0
  87. data/db/migrate/20220706112554_create_product_name_and_description_translations_for_mobility_table_backend.rb +27 -0
  88. data/db/migrate/20220715083542_create_spree_product_translations_for_mobility.rb +7 -0
  89. data/db/migrate/20220715120222_change_product_name_null_to_true.rb +5 -0
  90. data/db/migrate/20220718100743_create_spree_taxon_name_and_description_translations_for_mobility_table_backend.rb +27 -0
  91. data/db/migrate/20220718100948_change_taxon_name_null_to_true.rb +5 -0
  92. data/db/migrate/20220802070609_add_locale_to_friendly_id_slugs.rb +11 -0
  93. data/db/migrate/20220802073225_create_spree_product_slug_translations_for_mobility_table_backend.rb +5 -0
  94. data/db/migrate/20220804073928_transfer_data_to_translatable_tables.rb +66 -0
  95. data/db/migrate/20221215151408_add_selected_locale_to_spree_users.rb +8 -0
  96. data/db/migrate/20221219123957_add_deleted_at_to_product_translations.rb +6 -0
  97. data/db/migrate/20221220133432_add_uniqueness_constraint_to_product_translations.rb +5 -0
  98. data/db/migrate/20221229132350_create_spree_data_feed_settings.rb +14 -0
  99. data/db/migrate/20230103144439_create_option_type_translations.rb +26 -0
  100. data/db/migrate/20230103151034_create_option_value_translations.rb +26 -0
  101. data/db/migrate/20230109084253_create_product_property_translations.rb +25 -0
  102. data/db/migrate/20230109094907_transfer_options_data_to_translatable_tables.rb +58 -0
  103. data/db/migrate/20230109105943_create_property_translations.rb +26 -0
  104. data/db/migrate/20230109110840_transfer_property_data_to_translatable_tables.rb +59 -0
  105. data/db/migrate/20230110142344_backfill_friendly_id_slug_locale.rb +15 -0
  106. data/db/migrate/20230111121534_add_additional_taxon_translation_fields.rb +8 -0
  107. data/db/migrate/20230111122511_transfer_product_and_taxon_data_to_translatable_tables.rb +82 -0
  108. data/db/migrate/20230117115531_create_taxonomy_translations.rb +24 -0
  109. data/db/migrate/20230117120430_allow_null_taxonomy_name.rb +5 -0
  110. data/db/migrate/20230117121303_transfer_taxonomy_data_to_translatable_tables.rb +11 -0
  111. data/db/migrate/20230210142732_create_store_translations.rb +50 -0
  112. data/db/migrate/20230210142849_transfer_store_data_to_translatable_tables.rb +11 -0
  113. data/db/migrate/20230210230434_add_deleted_at_to_store_translations.rb +6 -0
  114. data/db/migrate/20230415155958_rename_data_feed_settings_table.rb +5 -0
  115. data/db/migrate/20230415160828_rename_data_feed_table_columns.rb +7 -0
  116. data/db/migrate/20230415161226_add_indexes_to_data_feeds_table.rb +5 -0
  117. data/db/migrate/20230512094803_rename_data_feeds_column_provider_to_type.rb +5 -0
  118. data/db/migrate/20230514162157_add_index_on_locale_and_permalink_to_spree_taxons.rb +5 -0
  119. data/lib/mobility/plugins/store_based_fallbacks.rb +55 -0
  120. data/lib/spree/core/configuration.rb +2 -1
  121. data/lib/spree/core/controller_helpers/auth.rb +1 -1
  122. data/lib/spree/core/controller_helpers/common.rb +5 -5
  123. data/lib/spree/core/controller_helpers/locale.rb +33 -2
  124. data/lib/spree/core/dependencies.rb +70 -94
  125. data/lib/spree/core/dependencies_helper.rb +19 -0
  126. data/lib/spree/core/engine.rb +7 -1
  127. data/lib/spree/core/preferences/preferable_class_methods.rb +1 -1
  128. data/lib/spree/core/product_duplicator.rb +4 -1
  129. data/lib/spree/core/product_filters.rb +7 -4
  130. data/lib/spree/core/search/base.rb +1 -1
  131. data/lib/spree/core/version.rb +1 -1
  132. data/lib/spree/core.rb +2 -0
  133. data/lib/spree/permitted_attributes.rb +1 -1
  134. data/lib/spree/testing_support/controller_requests.rb +10 -10
  135. data/lib/spree/testing_support/factories/google_data_feed_factory.rb +8 -0
  136. data/lib/spree/testing_support/factories/product_factory.rb +6 -0
  137. data/lib/spree/testing_support/factories/product_translation_factory.rb +6 -0
  138. data/lib/spree/testing_support/factories/store_factory.rb +3 -0
  139. data/lib/spree/testing_support/factories/variant_factory.rb +4 -0
  140. data/lib/spree/translation_migrations.rb +40 -0
  141. data/lib/spree_core.rb +1 -0
  142. data/spree_core.gemspec +6 -3
  143. metadata +147 -14
@@ -6,6 +6,7 @@ module Spree
6
6
 
7
7
  included do
8
8
  before_action :set_locale
9
+ before_action :set_fallback_locale
9
10
 
10
11
  if defined?(helper_method)
11
12
  helper_method :supported_locales
@@ -21,16 +22,36 @@ module Spree
21
22
  I18n.locale = current_locale
22
23
  end
23
24
 
25
+ def set_fallback_locale
26
+ return unless respond_to?(:current_store) && current_store.present?
27
+
28
+ Spree::Locales::SetFallbackLocaleForStore.new.call(store: current_store)
29
+ end
30
+
24
31
  def current_locale
25
- @current_locale ||= if params[:locale].present? && supported_locale?(params[:locale])
32
+ @current_locale ||= if user_locale?
33
+ try_spree_current_user.selected_locale
34
+ elsif params_locale?
26
35
  params[:locale]
27
- elsif respond_to?(:config_locale, true) && config_locale.present?
36
+ elsif config_locale?
28
37
  config_locale
29
38
  else
30
39
  current_store&.default_locale || Rails.application.config.i18n.default_locale || I18n.default_locale
31
40
  end
32
41
  end
33
42
 
43
+ def config_locale?
44
+ respond_to?(:config_locale, true) && config_locale.present?
45
+ end
46
+
47
+ def params_locale?
48
+ params[:locale].present? && supported_locale?(params[:locale])
49
+ end
50
+
51
+ def user_locale?
52
+ Spree::Config.use_user_locale && try_spree_current_user && supported_locale?(try_spree_current_user.selected_locale)
53
+ end
54
+
34
55
  def supported_locales
35
56
  @supported_locales ||= current_store&.supported_locales_list
36
57
  end
@@ -54,6 +75,16 @@ module Spree
54
75
 
55
76
  I18n.locale.to_s
56
77
  end
78
+
79
+ def find_with_fallback_default_locale(&block)
80
+ result = begin
81
+ block.call
82
+ rescue ActiveRecord::RecordNotFound => _e
83
+ nil
84
+ end
85
+
86
+ result || Mobility.with_locale(current_store.default_locale) { block.call }
87
+ end
57
88
  end
58
89
  end
59
90
  end
@@ -3,128 +3,104 @@ require_relative 'dependencies_helper'
3
3
  module Spree
4
4
  module Core
5
5
  class Dependencies
6
- include Spree::DependenciesHelper
6
+ INJECTION_POINTS_WITH_DEFAULTS = {
7
+ # ability
8
+ ability_class: 'Spree::Ability',
7
9
 
8
- INJECTION_POINTS = [
9
- :ability_class,
10
- :cart_create_service, :cart_add_item_service, :cart_remove_item_service,
11
- :cart_remove_line_item_service, :cart_set_item_quantity_service, :cart_recalculate_service,
12
- :cms_page_finder, :cart_update_service, :checkout_next_service, :checkout_advance_service, :checkout_update_service,
13
- :checkout_complete_service, :checkout_add_store_credit_service, :checkout_remove_store_credit_service, :checkout_get_shipping_rates_service,
14
- :coupon_handler, :menu_finder, :country_finder, :current_order_finder, :credit_card_finder,
15
- :completed_order_finder, :order_sorter, :cart_compare_line_items_service, :collection_paginator, :products_sorter,
16
- :products_finder, :taxon_finder, :line_item_by_variant_finder, :cart_estimate_shipping_rates_service,
17
- :account_create_address_service, :account_update_address_service, :account_create_service, :account_update_service,
18
- :address_finder, :collection_sorter, :error_handler, :current_store_finder, :cart_empty_service, :cart_destroy_service,
19
- :classification_reposition_service, :credit_cards_destroy_service, :cart_associate_service, :cart_change_currency_service,
20
- :line_item_create_service, :line_item_update_service, :line_item_destroy_service,
21
- :order_approve_service, :order_cancel_service, :shipment_change_state_service, :shipment_update_service,
22
- :shipment_create_service, :shipment_add_item_service, :shipment_remove_item_service,
23
- :payment_create_service, :address_create_service, :address_update_service,
24
- :checkout_select_shipping_method_service
25
- ].freeze
26
-
27
- attr_accessor *INJECTION_POINTS
28
-
29
- def initialize
30
- set_default_ability
31
- set_default_services
32
- set_default_finders
33
- end
34
-
35
- private
36
-
37
- def set_default_ability
38
- @ability_class = 'Spree::Ability'
39
- end
40
-
41
- def set_default_services
42
10
  # cart
43
- @cart_compare_line_items_service = 'Spree::CompareLineItems'
44
- @cart_create_service = 'Spree::Cart::Create'
45
- @cart_add_item_service = 'Spree::Cart::AddItem'
46
- @cart_update_service = 'Spree::Cart::Update'
47
- @cart_recalculate_service = 'Spree::Cart::Recalculate'
48
- @cart_remove_item_service = 'Spree::Cart::RemoveItem'
49
- @cart_remove_line_item_service = 'Spree::Cart::RemoveLineItem'
50
- @cart_set_item_quantity_service = 'Spree::Cart::SetQuantity'
51
- @cart_estimate_shipping_rates_service = 'Spree::Cart::EstimateShippingRates'
52
- @cart_empty_service = 'Spree::Cart::Empty'
53
- @cart_destroy_service = 'Spree::Cart::Destroy'
54
- @cart_associate_service = 'Spree::Cart::Associate'
55
- @cart_change_currency_service = 'Spree::Cart::ChangeCurrency'
11
+ cart_compare_line_items_service: 'Spree::CompareLineItems',
12
+ cart_create_service: 'Spree::Cart::Create',
13
+ cart_add_item_service: 'Spree::Cart::AddItem',
14
+ cart_update_service: 'Spree::Cart::Update',
15
+ cart_recalculate_service: 'Spree::Cart::Recalculate',
16
+ cart_remove_item_service: 'Spree::Cart::RemoveItem',
17
+ cart_remove_line_item_service: 'Spree::Cart::RemoveLineItem',
18
+ cart_set_item_quantity_service: 'Spree::Cart::SetQuantity',
19
+ cart_estimate_shipping_rates_service: 'Spree::Cart::EstimateShippingRates',
20
+ cart_empty_service: 'Spree::Cart::Empty',
21
+ cart_destroy_service: 'Spree::Cart::Destroy',
22
+ cart_associate_service: 'Spree::Cart::Associate',
23
+ cart_change_currency_service: 'Spree::Cart::ChangeCurrency',
56
24
 
57
25
  # checkout
58
- @checkout_next_service = 'Spree::Checkout::Next'
59
- @checkout_advance_service = 'Spree::Checkout::Advance'
60
- @checkout_update_service = 'Spree::Checkout::Update'
61
- @checkout_complete_service = 'Spree::Checkout::Complete'
62
- @checkout_add_store_credit_service = 'Spree::Checkout::AddStoreCredit'
63
- @checkout_remove_store_credit_service = 'Spree::Checkout::RemoveStoreCredit'
64
- @checkout_get_shipping_rates_service = 'Spree::Checkout::GetShippingRates'
65
- @checkout_select_shipping_method_service = 'Spree::Checkout::SelectShippingMethod'
26
+ checkout_next_service: 'Spree::Checkout::Next',
27
+ checkout_advance_service: 'Spree::Checkout::Advance',
28
+ checkout_update_service: 'Spree::Checkout::Update',
29
+ checkout_complete_service: 'Spree::Checkout::Complete',
30
+ checkout_add_store_credit_service: 'Spree::Checkout::AddStoreCredit',
31
+ checkout_remove_store_credit_service: 'Spree::Checkout::RemoveStoreCredit',
32
+ checkout_get_shipping_rates_service: 'Spree::Checkout::GetShippingRates',
33
+ checkout_select_shipping_method_service: 'Spree::Checkout::SelectShippingMethod',
66
34
 
67
35
  # order
68
- @order_approve_service = 'Spree::Orders::Approve'
69
- @order_cancel_service = 'Spree::Orders::Cancel'
36
+ order_approve_service: 'Spree::Orders::Approve',
37
+ order_cancel_service: 'Spree::Orders::Cancel',
70
38
 
71
39
  # shipment
72
- @shipment_change_state_service = 'Spree::Shipments::ChangeState'
73
- @shipment_create_service = 'Spree::Shipments::Create'
74
- @shipment_update_service = 'Spree::Shipments::Update'
75
- @shipment_add_item_service = 'Spree::Shipments::AddItem'
76
- @shipment_remove_item_service = 'Spree::Shipments::RemoveItem'
40
+ shipment_change_state_service: 'Spree::Shipments::ChangeState',
41
+ shipment_create_service: 'Spree::Shipments::Create',
42
+ shipment_update_service: 'Spree::Shipments::Update',
43
+ shipment_add_item_service: 'Spree::Shipments::AddItem',
44
+ shipment_remove_item_service: 'Spree::Shipments::RemoveItem',
77
45
 
78
46
  # sorter
79
- @collection_sorter = 'Spree::BaseSorter'
80
- @order_sorter = 'Spree::BaseSorter'
81
- @products_sorter = 'Spree::Products::Sort'
47
+ collection_sorter: 'Spree::BaseSorter',
48
+ order_sorter: 'Spree::BaseSorter',
49
+ products_sorter: 'Spree::Products::Sort',
82
50
 
83
51
  # paginator
84
- @collection_paginator = 'Spree::Shared::Paginate'
52
+ collection_paginator: 'Spree::Shared::Paginate',
85
53
 
86
54
  # coupons
87
55
  # TODO: we should split this service into 2 separate - Add and Remove
88
- @coupon_handler = 'Spree::PromotionHandler::Coupon'
56
+ coupon_handler: 'Spree::PromotionHandler::Coupon',
89
57
 
90
58
  # account
91
- @account_create_service = 'Spree::Account::Create'
92
- @account_update_service = 'Spree::Account::Update'
59
+ account_create_service: 'Spree::Account::Create',
60
+ account_update_service: 'Spree::Account::Update',
93
61
 
94
62
  # addresses
95
- @address_create_service = 'Spree::Addresses::Create'
96
- @address_update_service = 'Spree::Addresses::Update'
63
+ address_create_service: 'Spree::Addresses::Create',
64
+ address_update_service: 'Spree::Addresses::Update',
97
65
 
98
66
  # credit cards
99
- @credit_cards_destroy_service = 'Spree::CreditCards::Destroy'
67
+ credit_cards_destroy_service: 'Spree::CreditCards::Destroy',
100
68
 
101
69
  # classifications
102
- @classification_reposition_service = 'Spree::Classifications::Reposition'
70
+ classification_reposition_service: 'Spree::Classifications::Reposition',
103
71
 
104
72
  # line items
105
- @line_item_create_service = 'Spree::LineItems::Create'
106
- @line_item_update_service = 'Spree::LineItems::Update'
107
- @line_item_destroy_service = 'Spree::LineItems::Destroy'
73
+ line_item_create_service: 'Spree::LineItems::Create',
74
+ line_item_update_service: 'Spree::LineItems::Update',
75
+ line_item_destroy_service: 'Spree::LineItems::Destroy',
108
76
 
109
- @payment_create_service = 'Spree::Payments::Create'
77
+ payment_create_service: 'Spree::Payments::Create',
110
78
 
111
79
  # errors
112
- @error_handler = 'Spree::ErrorReporter'
113
- end
114
-
115
- def set_default_finders
116
- @address_finder = 'Spree::Addresses::Find'
117
- @country_finder = 'Spree::Countries::Find'
118
- @cms_page_finder = 'Spree::CmsPages::Find'
119
- @menu_finder = 'Spree::Menus::Find'
120
- @current_order_finder = 'Spree::Orders::FindCurrent'
121
- @current_store_finder = 'Spree::Stores::FindCurrent'
122
- @completed_order_finder = 'Spree::Orders::FindComplete'
123
- @credit_card_finder = 'Spree::CreditCards::Find'
124
- @products_finder = 'Spree::Products::Find'
125
- @taxon_finder = 'Spree::Taxons::Find'
126
- @line_item_by_variant_finder = 'Spree::LineItems::FindByVariant'
127
- end
80
+ error_handler: 'Spree::ErrorReporter',
81
+
82
+ # data feeds
83
+ data_feeds_google_rss_service: 'Spree::DataFeeds::Google::Rss',
84
+ data_feeds_google_optional_attributes_service: 'Spree::DataFeeds::Google::OptionalAttributes',
85
+ data_feeds_google_required_attributes_service: 'Spree::DataFeeds::Google::RequiredAttributes',
86
+ data_feeds_google_optional_sub_attributes_service: 'Spree::DataFeeds::Google::OptionalSubAttributes',
87
+ data_feeds_google_products_list: 'Spree::DataFeeds::Google::ProductsList',
88
+
89
+ # finders
90
+ address_finder: 'Spree::Addresses::Find',
91
+ country_finder: 'Spree::Countries::Find',
92
+ cms_page_finder: 'Spree::CmsPages::Find',
93
+ menu_finder: 'Spree::Menus::Find',
94
+ current_order_finder: 'Spree::Orders::FindCurrent',
95
+ current_store_finder: 'Spree::Stores::FindCurrent',
96
+ completed_order_finder: 'Spree::Orders::FindComplete',
97
+ credit_card_finder: 'Spree::CreditCards::Find',
98
+ products_finder: 'Spree::Products::Find',
99
+ taxon_finder: 'Spree::Taxons::Find',
100
+ line_item_by_variant_finder: 'Spree::LineItems::FindByVariant'
101
+ }.freeze
102
+
103
+ include Spree::DependenciesHelper
128
104
  end
129
105
  end
130
106
  end
@@ -1,5 +1,15 @@
1
1
  module Spree
2
2
  module DependenciesHelper
3
+ def self.included(base)
4
+ injection_points = base::INJECTION_POINTS_WITH_DEFAULTS.keys.freeze
5
+ base.const_set(:INJECTION_POINTS, injection_points)
6
+ base.attr_accessor(*injection_points)
7
+ end
8
+
9
+ def initialize
10
+ set_default_values
11
+ end
12
+
3
13
  def current_values
4
14
  values = []
5
15
  self.class::INJECTION_POINTS.each do |injection_point|
@@ -7,5 +17,14 @@ module Spree
7
17
  end
8
18
  values
9
19
  end
20
+
21
+ private
22
+
23
+ def set_default_values
24
+ self.class::INJECTION_POINTS_WITH_DEFAULTS.each do |injection_point, default_value|
25
+ value = default_value.respond_to?(:call) ? default_value.call : default_value
26
+ instance_variable_set("@#{injection_point}", value)
27
+ end
28
+ end
10
29
  end
11
30
  end
@@ -11,7 +11,8 @@ module Spree
11
11
  :adjusters,
12
12
  :stock_splitters,
13
13
  :promotions,
14
- :line_item_comparison_hooks)
14
+ :line_item_comparison_hooks,
15
+ :data_feed_types)
15
16
  SpreeCalculators = Struct.new(:shipping_methods, :tax_rates, :promotion_actions_create_adjustments, :promotion_actions_create_item_adjustments)
16
17
  PromoEnvironment = Struct.new(:rules, :actions)
17
18
  isolate_namespace Spree
@@ -26,6 +27,7 @@ module Spree
26
27
  app.config.active_record.yaml_column_permitted_classes = [Symbol, BigDecimal]
27
28
  Spree::Config = app.config.spree.preferences
28
29
  Spree::Dependencies = app.config.spree.dependencies
30
+ Spree::Deprecation = ActiveSupport::Deprecation.new
29
31
  end
30
32
 
31
33
  initializer 'spree.register.calculators', before: :after_initialize do |app|
@@ -122,6 +124,10 @@ module Spree
122
124
  Promotion::Actions::CreateLineItems,
123
125
  Promotion::Actions::FreeShipping
124
126
  ]
127
+
128
+ Rails.application.config.spree.data_feed_types = [
129
+ Spree::DataFeed::Google
130
+ ]
125
131
  end
126
132
 
127
133
  initializer 'spree.promo.register.promotions.actions' do |app|
@@ -19,7 +19,7 @@ module Spree::Preferences
19
19
  value = convert_preference_value(value, type)
20
20
  preferences[name] = value
21
21
 
22
- ActiveSupport::Deprecation.warn("`#{name}` is deprecated. #{deprecated}") if deprecated
22
+ Spree::Deprecation.warn("`#{name}` is deprecated. #{deprecated}") if deprecated
23
23
 
24
24
  # If this is an activerecord object, we need to inform
25
25
  # ActiveRecord::Dirty that this value has changed, since this is an
@@ -26,7 +26,10 @@ module Spree
26
26
 
27
27
  def duplicate_product
28
28
  product.dup.tap do |new_product|
29
- new_product.name = "COPY OF #{product.name}"
29
+ new_product.translations.each do |t|
30
+ t.name = "COPY OF #{t.name}"
31
+ t.slug = nil
32
+ end
30
33
  new_product.taxons = product.taxons
31
34
  new_product.stores = product.stores
32
35
  new_product.created_at = nil
@@ -98,18 +98,21 @@ module Spree
98
98
  conds.each do |new_scope|
99
99
  scope = scope.or(new_scope)
100
100
  end
101
- Spree::Product.with_property('brand').where(scope)
101
+ Product.with_property('brand').join_translation_table(ProductProperty).where(scope)
102
102
  end
103
103
 
104
104
  def self.brand_filter
105
105
  brand_property = Spree::Property.find_by(name: 'brand')
106
106
  brands = brand_property ? Spree::ProductProperty.where(property_id: brand_property.id).pluck(:value).uniq.map(&:to_s) : []
107
- pp = Spree::ProductProperty.arel_table
108
- conds = Hash[*brands.map { |b| [b, pp[:value].eq(b)] }.flatten]
107
+
108
+ conditions = brands.map do |brand|
109
+ [brand, { ProductProperty.translation_table_alias => { value: brand } }]
110
+ end.to_h
111
+
109
112
  {
110
113
  name: I18n.t('spree.taxonomy_brands_name'),
111
114
  scope: :brand_any,
112
- conds: conds,
115
+ conds: conditions,
113
116
  labels: brands.sort.map { |k| [k, k] }
114
117
  }
115
118
  end
@@ -83,7 +83,7 @@ module Spree
83
83
  # method should return new scope based on base_scope
84
84
  def get_products_conditions_for(base_scope, query)
85
85
  unless query.blank?
86
- base_scope = base_scope.like_any([:name, :description], [query])
86
+ base_scope = base_scope.i18n { name.matches("%#{query}%").or(description.matches("%#{query}%")) }
87
87
  end
88
88
  base_scope
89
89
  end
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- VERSION = '4.5.0'.freeze
2
+ VERSION = '4.7.3'.freeze
3
3
 
4
4
  def self.version
5
5
  VERSION
data/lib/spree/core.rb CHANGED
@@ -13,6 +13,7 @@ require 'cancan'
13
13
  require 'friendly_id'
14
14
  require 'kaminari'
15
15
  require 'monetize'
16
+ require 'mobility'
16
17
  require 'paranoia'
17
18
  require 'ransack'
18
19
  require 'state_machines-activerecord'
@@ -116,6 +117,7 @@ require 'spree/core/version'
116
117
 
117
118
  require 'spree/core/number_generator'
118
119
  require 'spree/migrations'
120
+ require 'spree/translation_migrations'
119
121
  require 'spree/core/engine'
120
122
 
121
123
  require 'spree/i18n'
@@ -147,7 +147,7 @@ module Spree
147
147
 
148
148
  # TODO: Should probably use something like Spree.user_class.attributes
149
149
  @@user_attributes = [:email, :bill_address_id, :ship_address_id, :password, :first_name, :last_name,
150
- :password_confirmation, { public_metadata: {}, private_metadata: {} }]
150
+ :password_confirmation, { public_metadata: {}, private_metadata: {} }, :selected_locale]
151
151
 
152
152
  @@variant_attributes = [
153
153
  :name, :presentation, :cost_price, :discontinue_on, :lock_version,
@@ -8,7 +8,7 @@ module Spree
8
8
  end
9
9
 
10
10
  def spree_get(action, parameters = nil, session = nil, flash = nil)
11
- ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
11
+ Spree::Deprecation.warn(<<-DEPRECATION, caller)
12
12
  ControllerRequests#spree_get is deprecated and will be removed in Spree 5.0.
13
13
  Please use get, params: {}
14
14
  DEPRECATION
@@ -17,7 +17,7 @@ module Spree
17
17
 
18
18
  # Executes a request simulating POST HTTP method and set/volley the response
19
19
  def spree_post(action, parameters = nil, session = nil, flash = nil)
20
- ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
20
+ Spree::Deprecation.warn(<<-DEPRECATION, caller)
21
21
  ControllerRequests#spree_post is deprecated and will be removed in Spree 5.0.
22
22
  Please use post, params: {}
23
23
  DEPRECATION
@@ -26,7 +26,7 @@ module Spree
26
26
 
27
27
  # Executes a request simulating PUT HTTP method and set/volley the response
28
28
  def spree_put(action, parameters = nil, session = nil, flash = nil)
29
- ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
29
+ Spree::Deprecation.warn(<<-DEPRECATION, caller)
30
30
  ControllerRequests#spree_put is deprecated and will be removed in Spree 5.0.
31
31
  Please use put, params: {}
32
32
  DEPRECATION
@@ -35,7 +35,7 @@ module Spree
35
35
 
36
36
  # # Executes a request simulating PATCH HTTP method and set/volley the response
37
37
  def spree_patch(action, parameters = nil, session = nil, flash = nil)
38
- ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
38
+ Spree::Deprecation.warn(<<-DEPRECATION, caller)
39
39
  ControllerRequests#spree_patch is deprecated and will be removed in Spree 5.0.
40
40
  Please use patch, params: {}
41
41
  DEPRECATION
@@ -44,7 +44,7 @@ module Spree
44
44
 
45
45
  # Executes a request simulating DELETE HTTP method and set/volley the response
46
46
  def spree_delete(action, parameters = nil, session = nil, flash = nil)
47
- ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
47
+ Spree::Deprecation.warn(<<-DEPRECATION, caller)
48
48
  ControllerRequests#spree_delete is deprecated and will be removed in Spree 5.0.
49
49
  Please use delete, params: {}
50
50
  DEPRECATION
@@ -52,35 +52,35 @@ module Spree
52
52
  end
53
53
 
54
54
  def spree_xhr_get(action, parameters = nil, session = nil, flash = nil)
55
- ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
55
+ Spree::Deprecation.warn(<<-DEPRECATION, caller)
56
56
  ControllerRequests#spree_xhr_get is deprecated and will be removed in Spree 5.0.
57
57
  DEPRECATION
58
58
  process_spree_xhr_action(action, parameters, session, flash, :get)
59
59
  end
60
60
 
61
61
  def spree_xhr_post(action, parameters = nil, session = nil, flash = nil)
62
- ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
62
+ Spree::Deprecation.warn(<<-DEPRECATION, caller)
63
63
  ControllerRequests#spree_xhr_post is deprecated and will be removed in Spree 5.0.
64
64
  DEPRECATION
65
65
  process_spree_xhr_action(action, parameters, session, flash, :post)
66
66
  end
67
67
 
68
68
  def spree_xhr_put(action, parameters = nil, session = nil, flash = nil)
69
- ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
69
+ Spree::Deprecation.warn(<<-DEPRECATION, caller)
70
70
  ControllerRequests#spree_xhr_put is deprecated and will be removed in Spree 5.0.
71
71
  DEPRECATION
72
72
  process_spree_xhr_action(action, parameters, session, flash, :put)
73
73
  end
74
74
 
75
75
  def spree_xhr_patch(action, parameters = nil, session = nil, flash = nil)
76
- ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
76
+ Spree::Deprecation.warn(<<-DEPRECATION, caller)
77
77
  ControllerRequests#spree_xhr_patch is deprecated and will be removed in Spree 5.0.
78
78
  DEPRECATION
79
79
  process_spree_xhr_action(action, parameters, session, flash, :patch)
80
80
  end
81
81
 
82
82
  def spree_xhr_delete(action, parameters = nil, session = nil, flash = nil)
83
- ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
83
+ Spree::Deprecation.warn(<<-DEPRECATION, caller)
84
84
  ControllerRequests#spree_xhr_delete is deprecated and will be removed in Spree 5.0.
85
85
  DEPRECATION
86
86
  process_spree_xhr_action(action, parameters, session, flash, :delete)
@@ -0,0 +1,8 @@
1
+ FactoryBot.define do
2
+ factory :google_data_feed, class: Spree::DataFeed::Google do
3
+ id { 1 }
4
+ active { true }
5
+ store { create(:store) }
6
+ name { 'test' }
7
+ end
8
+ end
@@ -52,6 +52,12 @@ FactoryBot.define do
52
52
  factory :product_with_option_types do
53
53
  after(:create) { |product| create(:product_option_type, product: product) }
54
54
  end
55
+ factory :product_with_properties do
56
+ after(:create) do |product|
57
+ create(:property, :brand, id: 10)
58
+ create(:product_property, product: product, property_id: 10, value: 'Epsilon')
59
+ end
60
+ end
55
61
  end
56
62
  end
57
63
  end
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :product_translation, class: Spree::Product::Translation do
3
+ sequence(:name) { |n| "Product #{n}" }
4
+ description { generate(:random_description) }
5
+ end
6
+ end
@@ -12,6 +12,9 @@ FactoryBot.define do
12
12
  facebook { 'spreecommerce' }
13
13
  twitter { 'spreecommerce' }
14
14
  instagram { 'spreecommerce' }
15
+ meta_description { 'Sample store description.' }
16
+ digital_asset_authorized_clicks { 5 }
17
+ digital_asset_authorized_days { 7 }
15
18
 
16
19
  trait :with_favicon do
17
20
  transient do
@@ -25,6 +25,10 @@ FactoryBot.define do
25
25
  factory :variant do
26
26
  # on_hand 5
27
27
  product { |p| p.association(:product, stores: [create(:store)]) }
28
+
29
+ factory :with_image_variant do
30
+ images { create_list(:image, 1) }
31
+ end
28
32
  end
29
33
 
30
34
  factory :master_variant do
@@ -0,0 +1,40 @@
1
+ module Spree
2
+ class TranslationMigrations
3
+ def initialize(resource_class, default_locale)
4
+ @resource_class = resource_class
5
+ @translations_table = resource_class::Translation.table_name
6
+ @translatable_fields = resource_class.translatable_fields.join(', ')
7
+ @foreign_key = "#{resource_class.table_name.singularize}_id"
8
+ @default_locale = default_locale
9
+ end
10
+
11
+ def transfer_translation_data
12
+ nullify_translatable_fields = @resource_class.translatable_fields.map { |f| "#{f}=null" }.join(', ')
13
+
14
+ unless @resource_class::Translation.exists?
15
+ ActiveRecord::Base.connection.execute("
16
+ INSERT INTO #{@translations_table} (#{@translatable_fields}, #{@foreign_key}, locale, created_at, updated_at)
17
+ SELECT #{@translatable_fields}, id, '#{@default_locale}' as locale, created_at, updated_at FROM #{@resource_class.table_name};
18
+ ")
19
+ ActiveRecord::Base.connection.execute("
20
+ UPDATE #{@resource_class.table_name}
21
+ SET #{nullify_translatable_fields};
22
+ ")
23
+ end
24
+ end
25
+
26
+ def revert_translation_data_transfer
27
+ translation_table_fields = @resource_class.translatable_fields.map { |f| "#{@translations_table}.#{f}" }.join(', ')
28
+ row_expression = @resource_class.translatable_fields.count == 1 ? 'ROW' : ''
29
+
30
+ ActiveRecord::Base.connection.execute("
31
+ UPDATE #{@resource_class.table_name}
32
+ SET (#{@translatable_fields}) = #{row_expression}(#{translation_table_fields})
33
+ FROM #{@translations_table}
34
+ WHERE #{@translations_table}.#{@foreign_key} = #{@resource_class.table_name}.id
35
+ ")
36
+
37
+ ActiveRecord::Base.connection.execute("TRUNCATE TABLE #{@translations_table}")
38
+ end
39
+ end
40
+ end
data/lib/spree_core.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  require 'friendly_id/paranoia'
2
+ require 'mobility/plugins/store_based_fallbacks'
2
3
 
3
4
  require 'spree/core'
data/spree_core.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  "source_code_uri" => "https://github.com/spree/spree/tree/v#{s.version}",
21
21
  }
22
22
 
23
- s.required_ruby_version = '>= 2.5.0'
23
+ s.required_ruby_version = '>= 3.0'
24
24
  s.required_rubygems_version = '>= 1.8.23'
25
25
 
26
26
  s.files = `git ls-files`.split("\n").reject { |f| f.match(/^spec/) && !f.match(/^spec\/fixtures/) }
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
30
30
  actionpack actionview activejob activemodel activerecord
31
31
  activestorage activesupport railties
32
32
  ].each do |rails_gem|
33
- s.add_dependency rails_gem, '>= 6.1'
33
+ s.add_dependency rails_gem, '>= 6.1', '< 7.2'
34
34
  end
35
35
 
36
36
  s.add_dependency 'activemerchant', '~> 1.67'
@@ -45,7 +45,7 @@ Gem::Specification.new do |s|
45
45
  s.add_dependency 'money', '~> 6.13'
46
46
  s.add_dependency 'monetize', '~> 1.9'
47
47
  s.add_dependency 'paranoia', '~> 2.4'
48
- s.add_dependency 'ransack', '>= 2.3', '< 3.0'
48
+ s.add_dependency 'ransack', '>= 4.1'
49
49
  s.add_dependency 'rexml'
50
50
  s.add_dependency 'state_machines-activerecord', '~> 0.6'
51
51
  s.add_dependency 'state_machines-activemodel', '~> 0.7'
@@ -54,4 +54,7 @@ Gem::Specification.new do |s|
54
54
  s.add_dependency 'image_processing', '~> 1.2'
55
55
  s.add_dependency 'active_storage_validations', '~> 0.9', '<= 0.9.5'
56
56
  s.add_dependency 'activerecord-typedstore'
57
+ s.add_dependency 'mobility', '~> 1.2.9'
58
+ s.add_dependency 'mobility-ransack', '~> 1.2.1'
59
+ s.add_dependency 'friendly_id-mobility', '~> 1.0.4'
57
60
  end