spree_multi_store 1.0.1 → 1.0.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.
- checksums.yaml +4 -4
- data/app/models/concerns/spree/multi_store_resource.rb +20 -3
- data/app/models/concerns/spree/store/multi_store_class_overrides.rb +1 -8
- data/app/models/concerns/spree/store/multi_store_methods.rb +13 -17
- data/app/models/concerns/spree/store/multi_store_overrides.rb +0 -12
- data/app/models/spree/multi_store/payment_method_decorator.rb +22 -0
- data/app/models/spree/multi_store/product_decorator.rb +13 -0
- data/app/models/spree/multi_store/promotion_decorator.rb +13 -0
- data/app/models/spree/store_product.rb +29 -0
- data/config/initializers/spree_multi_store.rb +5 -4
- data/config/routes.rb +0 -1
- data/lib/spree/multi_store/factories/store_product_factory.rb +6 -0
- data/lib/spree/multi_store/version.rb +1 -1
- data/lib/spree_multi_store/factories.rb +3 -0
- data/lib/spree_multi_store.rb +7 -0
- metadata +20 -13
- data/app/controllers/spree/admin/custom_domains_controller.rb +0 -21
- data/app/finders/spree/stores/find_current.rb +0 -28
- data/app/models/spree/custom_domain.rb +0 -61
- data/app/views/spree/admin/custom_domains/_custom_domain.html.erb +0 -11
- data/app/views/spree/admin/custom_domains/_custom_domains.html.erb +0 -19
- data/app/views/spree/admin/custom_domains/_form.html.erb +0 -7
- data/app/views/spree/admin/custom_domains/edit.html.erb +0 -1
- data/app/views/spree/admin/custom_domains/index.html.erb +0 -65
- data/app/views/spree/admin/custom_domains/new.html.erb +0 -1
- data/config/initializers/spree_multi_store_navigation.rb +0 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c0789427a739da1148da286873bd70d90dfeb6c3889f8f3a5ebae957ae4516ad
|
|
4
|
+
data.tar.gz: fdba3b3bba537a08aea6e755faa9173d70951aa36ecdc395512db05c393ead60
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6bc1d7195cdc16fb34b3dcd4477f6aa3b1237a7d14c0fe7340b65ce52d658883761344b5967284b9e7324fb5d4d88230a89ad25840aba58a6ab1e2e653d8b7d3
|
|
7
|
+
data.tar.gz: dec645a70fd411c7e1ad6f6f9b45340ed5e51afb3f1a3559a720abb0ff71a8bd51dced652099ba6e49ca9eff844786b94e82bb94e78b23b8cf39295a186d9278
|
|
@@ -13,21 +13,38 @@ module Spree
|
|
|
13
13
|
protected
|
|
14
14
|
|
|
15
15
|
def must_have_one_store
|
|
16
|
-
return if
|
|
16
|
+
return if associated_with_store?
|
|
17
17
|
|
|
18
18
|
errors.add(:stores, Spree.t(:must_have_one_store))
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def set_default_store
|
|
22
22
|
return if disable_store_presence_validation?
|
|
23
|
-
return if
|
|
23
|
+
return if associated_with_store?
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
# Build the join by +store_id+ instead of pushing the +Spree::Store.default+
|
|
26
|
+
# instance through the autosaving +has_many :stores, through:+.
|
|
27
|
+
send(store_join_association_name).build(store_id: Spree::Store.default.id)
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
# this can be overridden on model basis
|
|
29
31
|
def disable_store_presence_validation?
|
|
30
32
|
Spree::Config[:disable_store_presence_validation]
|
|
31
33
|
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# records built through a store's association (`store.payment_methods.build`)
|
|
38
|
+
# carry their link on the join association — `stores` can't see it until save
|
|
39
|
+
# (mirrors Spree::StoreScopedResource, spree/spree#14185)
|
|
40
|
+
def associated_with_store?
|
|
41
|
+
stores.any? || send(store_join_association_name).any?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Name of the join association backing +has_many :stores, through:+
|
|
45
|
+
# (e.g. +:store_products+, +:store_payment_methods+, +:store_promotions+).
|
|
46
|
+
def store_join_association_name
|
|
47
|
+
self.class.reflect_on_association(:stores).through_reflection.name
|
|
48
|
+
end
|
|
32
49
|
end
|
|
33
50
|
end
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
module Store::MultiStoreClassOverrides
|
|
3
|
-
|
|
4
|
-
if url.present?
|
|
5
|
-
Spree.current_store_finder.new(url: url).execute
|
|
6
|
-
else
|
|
7
|
-
Spree::Current.store
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
3
|
+
# Aggregate supported locales across every store, not just the current one.
|
|
11
4
|
def available_locales
|
|
12
5
|
Spree::Store.all.map(&:supported_locales_list).flatten.uniq
|
|
13
6
|
end
|
|
@@ -7,8 +7,19 @@ module Spree
|
|
|
7
7
|
)
|
|
8
8
|
|
|
9
9
|
included do
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
# Replace core's singular FK associations (+has_many :products /
|
|
11
|
+
# :promotions / :payment_methods, dependent: :nullify+, backed by each
|
|
12
|
+
# resource's +store_id+ column) with the legacy join-table associations.
|
|
13
|
+
# Re-declaring the same association name overrides the core declaration.
|
|
14
|
+
has_many :store_products, class_name: 'Spree::StoreProduct', dependent: :destroy
|
|
15
|
+
has_many :products, through: :store_products, class_name: 'Spree::Product'
|
|
16
|
+
has_many :variants, through: :products, class_name: 'Spree::Variant', source: :variants_including_master
|
|
17
|
+
|
|
18
|
+
has_many :store_promotions, class_name: 'Spree::StorePromotion', dependent: :destroy
|
|
19
|
+
has_many :promotions, through: :store_promotions, class_name: 'Spree::Promotion'
|
|
20
|
+
|
|
21
|
+
has_many :store_payment_methods, class_name: 'Spree::StorePaymentMethod', dependent: :destroy
|
|
22
|
+
has_many :payment_methods, through: :store_payment_methods, class_name: 'Spree::PaymentMethod'
|
|
12
23
|
|
|
13
24
|
attribute :import_products_from_store_id, :string, default: nil
|
|
14
25
|
attribute :import_payment_methods_from_store_id, :string, default: nil
|
|
@@ -25,27 +36,12 @@ module Spree
|
|
|
25
36
|
before_destroy :validate_not_last, unless: :skip_validate_not_last
|
|
26
37
|
before_destroy :pass_default_flag_to_other_store
|
|
27
38
|
|
|
28
|
-
scope :by_custom_domain, ->(url) { left_joins(:custom_domains).where("#{Spree::CustomDomain.table_name}.url" => url) }
|
|
29
39
|
scope :by_url, ->(url) { where(url: url).or(where("#{table_name}.url like ?", "%#{url}%")) }
|
|
30
40
|
|
|
31
41
|
# Re-configure FriendlyId to use :history for code tracking across renames
|
|
32
42
|
friendly_id :slug_candidates, use: [:slugged, :history], slug_column: :code, routes: :normal
|
|
33
43
|
end
|
|
34
44
|
|
|
35
|
-
def formatted_custom_domain
|
|
36
|
-
return unless default_custom_domain
|
|
37
|
-
|
|
38
|
-
@formatted_custom_domain ||= if Rails.env.development? || Rails.env.test?
|
|
39
|
-
URI::Generic.build(
|
|
40
|
-
scheme: Rails.application.routes.default_url_options[:protocol] || 'http',
|
|
41
|
-
host: default_custom_domain.url,
|
|
42
|
-
port: Rails.application.routes.default_url_options[:port]
|
|
43
|
-
).to_s
|
|
44
|
-
else
|
|
45
|
-
URI::HTTPS.build(host: default_custom_domain.url).to_s
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
45
|
def can_be_deleted?
|
|
50
46
|
self.class.where.not(id: id).any?
|
|
51
47
|
end
|
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
module Store::MultiStoreOverrides
|
|
3
|
-
def url_or_custom_domain
|
|
4
|
-
default_custom_domain&.url || url
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
def formatted_url_or_custom_domain
|
|
8
|
-
formatted_custom_domain || formatted_url
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def storefront_url
|
|
12
|
-
formatted_custom_domain || super
|
|
13
|
-
end
|
|
14
|
-
|
|
15
3
|
def can_be_deleted?
|
|
16
4
|
self.class.where.not(id: id).any?
|
|
17
5
|
end
|
|
@@ -2,8 +2,30 @@ module Spree
|
|
|
2
2
|
module MultiStore
|
|
3
3
|
module PaymentMethodDecorator
|
|
4
4
|
def self.prepended(base)
|
|
5
|
+
# Single-store core sets +belongs_to :store+ on PaymentMethod; this gem
|
|
6
|
+
# layers +has_many :stores+ back on top through the legacy join table.
|
|
7
|
+
# Core no longer declares this association, so it must live here —
|
|
8
|
+
# without it +Spree::MultiStoreResource#set_default_store+ has no
|
|
9
|
+
# +:stores+ reflection to build the join through.
|
|
10
|
+
base.has_many :store_payment_methods, class_name: 'Spree::StorePaymentMethod', inverse_of: :payment_method
|
|
11
|
+
base.has_many :stores, through: :store_payment_methods, class_name: 'Spree::Store'
|
|
12
|
+
|
|
13
|
+
base.scope :for_store, ->(store) { joins(:store_payment_methods).where(StorePaymentMethod.table_name => { store_id: store.id }) }
|
|
14
|
+
|
|
15
|
+
base.whitelisted_ransackable_associations =
|
|
16
|
+
(base.whitelisted_ransackable_associations.to_a + %w[stores store_payment_methods]).uniq
|
|
17
|
+
|
|
5
18
|
base.include Spree::MultiStoreResource
|
|
6
19
|
end
|
|
20
|
+
|
|
21
|
+
# Core checks the singular +store_id+ FK; with multi-store sharing a
|
|
22
|
+
# payment method can belong to several stores, so test membership of the
|
|
23
|
+
# join table instead.
|
|
24
|
+
def available_for_store?(store)
|
|
25
|
+
return true if store.blank?
|
|
26
|
+
|
|
27
|
+
store_ids.include?(store.id)
|
|
28
|
+
end
|
|
7
29
|
end
|
|
8
30
|
end
|
|
9
31
|
|
|
@@ -2,6 +2,19 @@ module Spree
|
|
|
2
2
|
module MultiStore
|
|
3
3
|
module ProductDecorator
|
|
4
4
|
def self.prepended(base)
|
|
5
|
+
# Spree 5.5 core sets +belongs_to :store+ via +Spree::Product::Channels+;
|
|
6
|
+
# this gem layers +has_many :stores+ on top through the legacy join.
|
|
7
|
+
# Keep both: +store+ stays as the "home" store used by core for
|
|
8
|
+
# publication/channel scoping; +stores+ is the multi-store catalog set.
|
|
9
|
+
base.has_many :store_products, class_name: 'Spree::StoreProduct'
|
|
10
|
+
base.has_many :stores, through: :store_products, class_name: 'Spree::Store'
|
|
11
|
+
|
|
12
|
+
base.scope :for_store, ->(store) { joins(:store_products).where(StoreProduct.table_name => { store_id: store.id }) }
|
|
13
|
+
|
|
14
|
+
# Ransack: re-expose +stores+ alongside the core associations.
|
|
15
|
+
base.whitelisted_ransackable_associations =
|
|
16
|
+
(base.whitelisted_ransackable_associations.to_a + %w[stores store_products]).uniq
|
|
17
|
+
|
|
5
18
|
base.include Spree::MultiStoreResource
|
|
6
19
|
end
|
|
7
20
|
end
|
|
@@ -2,6 +2,19 @@ module Spree
|
|
|
2
2
|
module MultiStore
|
|
3
3
|
module PromotionDecorator
|
|
4
4
|
def self.prepended(base)
|
|
5
|
+
# Single-store core sets +belongs_to :store+ on Promotion; this gem
|
|
6
|
+
# layers +has_many :stores+ back on top through the legacy join table.
|
|
7
|
+
# Core no longer declares this association, so it must live here —
|
|
8
|
+
# without it +Spree::MultiStoreResource#set_default_store+ has no
|
|
9
|
+
# +:stores+ reflection to build the join through.
|
|
10
|
+
base.has_many :store_promotions, class_name: 'Spree::StorePromotion'
|
|
11
|
+
base.has_many :stores, through: :store_promotions, class_name: 'Spree::Store'
|
|
12
|
+
|
|
13
|
+
base.scope :for_store, ->(store) { joins(:store_promotions).where(StorePromotion.table_name => { store_id: store.id }) }
|
|
14
|
+
|
|
15
|
+
base.whitelisted_ransackable_associations =
|
|
16
|
+
(base.whitelisted_ransackable_associations.to_a + %w[stores store_promotions]).uniq
|
|
17
|
+
|
|
5
18
|
base.include Spree::MultiStoreResource
|
|
6
19
|
end
|
|
7
20
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
class StoreProduct < Spree.base_class
|
|
3
|
+
has_prefix_id :sp
|
|
4
|
+
|
|
5
|
+
self.table_name = 'spree_products_stores'
|
|
6
|
+
|
|
7
|
+
belongs_to :store, class_name: 'Spree::Store', touch: true
|
|
8
|
+
belongs_to :product, class_name: 'Spree::Product', touch: true
|
|
9
|
+
|
|
10
|
+
validates :store, :product, presence: true
|
|
11
|
+
validates :store_id, uniqueness: { scope: :product_id }
|
|
12
|
+
|
|
13
|
+
def refresh_metrics!
|
|
14
|
+
return if product.nil?
|
|
15
|
+
|
|
16
|
+
completed_order_ids = product.completed_orders.where(store_id: store_id).select(:id)
|
|
17
|
+
variant_ids = product.variants_including_master.ids
|
|
18
|
+
|
|
19
|
+
line_items = Spree::LineItem.joins(:order)
|
|
20
|
+
.where(spree_orders: { id: completed_order_ids })
|
|
21
|
+
.where(variant_id: variant_ids)
|
|
22
|
+
|
|
23
|
+
update!(
|
|
24
|
+
units_sold_count: line_items.sum(:quantity),
|
|
25
|
+
revenue: line_items.sum(:pre_tax_amount)
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
Spree.root_domain = ENV.fetch('SPREE_ROOT_DOMAIN', 'localhost')
|
|
5
5
|
|
|
6
6
|
Rails.application.config.after_initialize do
|
|
7
|
-
Spree::Dependencies.current_store_finder = 'Spree::Stores::FindCurrent'
|
|
8
|
-
|
|
9
|
-
Spree.metafields.enabled_resources << Spree::CustomDomain
|
|
10
|
-
|
|
11
7
|
Spree::PermittedAttributes.store_attributes.push(
|
|
12
8
|
:import_products_from_store_id,
|
|
13
9
|
:import_payment_methods_from_store_id
|
|
14
10
|
)
|
|
15
11
|
|
|
12
|
+
# Re-add +store_ids+ to permitted product attributes — core dropped it when
|
|
13
|
+
# Product went single-store; this gem restores +has_many :stores+ and the
|
|
14
|
+
# legacy +_stores.html.erb+ partial submits a +store_ids[]+ checkbox list.
|
|
15
|
+
Spree::PermittedAttributes.product_attributes.push(store_ids: [])
|
|
16
|
+
|
|
16
17
|
if defined?(Spree::Admin)
|
|
17
18
|
Spree.admin.partials.product_form_sidebar << 'spree/admin/products/form/stores'
|
|
18
19
|
end
|
data/config/routes.rb
CHANGED
data/lib/spree_multi_store.rb
CHANGED
|
@@ -1 +1,8 @@
|
|
|
1
|
+
# Top-level marker constant. Spree core checks +defined?(SpreeMultiStore)+ before
|
|
2
|
+
# including +Spree::Product::LegacyMultiStoreSupport+ — defining it here ensures
|
|
3
|
+
# core skips the deprecation-only fallback so this gem's ProductDecorator can
|
|
4
|
+
# install the real +has_many :stores+ association.
|
|
5
|
+
module SpreeMultiStore
|
|
6
|
+
end
|
|
7
|
+
|
|
1
8
|
require 'spree/multi_store'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spree_multi_store
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vendo Connect Inc.
|
|
@@ -38,6 +38,20 @@ dependencies:
|
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: 5.4.0.beta
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: spree_custom_domains
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
56
|
name: spree_dev_tools
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -62,46 +76,39 @@ files:
|
|
|
62
76
|
- LICENSE.md
|
|
63
77
|
- README.md
|
|
64
78
|
- Rakefile
|
|
65
|
-
- app/controllers/spree/admin/custom_domains_controller.rb
|
|
66
79
|
- app/controllers/spree/admin/multi_store/base_controller_decorator.rb
|
|
67
80
|
- app/controllers/spree/admin/multi_store/stores_controller.rb
|
|
68
|
-
- app/finders/spree/stores/find_current.rb
|
|
69
81
|
- app/helpers/spree/admin/multi_store_helper.rb
|
|
70
82
|
- app/models/concerns/spree/multi_store_resource.rb
|
|
71
83
|
- app/models/concerns/spree/store/multi_store_class_overrides.rb
|
|
72
84
|
- app/models/concerns/spree/store/multi_store_methods.rb
|
|
73
85
|
- app/models/concerns/spree/store/multi_store_overrides.rb
|
|
74
|
-
- app/models/spree/custom_domain.rb
|
|
75
86
|
- app/models/spree/multi_store/payment_method_decorator.rb
|
|
76
87
|
- app/models/spree/multi_store/product_decorator.rb
|
|
77
88
|
- app/models/spree/multi_store/promotion_decorator.rb
|
|
78
89
|
- app/models/spree/multi_store/store_decorator.rb
|
|
79
|
-
- app/
|
|
80
|
-
- app/views/spree/admin/custom_domains/_custom_domains.html.erb
|
|
81
|
-
- app/views/spree/admin/custom_domains/_form.html.erb
|
|
82
|
-
- app/views/spree/admin/custom_domains/edit.html.erb
|
|
83
|
-
- app/views/spree/admin/custom_domains/index.html.erb
|
|
84
|
-
- app/views/spree/admin/custom_domains/new.html.erb
|
|
90
|
+
- app/models/spree/store_product.rb
|
|
85
91
|
- app/views/spree/admin/multi_store/stores/new.html.erb
|
|
86
92
|
- app/views/spree/admin/multi_store/stores/new.turbo_stream.erb
|
|
87
93
|
- app/views/spree/admin/products/form/_stores.html.erb
|
|
88
94
|
- app/views/spree/admin/shared/sidebar/_store_dropdown.html.erb
|
|
89
95
|
- config/initializers/spree_multi_store.rb
|
|
90
|
-
- config/initializers/spree_multi_store_navigation.rb
|
|
91
96
|
- config/locales/en.yml
|
|
92
97
|
- config/routes.rb
|
|
93
98
|
- lib/spree/multi_store.rb
|
|
94
99
|
- lib/spree/multi_store/engine.rb
|
|
100
|
+
- lib/spree/multi_store/factories/store_product_factory.rb
|
|
95
101
|
- lib/spree/multi_store/version.rb
|
|
96
102
|
- lib/spree_multi_store.rb
|
|
103
|
+
- lib/spree_multi_store/factories.rb
|
|
97
104
|
homepage: https://github.com/spree/spree_multi_store
|
|
98
105
|
licenses:
|
|
99
106
|
- AGPL-3.0-or-later
|
|
100
107
|
metadata:
|
|
101
108
|
bug_tracker_uri: https://github.com/spree/spree_multi_store/issues
|
|
102
|
-
changelog_uri: https://github.com/spree/spree_multi_store/releases/tag/v1.0.
|
|
109
|
+
changelog_uri: https://github.com/spree/spree_multi_store/releases/tag/v1.0.3
|
|
103
110
|
documentation_uri: https://docs.spreecommerce.org/
|
|
104
|
-
source_code_uri: https://github.com/spree/spree_multi_store/tree/v1.0.
|
|
111
|
+
source_code_uri: https://github.com/spree/spree_multi_store/tree/v1.0.3
|
|
105
112
|
post_install_message: |
|
|
106
113
|
--------------------------------------------------------------
|
|
107
114
|
Thank you for installing Spree Multi-Store!
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Admin
|
|
3
|
-
class CustomDomainsController < ResourceController
|
|
4
|
-
include Spree::Admin::SettingsConcern
|
|
5
|
-
|
|
6
|
-
protected
|
|
7
|
-
|
|
8
|
-
def collection_url
|
|
9
|
-
spree.admin_custom_domains_path
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def location_after_save
|
|
13
|
-
spree.admin_custom_domains_path
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def permitted_resource_params
|
|
17
|
-
params.require(:custom_domain).permit(Spree::PermittedAttributes.custom_domain_attributes)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Stores
|
|
3
|
-
class FindCurrent
|
|
4
|
-
def initialize(scope: nil, url: nil)
|
|
5
|
-
@scope = scope || Spree::Store
|
|
6
|
-
@url = url
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def execute
|
|
10
|
-
store = by_url(scope) || scope.default
|
|
11
|
-
return if store.nil?
|
|
12
|
-
|
|
13
|
-
Spree::Current.store = store
|
|
14
|
-
store
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
protected
|
|
18
|
-
|
|
19
|
-
attr_reader :scope, :url
|
|
20
|
-
|
|
21
|
-
def by_url(scope)
|
|
22
|
-
return if url.blank?
|
|
23
|
-
|
|
24
|
-
scope.by_custom_domain(url).or(scope.by_url(url)).first
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
class CustomDomain < Spree::Base
|
|
3
|
-
has_prefix_id :domain
|
|
4
|
-
|
|
5
|
-
include Spree::SingleStoreResource
|
|
6
|
-
include Spree::Metafields
|
|
7
|
-
include Spree::Metadata
|
|
8
|
-
|
|
9
|
-
normalizes :url, with: ->(value) { value&.to_s&.squish&.presence }
|
|
10
|
-
|
|
11
|
-
#
|
|
12
|
-
# Associations
|
|
13
|
-
#
|
|
14
|
-
belongs_to :store, class_name: 'Spree::Store', inverse_of: :custom_domains, touch: true
|
|
15
|
-
|
|
16
|
-
#
|
|
17
|
-
# Validations
|
|
18
|
-
#
|
|
19
|
-
validates :url, presence: true, uniqueness: true, format: {
|
|
20
|
-
with: %r{\A(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\z}i
|
|
21
|
-
}, length: { in: 1..63 }
|
|
22
|
-
validate :url_is_valid
|
|
23
|
-
|
|
24
|
-
#
|
|
25
|
-
# Callbacks
|
|
26
|
-
#
|
|
27
|
-
before_validation :sanitize_url
|
|
28
|
-
after_save :ensure_has_one_default
|
|
29
|
-
after_validation :ensure_default, on: :create
|
|
30
|
-
|
|
31
|
-
def url_is_valid
|
|
32
|
-
return if url.blank?
|
|
33
|
-
parts = url.split('.')
|
|
34
|
-
|
|
35
|
-
errors.add(:url, 'use domain or subdomain') if parts.size > 4 || parts.size < 2
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def ensure_default
|
|
39
|
-
self.default = store.custom_domains.count.zero?
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def ensure_has_one_default
|
|
43
|
-
store.custom_domains.where.not(id: id).update_all(default: false) if default?
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def active?
|
|
47
|
-
true
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def name
|
|
51
|
-
url
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
private
|
|
55
|
-
|
|
56
|
-
# remove https:// and http:// from the url
|
|
57
|
-
def sanitize_url
|
|
58
|
-
self.url = url&.gsub(%r{https?://}, '')
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
<tr id="<%= spree_dom_id custom_domain %>">
|
|
2
|
-
<td><%= custom_domain.url %></td>
|
|
3
|
-
<td>
|
|
4
|
-
<%= active_badge(custom_domain.active?) %>
|
|
5
|
-
</td>
|
|
6
|
-
|
|
7
|
-
<td><%= active_badge(custom_domain.default?) %></td>
|
|
8
|
-
<td class="actions">
|
|
9
|
-
<%= link_to_edit(custom_domain, no_text: true, url: spree.edit_admin_custom_domain_path(custom_domain), data: { turbo: false }) %>
|
|
10
|
-
</td>
|
|
11
|
-
</tr>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
<% if current_store.custom_domains.any? %>
|
|
2
|
-
<div class="table-responsive rounded-lg mt-4 border">
|
|
3
|
-
<table class="table">
|
|
4
|
-
<thead>
|
|
5
|
-
<tr>
|
|
6
|
-
<th scope="col"><%= sort_link @search, :name, Spree.t(:name) %></th>
|
|
7
|
-
<th scope="col"><%= Spree.t(:active) %>?</th>
|
|
8
|
-
<th scope="col"><%= Spree.t(:default) %>?</th>
|
|
9
|
-
<th scope="col"></th>
|
|
10
|
-
</tr>
|
|
11
|
-
</thead>
|
|
12
|
-
<tbody>
|
|
13
|
-
<%= render collection: current_store.custom_domains, partial: 'spree/admin/custom_domains/custom_domain', cached: spree_base_cache_scope %>
|
|
14
|
-
</tbody>
|
|
15
|
-
</table>
|
|
16
|
-
</div>
|
|
17
|
-
<% else %>
|
|
18
|
-
<%= render 'spree/admin/shared/no_resource_found' %>
|
|
19
|
-
<% end %>
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
<div class="card mb-6">
|
|
2
|
-
<div class="card-body">
|
|
3
|
-
<%= f.spree_text_field :url, label: Spree.t(:domain), prepend: 'https://', autofocus: f.object.new_record?, required: true %>
|
|
4
|
-
|
|
5
|
-
<%= f.spree_check_box :default, help: 'We will use this domain in emails to customers.' %>
|
|
6
|
-
</div>
|
|
7
|
-
</div>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<%= render 'spree/admin/shared/edit_resource' %>
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
<%= content_for(:page_title) do %>
|
|
2
|
-
<%= Spree.t(:domains) %>
|
|
3
|
-
<% end %>
|
|
4
|
-
|
|
5
|
-
<% content_for :page_actions do %>
|
|
6
|
-
<%= render_admin_partials(:custom_domains_actions_partials) %>
|
|
7
|
-
<% end %>
|
|
8
|
-
|
|
9
|
-
<%= render_admin_partials(:custom_domains_header_partials) %>
|
|
10
|
-
|
|
11
|
-
<div class="card-lg p-6">
|
|
12
|
-
<h5 class="mb-2">Internal URL</h5>
|
|
13
|
-
<div class="grid grid-cols-12 gap-6 mb-6">
|
|
14
|
-
<div class="col-span-12 lg:col-span-4">
|
|
15
|
-
<p class="text-gray-600">
|
|
16
|
-
This is your internal Admin URL.
|
|
17
|
-
</p>
|
|
18
|
-
</div>
|
|
19
|
-
<div class="col-span-12 lg:col-span-7 lg:col-start-6">
|
|
20
|
-
<%= form_for current_store, url: spree.admin_store_path, data: { turbo: false, controller: 'enable-button', 'enable-button-disable-when-not-changed-value': true } do |f| %>
|
|
21
|
-
<% if Spree.root_domain.present? %>
|
|
22
|
-
<div class="flex items-center gap-6">
|
|
23
|
-
<div class="input-group pr-2 grow <% if current_store.custom_domains.any? %>disabled<% end %>">
|
|
24
|
-
<span class="text-gray-400 pl-3 pr-0">https://</span>
|
|
25
|
-
<%= f.text_field :code, class: 'border-0 focus:ring-0 focus:outline-none grow rounded-lg text-base pl-0', data: { enable_button_target: 'input' }, required: true, disabled: current_store.custom_domains.any? %>
|
|
26
|
-
<span>.<%= Spree.root_domain %></span>
|
|
27
|
-
|
|
28
|
-
<%= clipboard_component(current_store.formatted_url) %>
|
|
29
|
-
</div>
|
|
30
|
-
<% unless current_store.custom_domains.any? %>
|
|
31
|
-
<%= turbo_save_button_tag %>
|
|
32
|
-
<% end %>
|
|
33
|
-
</div>
|
|
34
|
-
<% else %>
|
|
35
|
-
<div class="flex items-center gap-6">
|
|
36
|
-
<div class="input-group pr-2 grow">
|
|
37
|
-
<span class="text-gray-400 pl-3 pr-0">https://</span>
|
|
38
|
-
<%= f.text_field :url, class: 'border-0 focus:ring-0 focus:outline-none grow rounded-lg text-base pl-0', required: true, data: { enable_button_target: 'input' } %>
|
|
39
|
-
<%= clipboard_component(current_store.formatted_url) %>
|
|
40
|
-
</div>
|
|
41
|
-
<%= turbo_save_button_tag %>
|
|
42
|
-
</div>
|
|
43
|
-
<% end %>
|
|
44
|
-
<% end %>
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
<hr class="my-12" />
|
|
48
|
-
<h5 class="mb-2"><%= Spree.t(:custom_domains) %></h5>
|
|
49
|
-
<div class="grid grid-cols-12 gap-6">
|
|
50
|
-
<div class="col-span-12 lg:col-span-4">
|
|
51
|
-
<p class="text-gray-600">
|
|
52
|
-
Connect your domain or subdomain to your storefront.
|
|
53
|
-
</p>
|
|
54
|
-
</div>
|
|
55
|
-
<div class="col-span-12 lg:col-span-7 lg:col-start-6">
|
|
56
|
-
<div class="text-right">
|
|
57
|
-
<%= link_to Spree.t(:new_domain), spree.new_admin_custom_domain_path, class: "btn btn-primary" %>
|
|
58
|
-
</div>
|
|
59
|
-
|
|
60
|
-
<%= turbo_frame_tag 'admin_custom_domains_index' do %>
|
|
61
|
-
<%= render 'custom_domains' %>
|
|
62
|
-
<% end %>
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
</div>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<%= render 'spree/admin/shared/new_resource' %>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
Rails.application.config.after_initialize do
|
|
2
|
-
next unless defined?(Spree::Admin)
|
|
3
|
-
|
|
4
|
-
settings_nav = Spree.admin.navigation.settings
|
|
5
|
-
|
|
6
|
-
# Domains
|
|
7
|
-
settings_nav.add :domains,
|
|
8
|
-
label: :domains,
|
|
9
|
-
url: :admin_custom_domains_path,
|
|
10
|
-
icon: 'world-www',
|
|
11
|
-
position: 60,
|
|
12
|
-
active: -> { controller_name == 'custom_domains' },
|
|
13
|
-
if: -> { can?(:manage, Spree::CustomDomain) }
|
|
14
|
-
end
|