spree_core 5.4.0.beta → 5.4.0.beta2
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/finders/spree/products/find.rb +1 -28
- data/app/helpers/spree/base_helper.rb +1 -54
- data/app/mailers/spree/base_mailer.rb +4 -3
- data/app/models/concerns/spree/adjustment_source.rb +0 -8
- data/app/models/concerns/spree/admin_user_methods.rb +0 -2
- data/app/models/concerns/spree/image_methods.rb +4 -0
- data/app/models/concerns/spree/metadata.rb +10 -0
- data/app/models/concerns/spree/product_scopes.rb +2 -47
- data/app/models/concerns/spree/stores/markets.rb +7 -7
- data/app/models/concerns/spree/vat_price_calculation.rb +2 -2
- data/app/models/spree/ability.rb +5 -5
- data/app/models/spree/address.rb +3 -2
- data/app/models/spree/adjustable/promotion_accumulator.rb +1 -1
- data/app/models/spree/adjustment.rb +1 -20
- data/app/models/spree/api_key.rb +57 -2
- data/app/models/spree/country.rb +7 -3
- data/app/models/spree/credit_card.rb +0 -27
- data/app/models/spree/current.rb +38 -2
- data/app/models/spree/exports/products.rb +0 -6
- data/app/models/spree/gateway/bogus.rb +9 -9
- data/app/models/spree/gateway.rb +0 -3
- data/app/models/spree/gift_card_batch.rb +4 -0
- data/app/models/spree/image/configuration/active_storage.rb +0 -2
- data/app/models/spree/image.rb +7 -31
- data/app/models/spree/log_entry.rb +8 -5
- data/app/models/spree/order/checkout.rb +0 -18
- data/app/models/spree/order.rb +20 -11
- data/app/models/spree/payment/gateway_options.rb +2 -2
- data/app/models/spree/payment/processing.rb +5 -5
- data/app/models/spree/payment.rb +1 -1
- data/app/models/spree/payment_connection_error.rb +3 -0
- data/app/models/spree/payment_method/check.rb +1 -1
- data/app/models/spree/payment_method/store_credit.rb +5 -5
- data/app/models/spree/payment_response.rb +70 -0
- data/app/models/spree/permission_sets/default_customer.rb +0 -5
- data/app/models/spree/permission_sets/product_display.rb +0 -2
- data/app/models/spree/permission_sets/product_management.rb +0 -2
- data/app/models/spree/product.rb +4 -72
- data/app/models/spree/promotion.rb +2 -14
- data/app/models/spree/promotion_handler/coupon.rb +3 -3
- data/app/models/spree/prototype.rb +0 -3
- data/app/models/spree/refund.rb +6 -2
- data/app/models/spree/shipment/emails.rb +1 -0
- data/app/models/spree/shipping_category.rb +3 -3
- data/app/models/spree/store.rb +10 -49
- data/app/models/spree/store_credit.rb +4 -0
- data/app/models/spree/tax_category.rb +1 -11
- data/app/models/spree/taxon.rb +0 -16
- data/app/models/spree/variant.rb +2 -40
- data/app/models/spree/zone.rb +1 -4
- data/app/services/spree/cart/add_item.rb +8 -4
- data/app/services/spree/cart/create.rb +13 -2
- data/app/services/spree/products/duplicator.rb +0 -12
- data/app/services/spree/products/prepare_nested_attributes.rb +0 -12
- data/config/locales/en.yml +3 -20
- data/db/migrate/20210914000000_spree_four_three.rb +0 -38
- data/db/migrate/20210915064329_add_metadata_to_spree_multiple_tables.rb +0 -1
- data/db/migrate/20260226000000_add_locale_to_spree_orders.rb +5 -0
- data/db/migrate/20260226100000_add_token_digest_to_spree_api_keys.rb +21 -0
- data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +1 -3
- data/lib/spree/core/configuration.rb +0 -3
- data/lib/spree/core/controller_helpers/strong_parameters.rb +1 -2
- data/lib/spree/core/dependencies.rb +2 -10
- data/lib/spree/core/engine.rb +0 -13
- data/lib/spree/core/pricing/resolver.rb +1 -9
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +10 -25
- data/lib/spree/permitted_attributes.rb +2 -14
- data/lib/spree/testing_support/factories/order_factory.rb +1 -0
- data/lib/spree/testing_support/factories/payment_method_factory.rb +1 -6
- data/lib/spree/testing_support/factories/product_factory.rb +0 -7
- data/lib/spree/testing_support/factories/prototype_factory.rb +0 -2
- data/lib/tasks/core.rake +0 -265
- metadata +8 -101
- data/app/finders/spree/posts/find.rb +0 -137
- data/app/finders/spree/product_properties/find_available.rb +0 -20
- data/app/helpers/spree/mail_helper.rb +0 -27
- data/app/jobs/spree/api_key_touch_job.rb +0 -9
- data/app/mailers/spree/test_mailer.rb +0 -8
- data/app/models/action_text/video_embed.rb +0 -13
- data/app/models/concerns/spree/has_one_link.rb +0 -42
- data/app/models/concerns/spree/linkable.rb +0 -9
- data/app/models/concerns/spree/previewable.rb +0 -17
- data/app/models/spree/data_feed/google.rb +0 -15
- data/app/models/spree/data_feed.rb +0 -42
- data/app/models/spree/gateway/bogus_simple.rb +0 -24
- data/app/models/spree/post.rb +0 -108
- data/app/models/spree/post_category.rb +0 -46
- data/app/models/spree/product_property.rb +0 -51
- data/app/models/spree/property.rb +0 -86
- data/app/models/spree/property_prototype.rb +0 -9
- data/app/models/spree/store_favicon_image.rb +0 -20
- data/app/models/spree/store_logo.rb +0 -4
- data/app/models/spree/store_mailer_logo.rb +0 -7
- data/app/models/spree/taxon_image/configuration/active_storage.rb +0 -26
- data/app/models/spree/taxon_image.rb +0 -28
- data/app/presenters/spree/filters/properties_presenter.rb +0 -23
- data/app/presenters/spree/filters/property_presenter.rb +0 -42
- data/app/services/spree/data_feeds/google/optional_attributes.rb +0 -23
- data/app/services/spree/data_feeds/google/optional_sub_attributes.rb +0 -21
- data/app/services/spree/data_feeds/google/products_list.rb +0 -14
- data/app/services/spree/data_feeds/google/required_attributes.rb +0 -68
- data/app/services/spree/data_feeds/google/rss.rb +0 -109
- data/app/sorters/spree/posts/sort.rb +0 -40
- data/app/views/action_text/video_embeds/_thumbnail.html.erb +0 -1
- data/app/views/action_text/video_embeds/_video_embed.html.erb +0 -3
- data/app/views/layouts/action_text/contents/_content.html.erb +0 -3
- data/app/views/spree/test_mailer/test_email.html.erb +0 -40
- data/app/views/spree/test_mailer/test_email.text.erb +0 -4
- data/config/initializers/oembed.rb +0 -1
- data/db/migrate/20221229132350_create_spree_data_feed_settings.rb +0 -14
- data/db/migrate/20230109084253_create_product_property_translations.rb +0 -24
- data/db/migrate/20230109105943_create_property_translations.rb +0 -24
- data/db/migrate/20230415155958_rename_data_feed_settings_table.rb +0 -5
- data/db/migrate/20230415160828_rename_data_feed_table_columns.rb +0 -7
- data/db/migrate/20230415161226_add_indexes_to_data_feeds_table.rb +0 -5
- data/db/migrate/20230512094803_rename_data_feeds_column_provider_to_type.rb +0 -5
- data/db/migrate/20240914153106_add_display_on_to_spree_properties.rb +0 -5
- data/db/migrate/20240915144935_add_position_to_spree_properties.rb +0 -6
- data/db/migrate/20250121160028_create_spree_posts_and_spree_post_categories.rb +0 -33
- data/db/migrate/20250127083740_add_kind_to_spree_properties.rb +0 -5
- data/db/migrate/20250217171018_create_action_text_video_embeds.rb +0 -11
- data/db/migrate/20250305121657_remove_spree_posts_indices.rb +0 -7
- data/db/migrate/20250730154601_add_unique_index_on_spree_properties_name.rb +0 -24
- data/db/sample_data/posts.rb +0 -7
- data/lib/spree/core/controller_helpers/search.rb +0 -17
- data/lib/spree/core/product_filters.rb +0 -218
- data/lib/spree/core/query_filters/comparable.rb +0 -50
- data/lib/spree/core/query_filters/date.rb +0 -8
- data/lib/spree/core/query_filters/number.rb +0 -8
- data/lib/spree/core/query_filters/text.rb +0 -36
- data/lib/spree/core/query_filters.rb +0 -11
- data/lib/spree/core/search/base.rb +0 -144
- data/lib/spree/testing_support/factories/favicon_image_factory.rb +0 -9
- data/lib/spree/testing_support/factories/google_data_feed_factory.rb +0 -7
- data/lib/spree/testing_support/factories/post_category_factory.rb +0 -7
- data/lib/spree/testing_support/factories/post_factory.rb +0 -22
- data/lib/spree/testing_support/factories/product_property_factory.rb +0 -7
- data/lib/spree/testing_support/factories/property_factory.rb +0 -28
- data/lib/spree/testing_support/factories/taxon_image_factory.rb +0 -9
- data/lib/spree/testing_support/flash.rb +0 -25
- data/lib/spree/testing_support/flatpickr_capybara.rb +0 -124
- data/lib/tasks/exchanges.rake +0 -66
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Posts
|
|
3
|
-
class Find < Spree::BaseFinder
|
|
4
|
-
def initialize(scope:, params:)
|
|
5
|
-
super(scope: scope, params: params)
|
|
6
|
-
@scope = scope
|
|
7
|
-
@query = params[:q].presence&.strip
|
|
8
|
-
@ids = String(params.dig(:filter, :ids)).split(',')
|
|
9
|
-
@slugs = String(params.dig(:filter, :slugs)).split(',')
|
|
10
|
-
@category_ids = String(params.dig(:filter, :category_ids)).split(',')
|
|
11
|
-
@author_ids = String(params.dig(:filter, :author_ids)).split(',')
|
|
12
|
-
@tags = params.dig(:filter, :tags).to_s.split(',').compact_blank
|
|
13
|
-
@sort_by = params[:sort_by]
|
|
14
|
-
@published = params.dig(:filter, :published)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def execute
|
|
18
|
-
posts = by_ids(scope)
|
|
19
|
-
posts = by_slugs(posts)
|
|
20
|
-
posts = by_query(posts)
|
|
21
|
-
posts = by_category_ids(posts)
|
|
22
|
-
posts = by_author_ids(posts)
|
|
23
|
-
posts = by_tags(posts)
|
|
24
|
-
posts = by_published(posts)
|
|
25
|
-
posts = ordered(posts)
|
|
26
|
-
|
|
27
|
-
posts.distinct
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
private
|
|
31
|
-
|
|
32
|
-
attr_reader :scope, :query, :ids, :slugs, :category_ids, :author_ids, :tags, :sort_by, :published
|
|
33
|
-
|
|
34
|
-
def query?
|
|
35
|
-
query.present?
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def ids?
|
|
39
|
-
ids.present?
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def slugs?
|
|
43
|
-
slugs.present?
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def category_ids?
|
|
47
|
-
category_ids.present?
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def author_ids?
|
|
51
|
-
author_ids.present?
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def tags?
|
|
55
|
-
tags.present?
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def published?
|
|
59
|
-
published.present?
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def sort_by?
|
|
63
|
-
sort_by.present?
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def by_query(posts)
|
|
67
|
-
return posts unless query?
|
|
68
|
-
|
|
69
|
-
posts.search_by_title(query)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def by_ids(posts)
|
|
73
|
-
return posts unless ids?
|
|
74
|
-
|
|
75
|
-
posts.where(id: ids)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def by_slugs(posts)
|
|
79
|
-
return posts unless slugs?
|
|
80
|
-
|
|
81
|
-
posts.where(slug: slugs)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def by_category_ids(posts)
|
|
85
|
-
return posts unless category_ids?
|
|
86
|
-
|
|
87
|
-
posts.where(post_category_id: category_ids)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def by_author_ids(posts)
|
|
91
|
-
return posts unless author_ids?
|
|
92
|
-
|
|
93
|
-
posts.where(author_id: author_ids)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def by_tags(posts)
|
|
97
|
-
return posts if tags.empty?
|
|
98
|
-
|
|
99
|
-
posts.tagged_with(tags, any: true)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def by_published(posts)
|
|
103
|
-
return posts unless published?
|
|
104
|
-
|
|
105
|
-
case published.to_s
|
|
106
|
-
when 'true'
|
|
107
|
-
posts.published
|
|
108
|
-
when 'false'
|
|
109
|
-
posts.where(published_at: nil)
|
|
110
|
-
else
|
|
111
|
-
posts
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def ordered(posts)
|
|
116
|
-
return posts unless sort_by?
|
|
117
|
-
|
|
118
|
-
case sort_by
|
|
119
|
-
when 'newest-first'
|
|
120
|
-
posts.by_newest
|
|
121
|
-
when 'oldest-first'
|
|
122
|
-
posts.order(created_at: :asc)
|
|
123
|
-
when 'published-newest'
|
|
124
|
-
posts.order(published_at: :desc)
|
|
125
|
-
when 'published-oldest'
|
|
126
|
-
posts.order(published_at: :asc)
|
|
127
|
-
when 'title-a-z'
|
|
128
|
-
posts.order(title: :asc)
|
|
129
|
-
when 'title-z-a'
|
|
130
|
-
posts.order(title: :desc)
|
|
131
|
-
else
|
|
132
|
-
posts
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module ProductProperties
|
|
3
|
-
class FindAvailable
|
|
4
|
-
include ProductFilterable
|
|
5
|
-
|
|
6
|
-
def initialize(scope: ProductProperty.spree_base_scopes, products_scope: Product.spree_base_scopes)
|
|
7
|
-
@scope = scope
|
|
8
|
-
@products_scope = products_scope
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def execute
|
|
12
|
-
find_available(scope, products_scope).includes(:translations)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
private
|
|
16
|
-
|
|
17
|
-
attr_reader :scope, :products_scope
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module MailHelper
|
|
3
|
-
include Spree::BaseHelper
|
|
4
|
-
include Spree::ImagesHelper
|
|
5
|
-
|
|
6
|
-
def variant_image_url(variant)
|
|
7
|
-
image = variant.default_image
|
|
8
|
-
image.present? && image.attached? ? spree_image_url(image, variant: :mini) : image_url('noimage/small.png')
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def name_for(order)
|
|
12
|
-
order.name || Spree.t('customer')
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def store_logo
|
|
16
|
-
@store_logo ||= current_store&.mailer_logo || current_store&.logo
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def logo_path
|
|
20
|
-
Spree::Deprecation.warn('logo_path is deprecated and will be removed in Spree 5.5. Please use Active Storage URL helpers instead.')
|
|
21
|
-
|
|
22
|
-
return main_app.cdn_image_url(store_logo.variant(resize_to_limit: [244, 104])) if store_logo&.variable?
|
|
23
|
-
|
|
24
|
-
return main_app.cdn_image_url(store_logo) if store_logo&.image?
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
module ActionText
|
|
2
|
-
class VideoEmbed < ApplicationRecord
|
|
3
|
-
include ActionText::Attachable
|
|
4
|
-
|
|
5
|
-
validates :url, :raw_html, :thumbnail_url, presence: true
|
|
6
|
-
|
|
7
|
-
# `to_partial_path` for the storefront render is by default "action_text/video_embeds/video_embed"
|
|
8
|
-
|
|
9
|
-
def to_trix_content_attachment_partial_path
|
|
10
|
-
'action_text/video_embeds/thumbnail'
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module HasOneLink
|
|
3
|
-
extend ActiveSupport::Concern
|
|
4
|
-
|
|
5
|
-
included do
|
|
6
|
-
has_one :link, ->(ps) { ps.links }, class_name: 'Spree::PageLink', as: :parent, dependent: :destroy, inverse_of: :parent
|
|
7
|
-
accepts_nested_attributes_for :link
|
|
8
|
-
|
|
9
|
-
def allowed_linkable_types
|
|
10
|
-
[
|
|
11
|
-
[Spree.t(:page), 'Spree::Page'],
|
|
12
|
-
[Spree.t(:product), 'Spree::Product'],
|
|
13
|
-
[Spree.t(:post), 'Spree::Post'],
|
|
14
|
-
[Spree.t(:taxon), 'Spree::Taxon'],
|
|
15
|
-
[Spree.t(:policy), 'Spree::Policy'],
|
|
16
|
-
[Spree.t(:url), nil]
|
|
17
|
-
]
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def default_linkable_type
|
|
21
|
-
'Spree::Page'
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def default_linkable_resource
|
|
25
|
-
@default_linkable_resource ||= theme_or_parent.pages.find_by(type: 'Spree::Pages::Homepage')
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def default_links
|
|
29
|
-
@default_links.presence || [
|
|
30
|
-
Spree::PageLink.new(
|
|
31
|
-
label: Spree.t(:shop_all),
|
|
32
|
-
linkable: theme_or_parent.pages.find_by(type: 'Spree::Pages::ShopAll')
|
|
33
|
-
)
|
|
34
|
-
]
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def theme_or_parent
|
|
38
|
-
theme.preview? ? theme.parent : theme
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Previewable
|
|
3
|
-
extend ActiveSupport::Concern
|
|
4
|
-
|
|
5
|
-
included do |base|
|
|
6
|
-
belongs_to :parent, class_name: base.name, optional: true, foreign_key: :parent_id
|
|
7
|
-
has_many :previews, class_name: base.name, dependent: :destroy_async, foreign_key: :parent_id
|
|
8
|
-
|
|
9
|
-
scope :without_previews, -> { where(parent_id: nil) }
|
|
10
|
-
scope :only_previews, -> { where.not(parent_id: nil) }
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def preview?
|
|
14
|
-
parent.present?
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
class DataFeed < Spree.base_class
|
|
3
|
-
has_prefix_id :df
|
|
4
|
-
|
|
5
|
-
belongs_to :store, class_name: 'Spree::Store', foreign_key: 'store_id'
|
|
6
|
-
|
|
7
|
-
scope :for_store, ->(store) { where(store: store) }
|
|
8
|
-
|
|
9
|
-
before_validation :generate_slug
|
|
10
|
-
|
|
11
|
-
with_options presence: true do
|
|
12
|
-
validates :store
|
|
13
|
-
validates :name, uniqueness: true
|
|
14
|
-
validates :slug, uniqueness: { scope: :store_id }
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def formatted_url
|
|
18
|
-
"#{store.formatted_url}/api/v2/data_feeds/#{self.class.provider_name}/#{slug}.rss"
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def generate_slug
|
|
24
|
-
new_slug = slug.blank? ? SecureRandom.uuid : slug.parameterize
|
|
25
|
-
write_attribute(:slug, new_slug)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
class << self
|
|
29
|
-
def label
|
|
30
|
-
raise NotImplementedError
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def provider_name
|
|
34
|
-
raise NotImplementedError
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def available_types
|
|
38
|
-
Spree.data_feed_types
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# Bogus Gateway that doesn't support payment profiles
|
|
2
|
-
module Spree
|
|
3
|
-
class Gateway::BogusSimple < Gateway::Bogus
|
|
4
|
-
def payment_profiles_supported?
|
|
5
|
-
false
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def authorize(_money, credit_card, _options = {})
|
|
9
|
-
if VALID_CCS.include? credit_card.number
|
|
10
|
-
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'A' })
|
|
11
|
-
else
|
|
12
|
-
ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', { message: 'Bogus Gateway: Forced failure' }, test: true)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def purchase(_money, credit_card, _options = {})
|
|
17
|
-
if VALID_CCS.include? credit_card.number
|
|
18
|
-
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'A' })
|
|
19
|
-
else
|
|
20
|
-
ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', message: 'Bogus Gateway: Forced failure', test: true)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
data/app/models/spree/post.rb
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
class Post < Spree.base_class
|
|
3
|
-
has_prefix_id :post
|
|
4
|
-
|
|
5
|
-
include Spree::SingleStoreResource
|
|
6
|
-
include Spree::Metafields
|
|
7
|
-
extend FriendlyId
|
|
8
|
-
|
|
9
|
-
publishes_lifecycle_events
|
|
10
|
-
|
|
11
|
-
friendly_id :slug_candidates, use: %i[slugged scoped history], scope: %i[store_id deleted?]
|
|
12
|
-
acts_as_paranoid
|
|
13
|
-
acts_as_taggable_on :tags
|
|
14
|
-
acts_as_taggable_tenant :store_id
|
|
15
|
-
|
|
16
|
-
if defined?(PgSearch)
|
|
17
|
-
include PgSearch::Model
|
|
18
|
-
pg_search_scope :search_by_title, against: :title
|
|
19
|
-
else
|
|
20
|
-
scope :search_by_title, ->(query) { where('title LIKE ?', "%#{query}%") }
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
#
|
|
24
|
-
# Ransack filtering
|
|
25
|
-
#
|
|
26
|
-
self.whitelisted_ransackable_attributes = %w[author_id post_category_id published_at]
|
|
27
|
-
self.whitelisted_ransackable_associations = %w[author post_category]
|
|
28
|
-
self.whitelisted_ransackable_scopes = %w[search_by_title]
|
|
29
|
-
|
|
30
|
-
#
|
|
31
|
-
# Attachments
|
|
32
|
-
#
|
|
33
|
-
has_one_attached :image, service: Spree.public_storage_service_name
|
|
34
|
-
|
|
35
|
-
#
|
|
36
|
-
# Rich Text
|
|
37
|
-
#
|
|
38
|
-
has_rich_text :content
|
|
39
|
-
has_rich_text :excerpt
|
|
40
|
-
|
|
41
|
-
#
|
|
42
|
-
# Associations
|
|
43
|
-
#
|
|
44
|
-
belongs_to :author, class_name: Spree.admin_user_class.to_s, optional: true
|
|
45
|
-
belongs_to :store, class_name: 'Spree::Store', inverse_of: :posts
|
|
46
|
-
belongs_to :post_category, class_name: 'Spree::PostCategory', optional: true, touch: true, inverse_of: :posts
|
|
47
|
-
alias category post_category
|
|
48
|
-
|
|
49
|
-
#
|
|
50
|
-
# Validations
|
|
51
|
-
#
|
|
52
|
-
validates :title, :store, presence: true
|
|
53
|
-
validates :slug, presence: true, uniqueness: { scope: :store_id, conditions: -> { where(deleted_at: nil) } }
|
|
54
|
-
validates :meta_title, length: { maximum: 160 }, allow_blank: true
|
|
55
|
-
validates :meta_description, length: { maximum: 320 }, allow_blank: true
|
|
56
|
-
validates :image, content_type: Rails.application.config.active_storage.web_image_content_types
|
|
57
|
-
|
|
58
|
-
#
|
|
59
|
-
# Scopes
|
|
60
|
-
#
|
|
61
|
-
scope :published, -> { where(published_at: [..Time.current]) }
|
|
62
|
-
scope :by_newest, -> { order(created_at: :desc) }
|
|
63
|
-
|
|
64
|
-
delegate :name, to: :author, prefix: true, allow_nil: true
|
|
65
|
-
delegate :title, to: :post_category, prefix: true, allow_nil: true
|
|
66
|
-
|
|
67
|
-
def should_generate_new_friendly_id?
|
|
68
|
-
slug.blank? || (persisted? && title_changed?)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def slug_candidates
|
|
72
|
-
[
|
|
73
|
-
:title,
|
|
74
|
-
[:title, :id]
|
|
75
|
-
]
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def published?
|
|
79
|
-
published_at.present?
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def publish(date = nil)
|
|
83
|
-
update(published_at: date || Time.current)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def unpublish
|
|
87
|
-
update(published_at: nil)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def description
|
|
91
|
-
excerpt.to_plain_text.presence || content.to_plain_text
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def shortened_description
|
|
95
|
-
desc = excerpt.to_plain_text.presence || content.to_plain_text
|
|
96
|
-
desc.length > 320 ? "#{desc[0...320]}..." : desc
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def self.to_tom_select_json
|
|
100
|
-
pluck(:id, :title).map do |id, title|
|
|
101
|
-
{
|
|
102
|
-
id: id,
|
|
103
|
-
name: title
|
|
104
|
-
}
|
|
105
|
-
end.as_json
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
end
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
class PostCategory < Spree.base_class
|
|
3
|
-
has_prefix_id :pcat
|
|
4
|
-
|
|
5
|
-
include Spree::SingleStoreResource
|
|
6
|
-
include Spree::Metafields
|
|
7
|
-
extend FriendlyId
|
|
8
|
-
|
|
9
|
-
publishes_lifecycle_events
|
|
10
|
-
|
|
11
|
-
friendly_id :slug_candidates, use: %i[slugged scoped history], scope: %i[store_id]
|
|
12
|
-
|
|
13
|
-
#
|
|
14
|
-
# Associations
|
|
15
|
-
#
|
|
16
|
-
belongs_to :store, class_name: 'Spree::Store', inverse_of: :post_categories
|
|
17
|
-
has_many :posts, class_name: 'Spree::Post', dependent: :nullify, inverse_of: :post_category
|
|
18
|
-
|
|
19
|
-
#
|
|
20
|
-
# Validations
|
|
21
|
-
#
|
|
22
|
-
validates :title, :store, presence: true
|
|
23
|
-
validates :slug, presence: true, uniqueness: { scope: :store_id }
|
|
24
|
-
|
|
25
|
-
#
|
|
26
|
-
# ActionText
|
|
27
|
-
#
|
|
28
|
-
has_rich_text :description
|
|
29
|
-
|
|
30
|
-
#
|
|
31
|
-
# Ransack
|
|
32
|
-
#
|
|
33
|
-
self.whitelisted_ransackable_attributes = %w[title slug]
|
|
34
|
-
|
|
35
|
-
def should_generate_new_friendly_id?
|
|
36
|
-
slug.blank? || title_changed?
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def slug_candidates
|
|
40
|
-
[
|
|
41
|
-
:title,
|
|
42
|
-
[:title, :id]
|
|
43
|
-
]
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
class ProductProperty < Spree.base_class
|
|
3
|
-
include Spree::FilterParam
|
|
4
|
-
include Spree::TranslatableResource
|
|
5
|
-
|
|
6
|
-
if Spree.always_use_translations?
|
|
7
|
-
TRANSLATABLE_FIELDS = %i[value filter_param].freeze
|
|
8
|
-
translates(*TRANSLATABLE_FIELDS)
|
|
9
|
-
else
|
|
10
|
-
TRANSLATABLE_FIELDS = %i[value].freeze
|
|
11
|
-
translates(*TRANSLATABLE_FIELDS, column_fallback: true)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
self::Translation.class_eval do
|
|
15
|
-
normalizes :value, with: ->(value) { value&.to_s&.squish&.presence }
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
normalizes :value, with: ->(value) { value&.to_s&.squish&.presence }
|
|
19
|
-
|
|
20
|
-
acts_as_list scope: :product
|
|
21
|
-
|
|
22
|
-
with_options inverse_of: :product_properties do
|
|
23
|
-
belongs_to :product, touch: true, class_name: 'Spree::Product'
|
|
24
|
-
belongs_to :property, touch: true, class_name: 'Spree::Property'
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
validates :property, presence: true
|
|
28
|
-
validates :property_id, uniqueness: { scope: :product_id }
|
|
29
|
-
validates :value, presence: true
|
|
30
|
-
|
|
31
|
-
default_scope { order(:position) }
|
|
32
|
-
|
|
33
|
-
scope :filterable, -> { joins(:property).where(Property.table_name => { filterable: true }) }
|
|
34
|
-
scope :for_products, ->(products) { where(product_id: products) }
|
|
35
|
-
scope :sort_by_property_position, -> {
|
|
36
|
-
unscope(:order).joins(:property).order(Spree::Property.table_name => { position: :asc })
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
self.whitelisted_ransackable_attributes = ['value', 'filter_param']
|
|
40
|
-
self.whitelisted_ransackable_associations = ['property']
|
|
41
|
-
|
|
42
|
-
# virtual attributes for use with AJAX completion stuff
|
|
43
|
-
delegate :name, :presentation, to: :property, prefix: true, allow_nil: true
|
|
44
|
-
|
|
45
|
-
protected
|
|
46
|
-
|
|
47
|
-
def param_candidate
|
|
48
|
-
value
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
class Property < Spree.base_class
|
|
3
|
-
include Spree::FilterParam
|
|
4
|
-
include Spree::Metadata
|
|
5
|
-
include Spree::ParameterizableName
|
|
6
|
-
include Spree::UniqueName
|
|
7
|
-
include Spree::DisplayOn
|
|
8
|
-
include Spree::TranslatableResource
|
|
9
|
-
|
|
10
|
-
TRANSLATABLE_FIELDS = %i[presentation].freeze
|
|
11
|
-
translates(*TRANSLATABLE_FIELDS, column_fallback: !Spree.always_use_translations?)
|
|
12
|
-
|
|
13
|
-
self::Translation.class_eval do
|
|
14
|
-
normalizes :presentation, with: ->(value) { value&.to_s&.squish&.presence }
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
acts_as_list
|
|
18
|
-
|
|
19
|
-
has_many :property_prototypes, class_name: 'Spree::PropertyPrototype'
|
|
20
|
-
has_many :prototypes, through: :property_prototypes, class_name: 'Spree::Prototype'
|
|
21
|
-
|
|
22
|
-
has_many :product_properties, dependent: :delete_all, inverse_of: :property
|
|
23
|
-
has_many :products, through: :product_properties
|
|
24
|
-
|
|
25
|
-
validates :name, :presentation, presence: true
|
|
26
|
-
|
|
27
|
-
default_scope { order(:position) }
|
|
28
|
-
scope :sorted, -> { order(:name) }
|
|
29
|
-
scope :filterable, -> { where(filterable: true) }
|
|
30
|
-
|
|
31
|
-
KIND_OPTIONS = { short_text: 0, long_text: 1, number: 2, rich_text: 3 }.freeze
|
|
32
|
-
enum :kind, KIND_OPTIONS
|
|
33
|
-
|
|
34
|
-
DEPENDENCY_UPDATE_FIELDS = [:presentation, :name, :kind, :filterable, :display_on, :position].freeze
|
|
35
|
-
|
|
36
|
-
after_touch :touch_all_products
|
|
37
|
-
after_update :touch_all_products, if: -> { DEPENDENCY_UPDATE_FIELDS.any? { |field| saved_changes.key?(field) } }
|
|
38
|
-
after_save :ensure_product_properties_have_filter_params
|
|
39
|
-
|
|
40
|
-
self.whitelisted_ransackable_attributes = ['presentation', 'filterable']
|
|
41
|
-
|
|
42
|
-
def uniq_values(product_properties_scope: nil)
|
|
43
|
-
with_uniq_values_cache_key(product_properties_scope) do
|
|
44
|
-
properties = product_properties
|
|
45
|
-
properties = properties.where(id: product_properties_scope) if product_properties_scope.present?
|
|
46
|
-
properties.where('value IS NOT NULL AND value != ?', '').pluck(:filter_param, :value).uniq
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# Returns the metafield type for the property kind
|
|
51
|
-
# @return [String] eg. 'Spree::Metafields::ShortText'
|
|
52
|
-
def kind_to_metafield_type
|
|
53
|
-
case kind
|
|
54
|
-
when 'short_text'
|
|
55
|
-
'Spree::Metafields::ShortText'
|
|
56
|
-
when 'long_text'
|
|
57
|
-
'Spree::Metafields::LongText'
|
|
58
|
-
when 'number'
|
|
59
|
-
'Spree::Metafields::Number'
|
|
60
|
-
when 'rich_text'
|
|
61
|
-
'Spree::Metafields::RichText'
|
|
62
|
-
else
|
|
63
|
-
'Spree::Metafields::ShortText'
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
private
|
|
68
|
-
|
|
69
|
-
def touch_all_products
|
|
70
|
-
products.touch_all
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def with_uniq_values_cache_key(product_properties_scope, &block)
|
|
74
|
-
return block.call if product_properties_scope.present?
|
|
75
|
-
|
|
76
|
-
uniq_values_cache_key = ['property-uniq-values', cache_key_with_version]
|
|
77
|
-
Rails.cache.fetch(uniq_values_cache_key) { block.call }
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def ensure_product_properties_have_filter_params
|
|
81
|
-
return unless filterable?
|
|
82
|
-
|
|
83
|
-
product_properties.where(filter_param: [nil, '']).where('value IS NOT NULL AND value != ?', '').find_each(&:save)
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
class PropertyPrototype < Spree.base_class
|
|
3
|
-
belongs_to :prototype, class_name: 'Spree::Prototype'
|
|
4
|
-
belongs_to :property, class_name: 'Spree::Property'
|
|
5
|
-
|
|
6
|
-
validates :prototype, :property, presence: true
|
|
7
|
-
validates :prototype_id, uniqueness: { scope: :property_id }
|
|
8
|
-
end
|
|
9
|
-
end
|