spree_core 4.4.0 → 4.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/finders/spree/option_values/find_available.rb +1 -1
- data/app/finders/spree/product_properties/find_available.rb +1 -1
- data/app/finders/spree/products/find.rb +21 -15
- data/app/finders/spree/taxons/find.rb +11 -8
- data/app/helpers/spree/base_helper.rb +14 -11
- data/app/helpers/spree/locale_helper.rb +6 -2
- data/app/helpers/spree/products_helper.rb +9 -4
- data/app/jobs/spree/variants/remove_from_incomplete_orders_job.rb +9 -0
- data/app/jobs/spree/variants/remove_line_item_job.rb +9 -0
- data/app/models/concerns/spree/calculated_adjustments.rb +1 -1
- data/app/models/concerns/spree/display_link.rb +17 -29
- data/app/models/concerns/spree/image_methods.rb +21 -9
- data/app/models/concerns/spree/metadata.rb +2 -2
- data/app/models/concerns/spree/product_scopes.rb +34 -28
- data/app/models/concerns/spree/translatable_resource.rb +25 -0
- data/app/models/concerns/spree/translatable_resource_scopes.rb +24 -0
- data/app/models/concerns/spree/translatable_resource_slug.rb +17 -0
- data/app/models/spree/address.rb +7 -1
- data/app/models/spree/asset/support/active_storage.rb +3 -2
- data/app/models/spree/asset.rb +3 -0
- data/app/models/spree/base.rb +1 -0
- data/app/models/spree/cms_page.rb +4 -0
- data/app/models/spree/cms_section.rb +12 -12
- data/app/models/spree/cms_section_image.rb +15 -0
- data/app/models/spree/cms_section_image_one.rb +4 -0
- data/app/models/spree/cms_section_image_three.rb +4 -0
- data/app/models/spree/cms_section_image_two.rb +4 -0
- data/app/models/spree/credit_card.rb +10 -4
- data/app/models/spree/customer_return.rb +3 -0
- data/app/models/spree/data_feed/google.rb +15 -0
- data/app/models/spree/data_feed.rb +40 -0
- data/app/models/spree/digital.rb +4 -0
- data/app/models/spree/digital_link.rb +7 -0
- data/app/models/spree/fulfilment_changer.rb +1 -1
- data/app/models/spree/gateway/bogus.rb +1 -1
- data/app/models/spree/icon.rb +5 -1
- data/app/models/spree/image/configuration/active_storage.rb +5 -1
- data/app/models/spree/image.rb +3 -3
- data/app/models/spree/inventory_unit.rb +5 -2
- data/app/models/spree/legacy_user.rb +1 -2
- data/app/models/spree/line_item.rb +4 -1
- data/app/models/spree/linkable/homepage.rb +3 -0
- data/app/models/spree/linkable/uri.rb +3 -0
- data/app/models/spree/log_entry.rb +9 -1
- data/app/models/spree/menu.rb +3 -0
- data/app/models/spree/menu_item.rb +7 -11
- data/app/models/spree/option_type.rb +8 -0
- data/app/models/spree/option_value.rb +9 -0
- data/app/models/spree/order/address_book.rb +1 -0
- data/app/models/spree/order.rb +12 -3
- data/app/models/spree/order_merger.rb +1 -1
- data/app/models/spree/payment/processing.rb +1 -1
- data/app/models/spree/payment.rb +7 -1
- data/app/models/spree/payment_capture_event.rb +4 -0
- data/app/models/spree/payment_method/store_credit.rb +1 -1
- data/app/models/spree/payment_method.rb +3 -0
- data/app/models/spree/payment_source.rb +10 -0
- data/app/models/spree/preference.rb +4 -0
- data/app/models/spree/price.rb +3 -0
- data/app/models/spree/product.rb +97 -24
- data/app/models/spree/product_property.rb +13 -3
- data/app/models/spree/promotion/rules/option_value.rb +2 -2
- data/app/models/spree/promotion.rb +6 -0
- data/app/models/spree/promotion_rule.rb +1 -1
- data/app/models/spree/promotion_rule_user.rb +1 -1
- data/app/models/spree/property.rb +10 -1
- data/app/models/spree/prototype.rb +3 -0
- data/app/models/spree/refund.rb +8 -0
- data/app/models/spree/reimbursement.rb +3 -0
- data/app/models/spree/return_authorization.rb +3 -0
- data/app/models/spree/return_item.rb +4 -0
- data/app/models/spree/role.rb +1 -1
- data/app/models/spree/role_user.rb +1 -1
- data/app/models/spree/shipment.rb +8 -1
- data/app/models/spree/shipping_category.rb +3 -0
- data/app/models/spree/shipping_method.rb +6 -0
- data/app/models/spree/state_change.rb +1 -1
- data/app/models/spree/stock/availability_validator.rb +9 -3
- data/app/models/spree/stock/content_item.rb +1 -1
- data/app/models/spree/stock/quantifier.rb +1 -1
- data/app/models/spree/stock_item.rb +5 -0
- data/app/models/spree/stock_location.rb +19 -5
- data/app/models/spree/stock_movement.rb +4 -0
- data/app/models/spree/stock_transfer.rb +3 -0
- data/app/models/spree/store.rb +39 -15
- data/app/models/spree/store_credit.rb +4 -1
- data/app/models/spree/store_favicon_image.rb +17 -0
- data/app/models/spree/store_logo.rb +9 -0
- data/app/models/spree/store_mailer_logo.rb +13 -0
- data/app/models/spree/tax_category.rb +6 -0
- data/app/models/spree/tax_rate.rb +6 -1
- data/app/models/spree/taxon.rb +26 -7
- data/app/models/spree/taxon_image/configuration/active_storage.rb +5 -1
- data/app/models/spree/taxon_image.rb +3 -2
- data/app/models/spree/taxonomy.rb +8 -1
- data/app/models/spree/variant.rb +47 -21
- data/app/models/spree/wished_item.rb +4 -0
- data/app/models/spree/wishlist.rb +4 -1
- data/app/models/spree/zone.rb +3 -0
- data/app/services/spree/addresses/create.rb +1 -1
- data/app/services/spree/addresses/update.rb +7 -2
- data/app/services/spree/cart/remove_line_item.rb +1 -0
- data/app/services/spree/data_feeds/google/optional_attributes.rb +23 -0
- data/app/services/spree/data_feeds/google/optional_sub_attributes.rb +21 -0
- data/app/services/spree/data_feeds/google/products_list.rb +14 -0
- data/app/services/spree/data_feeds/google/required_attributes.rb +67 -0
- data/app/services/spree/data_feeds/google/rss.rb +107 -0
- data/app/services/spree/variants/remove_line_items.rb +15 -0
- data/app/sorters/spree/products/sort.rb +23 -0
- data/brakeman.ignore +326 -18
- data/config/initializers/friendly_id.rb +2 -0
- data/config/initializers/mobility.rb +18 -0
- data/config/locales/en.yml +6 -2
- data/config/routes.rb +43 -0
- data/db/migrate/20211201202851_update_linkable_resource_types.rb +10 -0
- data/db/migrate/20211203082008_add_settings_to_payment_methods.rb +11 -0
- data/db/migrate/20211229162122_disable_propagate_all_variants_by_default.rb +5 -0
- data/db/migrate/20220103082046_add_status_and_make_active_at_to_spree_products.rb +7 -0
- data/db/migrate/20220106230929_add_internal_note_to_spree_orders.rb +5 -0
- data/db/migrate/20220113052823_create_payment_sources.rb +22 -0
- data/db/migrate/20220117100333_add_make_active_at_to_spree_products.rb +17 -0
- data/db/migrate/20220120092821_add_metadata_to_spree_tax_rates.rb +13 -0
- data/db/migrate/20220201103922_add_first_name_and_last_name_to_spree_users.rb +9 -0
- data/db/migrate/20220222083546_add_barcode_to_spree_variants.rb +6 -0
- data/db/migrate/20220329113557_fix_cms_pages_unique_indexes.rb +8 -0
- data/db/migrate/20220613133029_add_metadata_to_spree_stock_items.rb +13 -0
- data/db/migrate/20220706112554_create_product_name_and_description_translations_for_mobility_table_backend.rb +27 -0
- data/db/migrate/20220715083542_create_spree_product_translations_for_mobility.rb +7 -0
- data/db/migrate/20220715120222_change_product_name_null_to_true.rb +5 -0
- data/db/migrate/20220718100743_create_spree_taxon_name_and_description_translations_for_mobility_table_backend.rb +27 -0
- data/db/migrate/20220718100948_change_taxon_name_null_to_true.rb +5 -0
- data/db/migrate/20220802070609_add_locale_to_friendly_id_slugs.rb +11 -0
- data/db/migrate/20220802073225_create_spree_product_slug_translations_for_mobility_table_backend.rb +5 -0
- data/db/migrate/20220804073928_transfer_data_to_translatable_tables.rb +66 -0
- data/db/migrate/20221215151408_add_selected_locale_to_spree_users.rb +8 -0
- data/db/migrate/20221219123957_add_deleted_at_to_product_translations.rb +6 -0
- data/db/migrate/20221220133432_add_uniqueness_constraint_to_product_translations.rb +5 -0
- data/db/migrate/20221229132350_create_spree_data_feed_settings.rb +14 -0
- data/db/migrate/20230103144439_create_option_type_translations.rb +26 -0
- data/db/migrate/20230103151034_create_option_value_translations.rb +26 -0
- data/db/migrate/20230109084253_create_product_property_translations.rb +25 -0
- data/db/migrate/20230109094907_transfer_options_data_to_translatable_tables.rb +58 -0
- data/db/migrate/20230109105943_create_property_translations.rb +26 -0
- data/db/migrate/20230109110840_transfer_property_data_to_translatable_tables.rb +59 -0
- data/db/migrate/20230110142344_backfill_friendly_id_slug_locale.rb +15 -0
- data/db/migrate/20230111121534_add_additional_taxon_translation_fields.rb +8 -0
- data/db/migrate/20230111122511_transfer_product_and_taxon_data_to_translatable_tables.rb +82 -0
- data/db/migrate/20230117115531_create_taxonomy_translations.rb +24 -0
- data/db/migrate/20230117120430_allow_null_taxonomy_name.rb +5 -0
- data/db/migrate/20230117121303_transfer_taxonomy_data_to_translatable_tables.rb +11 -0
- data/db/migrate/20230210142732_create_store_translations.rb +50 -0
- data/db/migrate/20230210142849_transfer_store_data_to_translatable_tables.rb +11 -0
- data/db/migrate/20230210230434_add_deleted_at_to_store_translations.rb +6 -0
- data/db/migrate/20230415155958_rename_data_feed_settings_table.rb +5 -0
- data/db/migrate/20230415160828_rename_data_feed_table_columns.rb +7 -0
- data/db/migrate/20230415161226_add_indexes_to_data_feeds_table.rb +5 -0
- data/db/migrate/20230512094803_rename_data_feeds_column_provider_to_type.rb +5 -0
- data/db/migrate/20230514162157_add_index_on_locale_and_permalink_to_spree_taxons.rb +5 -0
- data/lib/friendly_id/paranoia.rb +4 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +13 -2
- data/lib/generators/spree/dummy/templates/package.json +12 -0
- data/lib/generators/spree/dummy/templates/rails/test.rb +2 -0
- data/lib/spree/core/configuration.rb +91 -0
- data/lib/spree/core/controller_helpers/auth.rb +3 -1
- data/lib/spree/core/controller_helpers/currency.rb +7 -5
- data/lib/spree/core/controller_helpers/locale.rb +34 -8
- data/lib/spree/core/controller_helpers/order.rb +4 -2
- data/lib/spree/core/controller_helpers/search.rb +1 -1
- data/lib/spree/core/controller_helpers/store.rb +5 -3
- data/lib/spree/core/dependencies.rb +106 -0
- data/lib/spree/core/dependencies_helper.rb +19 -0
- data/lib/spree/core/engine.rb +53 -38
- data/{app/models/spree → lib/spree/core}/preferences/configuration.rb +3 -0
- data/{app/models/spree → lib/spree/core}/preferences/preferable.rb +3 -0
- data/lib/spree/core/product_duplicator.rb +1 -1
- data/lib/spree/core/product_filters.rb +7 -4
- data/lib/spree/core/search/base.rb +10 -6
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +27 -5
- data/lib/spree/permitted_attributes.rb +9 -7
- data/lib/spree/testing_support/common_rake.rb +1 -0
- data/lib/spree/testing_support/factories/favicon_image_factory.rb +9 -0
- data/lib/spree/testing_support/factories/google_data_feed_factory.rb +8 -0
- data/lib/spree/testing_support/factories/icon_factory.rb +3 -1
- data/lib/spree/testing_support/factories/image_factory.rb +3 -1
- data/lib/spree/testing_support/factories/menu_item_factory.rb +1 -1
- data/lib/spree/testing_support/factories/order_factory.rb +2 -1
- data/lib/spree/testing_support/factories/product_factory.rb +12 -1
- data/lib/spree/testing_support/factories/product_property_factory.rb +1 -0
- data/lib/spree/testing_support/factories/product_translation_factory.rb +6 -0
- data/lib/spree/testing_support/factories/refund_factory.rb +1 -1
- data/lib/spree/testing_support/factories/return_authorization_factory.rb +1 -1
- data/lib/spree/testing_support/factories/role_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipping_category_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_location_factory.rb +3 -2
- data/lib/spree/testing_support/factories/store_factory.rb +2 -1
- data/lib/spree/testing_support/factories/taxon_image_factory.rb +3 -1
- data/lib/spree/testing_support/factories/user_factory.rb +4 -0
- data/lib/spree/testing_support/factories/variant_factory.rb +8 -0
- data/lib/spree/translation_migrations.rb +40 -0
- data/lib/spree_core.rb +2 -1
- data/lib/tasks/core.rake +12 -0
- data/spree_core.gemspec +5 -3
- metadata +152 -52
- data/app/models/friendly_id/slug_decorator.rb +0 -9
- data/app/models/spree/app_configuration.rb +0 -86
- data/lib/friendly_id/slug_rails5_patch.rb +0 -11
- data/lib/spree/core/app_dependencies.rb +0 -126
- /data/{app/models/spree → lib/spree/core}/preferences/preferable_class_methods.rb +0 -0
- /data/{app/models/spree → lib/spree/core}/preferences/scoped_store.rb +0 -0
- /data/{app/models/spree → lib/spree/core}/preferences/store.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 619f5416fb099c1cccaeb2432fd6002b53aa605aff90c9b4078f2a51ba73e89b
|
4
|
+
data.tar.gz: e53a5c780f9c4e79c50cc38d2fdd055dc20b04bef93c89e33e88b7a4fd9facce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e8cc84789a7c8564b45576c2aa9f8974f62da3b2c752869a9950497b01382b073b50a4d7746d9f2142bee4248115b58a527637b104f3750504499f2a6608459
|
7
|
+
data.tar.gz: fab84d0b2eb02221f96209f11c118feb77928d69269b009abb4c9a773089f1a011a96bbb3b731abce9cd8af45208eaabdef464c27244b7fd954554de1203c15b
|
@@ -4,8 +4,6 @@ module Spree
|
|
4
4
|
def initialize(scope:, params:, current_currency: nil)
|
5
5
|
@scope = scope
|
6
6
|
|
7
|
-
ActiveSupport::Deprecation.warn('`current_currency` param is deprecated and will be removed in Spree 5') if current_currency
|
8
|
-
|
9
7
|
if current_currency.present?
|
10
8
|
ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
|
11
9
|
`current_currency` param is deprecated and will be removed in Spree 5.
|
@@ -148,7 +146,10 @@ module Spree
|
|
148
146
|
def by_name(products)
|
149
147
|
return products unless name?
|
150
148
|
|
151
|
-
|
149
|
+
product_name = name
|
150
|
+
|
151
|
+
# i18n mobility scope doesn't automatically get set for query blocks (Mobility issue #599) - set it explicitly
|
152
|
+
products.i18n { name.matches("%#{product_name}%") }
|
152
153
|
end
|
153
154
|
|
154
155
|
def by_options(products)
|
@@ -185,7 +186,7 @@ module Spree
|
|
185
186
|
|
186
187
|
next if values.empty?
|
187
188
|
|
188
|
-
ids =
|
189
|
+
ids = scope.unscope(:order, :includes).with_property_values(property_filter_param, values).ids
|
189
190
|
product_ids = index == 0 ? ids : product_ids & ids
|
190
191
|
index += 1
|
191
192
|
end
|
@@ -211,21 +212,19 @@ module Spree
|
|
211
212
|
products
|
212
213
|
end
|
213
214
|
when 'name-a-z'
|
214
|
-
|
215
|
+
# workaround for Mobility issue #596 - explicitly select fields to avoid error when selecting distinct
|
216
|
+
products.i18n.
|
217
|
+
select("#{Product.table_name}.*").select(:name).order(name: :asc)
|
215
218
|
when 'name-z-a'
|
216
|
-
|
219
|
+
# workaround for Mobility issue #596
|
220
|
+
products.i18n.
|
221
|
+
select("#{Product.table_name}.*").select(:name).order(name: :desc)
|
217
222
|
when 'newest-first'
|
218
223
|
products.order(available_on: :desc)
|
219
224
|
when 'price-high-to-low'
|
220
|
-
products
|
221
|
-
select("#{Product.table_name}.*, #{Spree::Price.table_name}.amount").
|
222
|
-
reorder('').
|
223
|
-
send(:descend_by_master_price)
|
225
|
+
order_by_price(products, :descend_by_master_price)
|
224
226
|
when 'price-low-to-high'
|
225
|
-
products
|
226
|
-
select("#{Product.table_name}.*, #{Spree::Price.table_name}.amount").
|
227
|
-
reorder('').
|
228
|
-
send(:ascend_by_master_price)
|
227
|
+
order_by_price(products, :ascend_by_master_price)
|
229
228
|
end
|
230
229
|
end
|
231
230
|
|
@@ -257,7 +256,7 @@ module Spree
|
|
257
256
|
|
258
257
|
def map_prices(prices)
|
259
258
|
prices.map do |price|
|
260
|
-
price == 'Infinity' ?
|
259
|
+
price == 'Infinity' ? BigDecimal::INFINITY : price.to_f
|
261
260
|
end
|
262
261
|
end
|
263
262
|
|
@@ -267,6 +266,13 @@ module Spree
|
|
267
266
|
taxons = store.taxons.where(id: taxons_ids.to_s.split(','))
|
268
267
|
taxons.map(&:cached_self_and_descendants_ids).flatten.compact.uniq.map(&:to_s)
|
269
268
|
end
|
269
|
+
|
270
|
+
def order_by_price(scope, order_type)
|
271
|
+
scope.
|
272
|
+
select("#{Product.table_name}.*, #{Spree::Price.table_name}.amount").
|
273
|
+
reorder('').
|
274
|
+
send(order_type)
|
275
|
+
end
|
270
276
|
end
|
271
277
|
end
|
272
278
|
end
|
@@ -19,7 +19,7 @@ module Spree
|
|
19
19
|
taxons = by_roots(taxons)
|
20
20
|
taxons = by_name(taxons)
|
21
21
|
|
22
|
-
taxons
|
22
|
+
taxons.distinct
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
@@ -50,10 +50,6 @@ module Spree
|
|
50
50
|
name.present?
|
51
51
|
end
|
52
52
|
|
53
|
-
def name_matcher
|
54
|
-
Spree::Taxon.arel_table[:name].matches("%#{name}%")
|
55
|
-
end
|
56
|
-
|
57
53
|
def by_ids(taxons)
|
58
54
|
return taxons unless ids?
|
59
55
|
|
@@ -70,9 +66,13 @@ module Spree
|
|
70
66
|
return taxons unless parent_permalink?
|
71
67
|
|
72
68
|
if Rails::VERSION::STRING >= '6.1'
|
73
|
-
taxons.joins(:parent).
|
69
|
+
taxons.joins(:parent).
|
70
|
+
join_translation_table(Taxon, 'parents_spree_taxons').
|
71
|
+
where(["#{Taxon.translation_table_alias}.permalink = ?", parent_permalink])
|
74
72
|
else
|
75
|
-
taxons.joins("INNER JOIN #{Spree::Taxon.table_name} AS parent_taxon ON parent_taxon.id = #{Spree::Taxon.table_name}.parent_id").
|
73
|
+
taxons.joins("INNER JOIN #{Spree::Taxon.table_name} AS parent_taxon ON parent_taxon.id = #{Spree::Taxon.table_name}.parent_id").
|
74
|
+
join_translation_table(Taxon, 'parent_taxon').
|
75
|
+
where(["#{Taxon.translation_table_alias}.permalink = ?", parent_permalink])
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -91,7 +91,10 @@ module Spree
|
|
91
91
|
def by_name(taxons)
|
92
92
|
return taxons unless name?
|
93
93
|
|
94
|
-
|
94
|
+
taxon_name = name
|
95
|
+
|
96
|
+
# i18n mobility scope doesn't automatically get set for query blocks (Mobility issue #599) - set it explicitly
|
97
|
+
taxons.i18n { name.matches("%#{taxon_name}%") }
|
95
98
|
end
|
96
99
|
end
|
97
100
|
end
|
@@ -61,11 +61,11 @@ module Spree
|
|
61
61
|
DEPRECATION
|
62
62
|
|
63
63
|
image_path ||= if current_store.logo.attached? && current_store.logo.variable?
|
64
|
-
main_app.
|
64
|
+
main_app.cdn_image_url(current_store.logo.variant(resize_to_limit: [244, 104]))
|
65
65
|
elsif current_store.logo.attached? && current_store.logo.image?
|
66
|
-
main_app.
|
66
|
+
main_app.cdn_image_url(current_store.logo)
|
67
67
|
else
|
68
|
-
|
68
|
+
'logo/spree_50.png'
|
69
69
|
end
|
70
70
|
|
71
71
|
path = spree.respond_to?(:root_path) ? spree.root_path : main_app.root_path
|
@@ -76,7 +76,11 @@ module Spree
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def spree_favicon_path
|
79
|
-
|
79
|
+
if current_store.favicon.present?
|
80
|
+
main_app.cdn_image_url(current_store.favicon)
|
81
|
+
else
|
82
|
+
url_for('favicon.ico')
|
83
|
+
end
|
80
84
|
end
|
81
85
|
|
82
86
|
def object
|
@@ -88,7 +92,7 @@ module Spree
|
|
88
92
|
|
89
93
|
if object.is_a? Spree::Product
|
90
94
|
image = default_image_for_product_or_variant(object)
|
91
|
-
og_meta['og:image'] = main_app.
|
95
|
+
og_meta['og:image'] = main_app.cdn_image_url(image.attachment) if image&.attachment
|
92
96
|
|
93
97
|
og_meta['og:url'] = spree.url_for(object) if frontend_available? # url_for product needed
|
94
98
|
og_meta['og:type'] = object.class.name.demodulize.downcase
|
@@ -109,8 +113,8 @@ module Spree
|
|
109
113
|
meta = {}
|
110
114
|
|
111
115
|
if object.is_a? ApplicationRecord
|
112
|
-
meta[:keywords] = object.meta_keywords if object
|
113
|
-
meta[:description] = object.meta_description if object
|
116
|
+
meta[:keywords] = object.meta_keywords if object.try(:meta_keywords).present?
|
117
|
+
meta[:description] = object.meta_description if object.try(:meta_description).present?
|
114
118
|
end
|
115
119
|
|
116
120
|
if meta[:description].blank? && object.is_a?(Spree::Product)
|
@@ -163,8 +167,7 @@ module Spree
|
|
163
167
|
end
|
164
168
|
|
165
169
|
def seo_url(taxon, options = {})
|
166
|
-
options.merge(locale: locale_param)
|
167
|
-
spree.nested_taxons_path(taxon.permalink, options)
|
170
|
+
spree.nested_taxons_path(taxon.permalink, options.merge(locale: locale_param))
|
168
171
|
end
|
169
172
|
|
170
173
|
def frontend_available?
|
@@ -238,7 +241,7 @@ module Spree
|
|
238
241
|
|
239
242
|
def create_product_image_tag(image, product, options, style)
|
240
243
|
options[:alt] = image.alt.blank? ? product.name : image.alt
|
241
|
-
image_tag main_app.
|
244
|
+
image_tag main_app.cdn_image_url(image.url(style)), options
|
242
245
|
end
|
243
246
|
|
244
247
|
def define_image_method(style)
|
@@ -249,7 +252,7 @@ module Spree
|
|
249
252
|
img = if image_path.present?
|
250
253
|
create_product_image_tag image_path, product, options, style
|
251
254
|
else
|
252
|
-
|
255
|
+
inline_svg_tag 'noimage/backend-missing-image.svg', class: 'noimage', size: '60%*60%'
|
253
256
|
end
|
254
257
|
|
255
258
|
content_tag(:div, img, class: "admin-product-image-container #{style}-img")
|
@@ -15,10 +15,14 @@ module Spree
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def locale_presentation(locale)
|
18
|
-
if I18n.exists?('spree.i18n.this_file_language', locale: locale)
|
18
|
+
if I18n.exists?('spree.i18n.this_file_language', locale: locale, fallback: false)
|
19
19
|
[locale_full_name(locale), locale.to_s]
|
20
|
+
elsif defined?(SpreeI18n::Locale) && (language_name = SpreeI18n::Locale.local_language_name(locale))
|
21
|
+
["#{language_name} (#{locale})", locale.to_s]
|
22
|
+
elsif locale.to_s == 'en'
|
23
|
+
['English (US)', 'en']
|
20
24
|
else
|
21
|
-
|
25
|
+
[locale, locale.to_s]
|
22
26
|
end
|
23
27
|
end
|
24
28
|
|
@@ -76,15 +76,20 @@ module Spree
|
|
76
76
|
|
77
77
|
# will return a human readable string
|
78
78
|
def available_status(product)
|
79
|
-
|
79
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
|
80
|
+
`Spree::ProductsHelper#available_status` method from spree/core is deprecated and will be removed.
|
81
|
+
Please use `Spree::Admin::ProductsHelper#available_status` from spree_backend instead.
|
82
|
+
DEPRECATION
|
83
|
+
|
84
|
+
return Spree.t(:archived) if product.discontinued?
|
80
85
|
return Spree.t(:deleted) if product.deleted?
|
81
86
|
|
82
87
|
if product.available?
|
83
|
-
Spree.t(:
|
84
|
-
elsif product.
|
88
|
+
Spree.t(:active)
|
89
|
+
elsif product.make_active_at&.future?
|
85
90
|
Spree.t(:pending_sale)
|
86
91
|
else
|
87
|
-
Spree.t(:
|
92
|
+
Spree.t(:draft)
|
88
93
|
end
|
89
94
|
end
|
90
95
|
|
@@ -18,7 +18,7 @@ module Spree
|
|
18
18
|
|
19
19
|
def calculator_type=(calculator_type)
|
20
20
|
klass = calculator_type.constantize if calculator_type
|
21
|
-
self.calculator = klass.new if klass && !calculator.
|
21
|
+
self.calculator = klass.new if klass && !calculator.instance_of?(klass)
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
@@ -1,42 +1,30 @@
|
|
1
1
|
module Spree
|
2
2
|
module DisplayLink
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
belongs_to :linked_resource, polymorphic: true
|
7
|
+
|
8
|
+
def link
|
9
|
+
case linked_resource_type
|
10
|
+
when 'Spree::Taxon'
|
11
|
+
return if linked_resource&.permalink.blank?
|
7
12
|
|
8
|
-
if spree_routes.method_defined?(:nested_taxons_path)
|
9
|
-
spree_routes.nested_taxons_path(linked_resource.permalink)
|
10
|
-
else
|
11
13
|
"/#{Spree::Config[:storefront_taxons_path]}/#{linked_resource.permalink}"
|
12
|
-
|
13
|
-
|
14
|
-
return if linked_resource&.slug.blank?
|
14
|
+
when 'Spree::Product'
|
15
|
+
return if linked_resource&.slug.blank?
|
15
16
|
|
16
|
-
if spree_routes.method_defined?(:products_path)
|
17
|
-
spree_routes.product_path(linked_resource)
|
18
|
-
else
|
19
17
|
"/#{Spree::Config[:storefront_products_path]}/#{linked_resource.slug}"
|
20
|
-
|
21
|
-
|
22
|
-
return if linked_resource&.slug.blank?
|
18
|
+
when 'Spree::CmsPage'
|
19
|
+
return if linked_resource&.slug.blank?
|
23
20
|
|
24
|
-
if spree_routes.method_defined?(:page_path)
|
25
|
-
spree_routes.page_path(linked_resource.slug)
|
26
|
-
else
|
27
21
|
"/#{Spree::Config[:storefront_pages_path]}/#{linked_resource.slug}"
|
22
|
+
when 'Spree::Linkable::Homepage'
|
23
|
+
'/'
|
24
|
+
when 'Spree::Linkable::Uri'
|
25
|
+
destination
|
28
26
|
end
|
29
|
-
when 'Home Page'
|
30
|
-
'/'
|
31
|
-
when 'URL'
|
32
|
-
destination
|
33
27
|
end
|
34
28
|
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def spree_routes
|
39
|
-
Spree::Core::Engine.routes.url_helpers
|
40
|
-
end
|
41
29
|
end
|
42
30
|
end
|
@@ -2,23 +2,35 @@ module Spree
|
|
2
2
|
module ImageMethods
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
-
def generate_url(size:, gravity: '
|
5
|
+
def generate_url(size:, gravity: 'centre', quality: 80, background: [0, 0, 0])
|
6
6
|
return if size.blank?
|
7
|
+
|
7
8
|
size = size.gsub(/\s+/, '')
|
8
9
|
|
9
10
|
return unless size.match(/(\d+)x(\d+)/)
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
), only_path: true)
|
12
|
+
width, height = size.split('x').map(&:to_i)
|
13
|
+
gravity = translate_gravity_for_mini_magick(gravity)
|
14
|
+
|
15
|
+
# FIXME: bring back support for background color
|
16
|
+
|
17
|
+
cdn_image_url(attachment.variant(resize_and_pad: [width, height, { gravity: gravity }], saver: { quality: quality }))
|
18
18
|
end
|
19
19
|
|
20
20
|
def original_url
|
21
|
-
|
21
|
+
cdn_image_url(attachment)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def translate_gravity_for_mini_magick(gravity)
|
27
|
+
variant_processor = Rails.application.config.active_storage.variant_processor
|
28
|
+
|
29
|
+
if gravity.downcase == 'centre' && [:mini_magick, nil].include?(variant_processor)
|
30
|
+
'center'
|
31
|
+
else
|
32
|
+
gravity
|
33
|
+
end
|
22
34
|
end
|
23
35
|
end
|
24
36
|
end
|
@@ -3,8 +3,8 @@ module Spree
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
attribute :public_metadata, default: {}
|
7
|
-
attribute :private_metadata, default: {}
|
6
|
+
attribute :public_metadata, default: {}
|
7
|
+
attribute :private_metadata, default: {}
|
8
8
|
serialize :public_metadata, HashSerializer
|
9
9
|
serialize :private_metadata, HashSerializer
|
10
10
|
end
|
@@ -32,15 +32,16 @@ module Spree
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def self.property_conditions(property)
|
35
|
-
|
35
|
+
properties_table = Property.table_name
|
36
|
+
property_translations_table = Property.translation_table_alias
|
36
37
|
case property
|
37
|
-
when Property then { "#{
|
38
|
-
when Integer then { "#{
|
38
|
+
when Property then { "#{properties_table}.id" => property.id }
|
39
|
+
when Integer then { "#{properties_table}.id" => property }
|
39
40
|
else
|
40
41
|
if Property.column_for_attribute('id').type == :uuid
|
41
|
-
["#{
|
42
|
+
["#{property_translations_table.name} = ? OR #{properties_table.id} = ?", property, property]
|
42
43
|
else
|
43
|
-
{ "#{
|
44
|
+
{ "#{property_translations_table}.name" => property }
|
44
45
|
end
|
45
46
|
end
|
46
47
|
end
|
@@ -126,21 +127,25 @@ module Spree
|
|
126
127
|
|
127
128
|
# a scope that finds all products having property specified by name, object or id
|
128
129
|
add_search_scope :with_property do |property|
|
129
|
-
joins(:properties).where(property_conditions(property))
|
130
|
+
joins(:properties).join_translation_table(Property).where(property_conditions(property))
|
130
131
|
end
|
131
132
|
|
132
133
|
# a simple test for product with a certain property-value pairing
|
133
134
|
# note that it can test for properties with NULL values, but not for absent values
|
134
135
|
add_search_scope :with_property_value do |property, value|
|
135
136
|
joins(:properties).
|
136
|
-
|
137
|
+
join_translation_table(Property).
|
138
|
+
join_translation_table(ProductProperty).
|
139
|
+
where("#{ProductProperty.translation_table_alias}.value = ?", value).
|
137
140
|
where(property_conditions(property))
|
138
141
|
end
|
139
142
|
|
140
143
|
add_search_scope :with_property_values do |property_filter_param, property_values|
|
141
144
|
joins(product_properties: :property).
|
142
|
-
|
143
|
-
|
145
|
+
join_translation_table(Property).
|
146
|
+
join_translation_table(ProductProperty).
|
147
|
+
where(Property.translation_table_alias => { filter_param: property_filter_param }).
|
148
|
+
where(ProductProperty.translation_table_alias => { filter_param: property_values.map(&:parameterize) })
|
144
149
|
end
|
145
150
|
|
146
151
|
add_search_scope :with_option do |option|
|
@@ -151,7 +156,9 @@ module Spree
|
|
151
156
|
elsif OptionType.column_for_attribute('id').type == :uuid
|
152
157
|
joins(:option_types).where(spree_option_types: { name: option }).or(Product.joins(:option_types).where(spree_option_types: { id: option }))
|
153
158
|
else
|
154
|
-
joins(:option_types).
|
159
|
+
joins(:option_types).
|
160
|
+
join_translation_table(OptionType).
|
161
|
+
where(OptionType.translation_table_alias => { name: option })
|
155
162
|
end
|
156
163
|
end
|
157
164
|
|
@@ -164,6 +171,7 @@ module Spree
|
|
164
171
|
OptionType.where(id: option).or(OptionType.where(name: option))&.first&.id
|
165
172
|
else
|
166
173
|
OptionType.where(name: option)&.first&.id
|
174
|
+
OptionType.where(name: option)&.first&.id
|
167
175
|
end
|
168
176
|
end
|
169
177
|
|
@@ -171,7 +179,9 @@ module Spree
|
|
171
179
|
|
172
180
|
group("#{Spree::Product.table_name}.id").
|
173
181
|
joins(variants_including_master: :option_values).
|
174
|
-
|
182
|
+
join_translation_table(Spree::OptionValue).
|
183
|
+
where(Spree::OptionValue.translation_table_alias => { name: value },
|
184
|
+
Spree::OptionValue.table_name => { option_type_id: option_type_id })
|
175
185
|
end
|
176
186
|
|
177
187
|
# Finds all products which have either:
|
@@ -236,7 +246,7 @@ module Spree
|
|
236
246
|
|
237
247
|
def self.not_discontinued(only_not_discontinued = true)
|
238
248
|
if only_not_discontinued != '0' && only_not_discontinued
|
239
|
-
where(
|
249
|
+
where.not(status: 'archived')
|
240
250
|
else
|
241
251
|
all
|
242
252
|
end
|
@@ -253,9 +263,11 @@ module Spree
|
|
253
263
|
|
254
264
|
# Can't use add_search_scope for this as it needs a default argument
|
255
265
|
def self.available(available_on = nil, currency = nil)
|
256
|
-
available_on
|
257
|
-
|
258
|
-
|
266
|
+
if available_on
|
267
|
+
scope = not_discontinued.where("#{Product.quoted_table_name}.available_on <= ?", available_on)
|
268
|
+
else
|
269
|
+
scope = where(status: 'active')
|
270
|
+
end
|
259
271
|
|
260
272
|
unless Spree::Config.show_products_without_price
|
261
273
|
currency ||= Spree::Store.default.default_currency
|
@@ -282,7 +294,7 @@ module Spree
|
|
282
294
|
if user.try(:has_spree_role?, 'admin')
|
283
295
|
with_deleted
|
284
296
|
else
|
285
|
-
not_deleted.
|
297
|
+
not_deleted.where(status: 'active')
|
286
298
|
end
|
287
299
|
end
|
288
300
|
|
@@ -293,19 +305,10 @@ module Spree
|
|
293
305
|
# .search_by_name
|
294
306
|
if defined?(PgSearch)
|
295
307
|
include PgSearch::Model
|
296
|
-
|
297
|
-
if defined?(SpreeGlobalize)
|
298
|
-
pg_search_scope :search_by_name, associated_against: { translations: :name }, using: :tsearch
|
299
|
-
else
|
300
|
-
pg_search_scope :search_by_name, against: :name, using: :tsearch
|
301
|
-
end
|
308
|
+
pg_search_scope :search_by_name, against: :name, using: { tsearch: { any_word: true, prefix: true } }
|
302
309
|
else
|
303
310
|
def self.search_by_name(query)
|
304
|
-
|
305
|
-
joins(:translations).order(:name).where("LOWER(#{Product::Translation.table_name}.name) LIKE LOWER(:query)", query: "%#{query}%").distinct
|
306
|
-
else
|
307
|
-
where("LOWER(#{Product.table_name}.name) LIKE LOWER(:query)", query: "%#{query}%")
|
308
|
-
end
|
311
|
+
i18n { name.lower.matches("%#{query.downcase}%") }
|
309
312
|
end
|
310
313
|
end
|
311
314
|
search_scopes << :search_by_name
|
@@ -337,7 +340,10 @@ module Spree
|
|
337
340
|
case t
|
338
341
|
when ApplicationRecord then t
|
339
342
|
else
|
340
|
-
Taxon.where(name: t).
|
343
|
+
Taxon.where(name: t).
|
344
|
+
or(Taxon.where(Taxon.arel_table[:id].eq(t))).
|
345
|
+
or(Taxon.where(Taxon.arel_table[:permalink].matches("%/#{t}/"))).
|
346
|
+
or(Taxon.where(Taxon.arel_table[:permalink].matches("#{t}/"))).first
|
341
347
|
end
|
342
348
|
end.compact.flatten.uniq
|
343
349
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Spree
|
2
|
+
module TranslatableResource
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
extend Mobility
|
7
|
+
default_scope { i18n }
|
8
|
+
|
9
|
+
def get_field_with_locale(locale, field_name, fallback: false)
|
10
|
+
# method will return nil if no translation is present due to fallback: false setting
|
11
|
+
public_send(field_name, locale: locale, fallback: fallback)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class_methods do
|
16
|
+
def translatable_fields
|
17
|
+
const_get(:TRANSLATABLE_FIELDS)
|
18
|
+
end
|
19
|
+
|
20
|
+
def translation_table_alias
|
21
|
+
"#{self::Translation.table_name}_#{Mobility.locale}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Spree
|
2
|
+
module TranslatableResourceScopes
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
# To be used when joining on the resource itself does not automatically join on its translations table
|
7
|
+
# This method is to be used when you've already joined on the translatable table itself
|
8
|
+
#
|
9
|
+
# If the resource table is aliased, pass the alias to `join_on_table_alias`, otherwise omit the param
|
10
|
+
def join_translation_table(translatable_class, join_on_table_alias = nil)
|
11
|
+
join_on_table_name = if join_on_table_alias.nil?
|
12
|
+
translatable_class.table_name
|
13
|
+
else
|
14
|
+
join_on_table_alias
|
15
|
+
end
|
16
|
+
translatable_class_foreign_key = "#{translatable_class.table_name.singularize}_id"
|
17
|
+
|
18
|
+
joins("LEFT OUTER JOIN #{translatable_class::Translation.table_name} #{translatable_class.translation_table_alias}
|
19
|
+
ON #{translatable_class.translation_table_alias}.#{translatable_class_foreign_key} = #{join_on_table_name}.id
|
20
|
+
AND #{translatable_class.translation_table_alias}.locale = '#{Mobility.locale}'")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Spree
|
2
|
+
module TranslatableResourceSlug
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
def localized_slugs_for_store(store)
|
7
|
+
localized_slugs = Hash[translations.pluck(:locale, :slug)]
|
8
|
+
default_locale = store.default_locale
|
9
|
+
supported_locales = store.supported_locales_list
|
10
|
+
|
11
|
+
supported_locales.each_with_object({}) do |locale, hash|
|
12
|
+
hash[locale] = localized_slugs[locale] || localized_slugs[default_locale]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|