spree_core 5.2.8 → 5.3.0.rc1

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 (296) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/addresses_helper.rb +1 -23
  3. data/app/helpers/spree/base_helper.rb +25 -77
  4. data/app/helpers/spree/currency_helper.rb +2 -2
  5. data/app/helpers/spree/images_helper.rb +5 -0
  6. data/app/helpers/spree/mail_helper.rb +1 -1
  7. data/app/helpers/spree/products_helper.rb +1 -1
  8. data/app/jobs/spree/events/subscriber_job.rb +58 -0
  9. data/app/jobs/spree/products/refresh_metrics_job.rb +14 -0
  10. data/app/jobs/spree/products/touch_taxons_job.rb +0 -1
  11. data/app/jobs/spree/variants/touch_job.rb +9 -0
  12. data/app/models/concerns/spree/adjustment_source.rb +8 -0
  13. data/app/models/concerns/spree/parameterizable_name.rb +1 -1
  14. data/app/models/concerns/spree/product_scopes.rb +54 -8
  15. data/app/models/concerns/spree/publishable.rb +253 -0
  16. data/app/models/concerns/spree/unique_name.rb +1 -1
  17. data/app/models/concerns/spree/user_methods.rb +21 -1
  18. data/app/models/spree/ability.rb +3 -3
  19. data/app/models/spree/address.rb +0 -3
  20. data/app/models/spree/adjustable/promotion_accumulator.rb +1 -1
  21. data/app/models/spree/adjustment.rb +32 -6
  22. data/app/models/spree/asset.rb +6 -3
  23. data/app/models/spree/base.rb +3 -1
  24. data/app/models/spree/classification.rb +2 -2
  25. data/app/models/spree/credit_card.rb +0 -3
  26. data/app/models/spree/current.rb +24 -3
  27. data/app/models/spree/custom_domain.rb +1 -1
  28. data/app/models/spree/customer_group.rb +94 -0
  29. data/app/models/spree/customer_group_user.rb +16 -0
  30. data/app/models/spree/customer_return.rb +2 -3
  31. data/app/models/spree/digital.rb +2 -4
  32. data/app/models/spree/digital_link.rb +2 -3
  33. data/app/models/spree/event.rb +104 -0
  34. data/app/models/spree/export.rb +9 -3
  35. data/app/models/spree/gift_card.rb +13 -1
  36. data/app/models/spree/gift_card_batch.rb +3 -1
  37. data/app/models/spree/image.rb +20 -5
  38. data/app/models/spree/import.rb +17 -12
  39. data/app/models/spree/import_row.rb +13 -26
  40. data/app/models/spree/inventory_unit.rb +0 -3
  41. data/app/models/spree/invitation.rb +12 -6
  42. data/app/models/spree/line_item.rb +57 -4
  43. data/app/models/spree/newsletter_subscriber.rb +2 -0
  44. data/app/models/spree/option_type.rb +2 -5
  45. data/app/models/spree/option_value.rb +1 -4
  46. data/app/models/spree/order/address_book.rb +4 -12
  47. data/app/models/spree/order/checkout.rb +7 -2
  48. data/app/models/spree/order/emails.rb +3 -11
  49. data/app/models/spree/order/store_credit.rb +5 -1
  50. data/app/models/spree/order.rb +80 -31
  51. data/app/models/spree/order_updater.rb +28 -9
  52. data/app/models/spree/payment/custom_events.rb +37 -0
  53. data/app/models/spree/payment.rb +13 -4
  54. data/app/models/spree/payment_capture_event.rb +0 -4
  55. data/app/models/spree/payment_method.rb +1 -1
  56. data/app/models/spree/permission_sets/default_customer.rb +3 -3
  57. data/app/models/spree/policy.rb +1 -8
  58. data/app/models/spree/post.rb +2 -7
  59. data/app/models/spree/post_category.rb +2 -0
  60. data/app/models/spree/price.rb +8 -6
  61. data/app/models/spree/price_list.rb +263 -0
  62. data/app/models/spree/price_rule.rb +26 -0
  63. data/app/models/spree/price_rules/customer_group_rule.rb +21 -0
  64. data/app/models/spree/price_rules/user_rule.rb +19 -0
  65. data/app/models/spree/price_rules/volume_rule.rb +21 -0
  66. data/app/models/spree/price_rules/zone_rule.rb +19 -0
  67. data/app/models/spree/product.rb +117 -76
  68. data/app/models/spree/product_property.rb +2 -2
  69. data/app/models/spree/promotion/rules/customer_group.rb +22 -0
  70. data/app/models/spree/promotion/rules/user.rb +2 -2
  71. data/app/models/spree/promotion.rb +3 -4
  72. data/app/models/spree/promotion_handler/coupon.rb +3 -3
  73. data/app/models/spree/property.rb +3 -6
  74. data/app/models/spree/prototype.rb +0 -3
  75. data/app/models/spree/refund.rb +2 -3
  76. data/app/models/spree/reimbursement.rb +5 -3
  77. data/app/models/spree/report.rb +7 -1
  78. data/app/models/spree/reports/products_performance.rb +1 -1
  79. data/app/models/spree/reports/sales_total.rb +1 -1
  80. data/app/models/spree/return_authorization.rb +7 -3
  81. data/app/models/spree/return_item.rb +15 -4
  82. data/app/models/spree/shipment/custom_events.rb +47 -0
  83. data/app/models/spree/shipment.rb +12 -5
  84. data/app/models/spree/shipping_category.rb +0 -3
  85. data/app/models/spree/shipping_method.rb +0 -3
  86. data/app/models/spree/stock/quantifier.rb +1 -1
  87. data/app/models/spree/stock_item.rb +2 -0
  88. data/app/models/spree/stock_location.rb +0 -3
  89. data/app/models/spree/stock_movement/custom_events.rb +44 -0
  90. data/app/models/spree/stock_movement.rb +3 -0
  91. data/app/models/spree/stock_transfer.rb +2 -3
  92. data/app/models/spree/store.rb +64 -92
  93. data/app/models/spree/store_credit.rb +3 -4
  94. data/app/models/spree/store_product.rb +14 -0
  95. data/app/models/spree/subscriber.rb +186 -0
  96. data/app/models/spree/tax_category.rb +0 -4
  97. data/app/models/spree/tax_rate.rb +0 -3
  98. data/app/models/spree/taxon.rb +3 -36
  99. data/app/models/spree/taxonomy.rb +0 -3
  100. data/app/models/spree/variant.rb +114 -21
  101. data/app/models/spree/webhook_delivery.rb +60 -0
  102. data/app/models/spree/webhook_endpoint.rb +53 -0
  103. data/app/models/spree/wished_item.rb +2 -4
  104. data/app/models/spree/wishlist.rb +2 -3
  105. data/app/models/spree/zone.rb +0 -9
  106. data/app/paginators/spree/shared/paginate.rb +4 -0
  107. data/app/serializers/spree/events/asset_serializer.rb +22 -0
  108. data/app/serializers/spree/events/base_serializer.rb +61 -0
  109. data/app/serializers/spree/events/customer_return_serializer.rb +20 -0
  110. data/app/serializers/spree/events/digital_link_serializer.rb +20 -0
  111. data/app/serializers/spree/events/digital_serializer.rb +18 -0
  112. data/app/serializers/spree/events/export_serializer.rb +22 -0
  113. data/app/serializers/spree/events/gift_card_batch_serializer.rb +24 -0
  114. data/app/serializers/spree/events/gift_card_serializer.rb +29 -0
  115. data/app/serializers/spree/events/image_serializer.rb +9 -0
  116. data/app/serializers/spree/events/import_row_serializer.rb +23 -0
  117. data/app/serializers/spree/events/import_serializer.rb +24 -0
  118. data/app/serializers/spree/events/invitation_serializer.rb +28 -0
  119. data/app/serializers/spree/events/line_item_serializer.rb +31 -0
  120. data/app/serializers/spree/events/newsletter_subscriber_serializer.rb +21 -0
  121. data/app/serializers/spree/events/order_serializer.rb +39 -0
  122. data/app/serializers/spree/events/payment_serializer.rb +24 -0
  123. data/app/serializers/spree/events/post_category_serializer.rb +20 -0
  124. data/app/serializers/spree/events/post_serializer.rb +26 -0
  125. data/app/serializers/spree/events/price_serializer.rb +22 -0
  126. data/app/serializers/spree/events/product_serializer.rb +24 -0
  127. data/app/serializers/spree/events/promotion_serializer.rb +32 -0
  128. data/app/serializers/spree/events/refund_serializer.rb +23 -0
  129. data/app/serializers/spree/events/reimbursement_serializer.rb +22 -0
  130. data/app/serializers/spree/events/report_serializer.rb +23 -0
  131. data/app/serializers/spree/events/return_authorization_serializer.rb +22 -0
  132. data/app/serializers/spree/events/return_item_serializer.rb +27 -0
  133. data/app/serializers/spree/events/shipment_serializer.rb +24 -0
  134. data/app/serializers/spree/events/stock_item_serializer.rb +22 -0
  135. data/app/serializers/spree/events/stock_movement_serializer.rb +22 -0
  136. data/app/serializers/spree/events/stock_transfer_serializer.rb +22 -0
  137. data/app/serializers/spree/events/store_credit_serializer.rb +30 -0
  138. data/app/serializers/spree/events/user_serializer.rb +18 -0
  139. data/app/serializers/spree/events/variant_serializer.rb +34 -0
  140. data/app/serializers/spree/events/wished_item_serializer.rb +20 -0
  141. data/app/serializers/spree/events/wishlist_serializer.rb +22 -0
  142. data/app/services/spree/addresses/update.rb +1 -1
  143. data/app/services/spree/cart/add_item.rb +1 -1
  144. data/app/services/spree/coupon_codes/coupon_codes_handler.rb +2 -1
  145. data/app/services/spree/data_feeds/google/required_attributes.rb +4 -4
  146. data/app/services/spree/newsletter/verify.rb +5 -0
  147. data/app/services/spree/products/auto_match_taxons.rb +1 -1
  148. data/app/services/spree/seeds/all.rb +1 -1
  149. data/app/services/spree/taxons/add_products.rb +8 -4
  150. data/app/services/spree/taxons/regenerate_products.rb +8 -0
  151. data/app/services/spree/taxons/remove_products.rb +12 -7
  152. data/app/subscribers/spree/event_log_subscriber.rb +64 -0
  153. data/app/subscribers/spree/export_subscriber.rb +26 -0
  154. data/app/subscribers/spree/invitation_email_subscriber.rb +40 -0
  155. data/app/subscribers/spree/product_metrics_subscriber.rb +29 -0
  156. data/app/subscribers/spree/report_subscriber.rb +26 -0
  157. data/config/locales/en.yml +126 -0
  158. data/db/migrate/20251110120000_create_spree_price_lists.rb +22 -0
  159. data/db/migrate/20251110120001_create_spree_price_rules.rb +13 -0
  160. data/db/migrate/20251110120002_add_price_list_id_to_spree_prices.rb +6 -0
  161. data/db/migrate/20251110120003_add_price_list_id_to_spree_line_items.rb +5 -0
  162. data/db/migrate/20251201172118_fix_indexes_on_friendly_id_slugs.rb +8 -0
  163. data/db/migrate/20251214000001_create_spree_webhook_endpoints.rb +19 -0
  164. data/db/migrate/20251214000002_create_spree_webhook_deliveries.rb +23 -0
  165. data/db/migrate/20251222000000_add_performance_indexes_to_spree_adjustments.rb +25 -0
  166. data/db/migrate/20260112000000_fix_spree_prices_unique_indexes.rb +33 -0
  167. data/db/migrate/20260115120000_create_spree_customer_groups.rb +14 -0
  168. data/db/migrate/20260115120001_create_spree_customer_group_users.rb +14 -0
  169. data/db/migrate/20260117140831_remove_not_null_constraint_from_policy_name.rb +5 -0
  170. data/db/migrate/20260118120000_add_statistics_to_store_products.rb +11 -0
  171. data/db/migrate/20260119120000_add_counter_caches_to_spree_products.rb +9 -0
  172. data/db/migrate/20260119170000_add_counter_caches_to_spree_taxons.rb +9 -0
  173. data/db/migrate/20260120120000_add_image_count_to_spree_variants.rb +9 -0
  174. data/lib/generators/spree/dummy/dummy_generator.rb +14 -2
  175. data/lib/spree/core/configuration.rb +1 -0
  176. data/lib/spree/core/controller_helpers/auth.rb +0 -15
  177. data/lib/spree/core/controller_helpers/currency.rb +13 -9
  178. data/lib/spree/core/controller_helpers/search.rb +1 -1
  179. data/lib/spree/core/controller_helpers/store.rb +5 -1
  180. data/lib/spree/core/engine.rb +61 -78
  181. data/lib/spree/core/importer/order.rb +1 -1
  182. data/lib/spree/core/importer/product.rb +1 -1
  183. data/lib/spree/core/preferences/preferable.rb +14 -1
  184. data/lib/spree/core/pricing/context.rb +63 -0
  185. data/lib/spree/core/pricing/resolver.rb +129 -0
  186. data/lib/spree/core/search/base.rb +1 -1
  187. data/lib/spree/core/token_generator.rb +1 -1
  188. data/lib/spree/core/version.rb +1 -1
  189. data/lib/spree/core.rb +42 -47
  190. data/lib/spree/events/adapters/active_support_notifications.rb +112 -0
  191. data/lib/spree/events/adapters/base.rb +193 -0
  192. data/lib/spree/events/registry.rb +99 -0
  193. data/lib/spree/events.rb +240 -0
  194. data/lib/spree/permitted_attributes.rb +13 -2
  195. data/lib/spree/testing_support/common_rake.rb +68 -35
  196. data/lib/spree/testing_support/factories/customer_group_factory.rb +6 -0
  197. data/lib/spree/testing_support/factories/customer_group_user_factory.rb +6 -0
  198. data/lib/spree/testing_support/factories/price_factory.rb +4 -0
  199. data/lib/spree/testing_support/factories/price_list_factory.rb +34 -0
  200. data/lib/spree/testing_support/factories/price_rule_factory.rb +49 -0
  201. data/lib/spree/testing_support/factories/promotion_rule_factory.rb +12 -0
  202. data/lib/spree/testing_support/factories/stock_item_factory.rb +6 -4
  203. data/lib/spree/testing_support/factories/store_product_factory.rb +6 -0
  204. data/lib/spree/testing_support/factories/taxon_factory.rb +0 -1
  205. data/lib/spree/testing_support/factories/webhook_delivery_factory.rb +48 -0
  206. data/lib/spree/testing_support/factories/webhook_endpoint_factory.rb +22 -0
  207. data/lib/spree/testing_support/lifecycle_events.rb +38 -0
  208. data/lib/spree/testing_support/store.rb +4 -2
  209. data/lib/spree/webhooks.rb +22 -0
  210. data/lib/tasks/products.rake +40 -0
  211. data/lib/tasks/taxons.rake +19 -0
  212. data/lib/tasks/variants.rake +18 -0
  213. metadata +112 -115
  214. data/app/jobs/spree/themes/duplicate_components_job.rb +0 -59
  215. data/app/jobs/spree/themes/screenshot_job.rb +0 -81
  216. data/app/models/concerns/spree/has_page_links.rb +0 -53
  217. data/app/models/spree/page.rb +0 -188
  218. data/app/models/spree/page_block.rb +0 -73
  219. data/app/models/spree/page_blocks/buttons.rb +0 -29
  220. data/app/models/spree/page_blocks/heading.rb +0 -18
  221. data/app/models/spree/page_blocks/image.rb +0 -20
  222. data/app/models/spree/page_blocks/link.rb +0 -21
  223. data/app/models/spree/page_blocks/mega_nav.rb +0 -33
  224. data/app/models/spree/page_blocks/mega_nav_with_subcategories.rb +0 -32
  225. data/app/models/spree/page_blocks/metafields.rb +0 -18
  226. data/app/models/spree/page_blocks/nav.rb +0 -15
  227. data/app/models/spree/page_blocks/newsletter_form.rb +0 -18
  228. data/app/models/spree/page_blocks/products/brand.rb +0 -15
  229. data/app/models/spree/page_blocks/products/buy_buttons.rb +0 -24
  230. data/app/models/spree/page_blocks/products/description.rb +0 -18
  231. data/app/models/spree/page_blocks/products/price.rb +0 -18
  232. data/app/models/spree/page_blocks/products/quantity_selector.rb +0 -20
  233. data/app/models/spree/page_blocks/products/share.rb +0 -8
  234. data/app/models/spree/page_blocks/products/title.rb +0 -19
  235. data/app/models/spree/page_blocks/products/variant_picker.rb +0 -13
  236. data/app/models/spree/page_blocks/subheading.rb +0 -17
  237. data/app/models/spree/page_blocks/text.rb +0 -16
  238. data/app/models/spree/page_link.rb +0 -60
  239. data/app/models/spree/page_section.rb +0 -222
  240. data/app/models/spree/page_sections/announcement_bar.rb +0 -28
  241. data/app/models/spree/page_sections/breadcrumbs.rb +0 -12
  242. data/app/models/spree/page_sections/collection_banner.rb +0 -18
  243. data/app/models/spree/page_sections/custom_code.rb +0 -11
  244. data/app/models/spree/page_sections/featured_posts.rb +0 -45
  245. data/app/models/spree/page_sections/featured_product.rb +0 -50
  246. data/app/models/spree/page_sections/featured_taxon.rb +0 -90
  247. data/app/models/spree/page_sections/featured_taxons.rb +0 -45
  248. data/app/models/spree/page_sections/footer.rb +0 -101
  249. data/app/models/spree/page_sections/header.rb +0 -62
  250. data/app/models/spree/page_sections/image_banner.rb +0 -55
  251. data/app/models/spree/page_sections/image_with_text.rb +0 -65
  252. data/app/models/spree/page_sections/main_password_footer.rb +0 -18
  253. data/app/models/spree/page_sections/main_password_header.rb +0 -20
  254. data/app/models/spree/page_sections/newsletter.rb +0 -54
  255. data/app/models/spree/page_sections/page_title.rb +0 -19
  256. data/app/models/spree/page_sections/post_details.rb +0 -19
  257. data/app/models/spree/page_sections/post_grid.rb +0 -19
  258. data/app/models/spree/page_sections/product_details.rb +0 -53
  259. data/app/models/spree/page_sections/product_grid.rb +0 -13
  260. data/app/models/spree/page_sections/related_products.rb +0 -58
  261. data/app/models/spree/page_sections/rich_text.rb +0 -31
  262. data/app/models/spree/page_sections/taxon_banner.rb +0 -18
  263. data/app/models/spree/page_sections/taxon_grid.rb +0 -17
  264. data/app/models/spree/page_sections/video.rb +0 -107
  265. data/app/models/spree/pages/account.rb +0 -19
  266. data/app/models/spree/pages/cart.rb +0 -19
  267. data/app/models/spree/pages/checkout.rb +0 -15
  268. data/app/models/spree/pages/custom.rb +0 -38
  269. data/app/models/spree/pages/homepage.rb +0 -72
  270. data/app/models/spree/pages/login.rb +0 -19
  271. data/app/models/spree/pages/password.rb +0 -59
  272. data/app/models/spree/pages/post.rb +0 -27
  273. data/app/models/spree/pages/post_list.rb +0 -36
  274. data/app/models/spree/pages/product_details.rb +0 -30
  275. data/app/models/spree/pages/search_results.rb +0 -43
  276. data/app/models/spree/pages/shop_all.rb +0 -40
  277. data/app/models/spree/pages/taxon.rb +0 -29
  278. data/app/models/spree/pages/taxon_list.rb +0 -41
  279. data/app/models/spree/pages/wishlist.rb +0 -15
  280. data/app/models/spree/theme.rb +0 -233
  281. data/app/models/spree/themes/default.rb +0 -97
  282. data/app/presenters/spree/csv/formula_sanitizer.rb +0 -28
  283. data/app/services/spree/taxons/touch_featured_sections.rb +0 -21
  284. data/db/migrate/20250120094216_create_page_builder_models.rb +0 -78
  285. data/db/migrate/20250305121352_remove_page_builder_indices.rb +0 -11
  286. data/db/migrate/20250825175217_add_missing_page_builder_indexes.rb +0 -7
  287. data/db/migrate/20250913130044_add_page_links_counter_cache_to_spree_stores.rb +0 -10
  288. data/lib/generators/spree/dummy/templates/initializers/devise.rb +0 -3
  289. data/lib/generators/spree/install/install_generator.rb +0 -219
  290. data/lib/generators/spree/install/templates/config/initializers/spree.rb +0 -126
  291. data/lib/spree/core/webhooks.rb +0 -21
  292. data/lib/spree/testing_support/factories/page_block_factory.rb +0 -22
  293. data/lib/spree/testing_support/factories/page_factory.rb +0 -33
  294. data/lib/spree/testing_support/factories/page_link_factory.rb +0 -7
  295. data/lib/spree/testing_support/factories/page_section_factory.rb +0 -27
  296. data/lib/spree/testing_support/factories/theme_factory.rb +0 -14
@@ -1,53 +0,0 @@
1
- module Spree
2
- module HasPageLinks
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- has_many :links, -> { order(:position).includes(:linkable) }, class_name: 'Spree::PageLink', as: :parent, dependent: :destroy, inverse_of: :parent
7
- alias page_links links
8
-
9
- after_create :create_default_links, unless: :do_not_create_links
10
-
11
- attribute :do_not_create_links, :boolean, default: false
12
- attr_accessor :default_links
13
-
14
- def allowed_linkable_types
15
- [
16
- [Spree.t(:page), 'Spree::Page'],
17
- [Spree.t(:product), 'Spree::Product'],
18
- [Spree.t(:post), 'Spree::Post'],
19
- [Spree.t(:taxon), 'Spree::Taxon'],
20
- [Spree.t(:policy), 'Spree::Policy'],
21
- [Spree.t(:url), nil]
22
- ]
23
- end
24
-
25
- def default_linkable_type
26
- 'Spree::Page'
27
- end
28
-
29
- def theme_or_parent
30
- theme.preview? ? theme.parent : theme
31
- end
32
-
33
- def default_linkable_resource
34
- @default_linkable_resource ||= theme_or_parent.pages.find_by(type: 'Spree::Pages::Homepage')
35
- end
36
-
37
- def default_links
38
- @default_links.presence || []
39
- end
40
-
41
- def links_available?
42
- true
43
- end
44
-
45
- def create_default_links
46
- default_links.each do |link|
47
- link.parent = self
48
- link.save!
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,188 +0,0 @@
1
- module Spree
2
- class Page < Spree.base_class
3
- include Spree::Previewable
4
- include Spree::Linkable
5
-
6
- #
7
- # Magic methods
8
- #
9
- extend FriendlyId
10
- friendly_id :slug_candidates, use: [:slugged, :scoped, :history], scope: :pageable
11
- acts_as_paranoid
12
-
13
- #
14
- # Associations
15
- #
16
- belongs_to :pageable, polymorphic: true # this can be either Store or Theme
17
- has_many :sections, -> { order(position: :asc) }, class_name: 'Spree::PageSection', dependent: :destroy_async, as: :pageable
18
- alias page_sections sections
19
-
20
- #
21
- # Validations
22
- #
23
- validates :name, presence: true
24
- validates :pageable, presence: true
25
- validates :slug, uniqueness: { scope: :pageable, conditions: -> { where(deleted_at: nil).where.not(slug: nil) } }
26
-
27
- #
28
- # Callbacks
29
- #
30
- before_validation :set_name
31
- after_create :create_default_sections, unless: :duplicating
32
-
33
- #
34
- # Scopes
35
- #
36
- scope :linkable, lambda {
37
- where(type: [
38
- 'Spree::Pages::Homepage',
39
- 'Spree::Pages::ShopAll',
40
- 'Spree::Pages::PostList',
41
- 'Spree::Pages::Custom',
42
- 'Spree::Pages::Account',
43
- 'Spree::Pages::Login'
44
- ])
45
- }
46
- scope :product_details, -> { where(type: 'Spree::Pages::ProductDetails') }
47
- scope :standard, -> { where.not(type: 'Spree::Pages::Custom') }
48
- scope :custom, -> { where(type: 'Spree::Pages::Custom') }
49
-
50
- #
51
- # Virtual attributes
52
- #
53
- attribute :duplicating, :boolean, default: false
54
-
55
- def icon_name
56
- 'file-earmark-richtext'
57
- end
58
-
59
- def store
60
- if pageable.is_a?(Spree::Store)
61
- pageable
62
- else
63
- pageable.store
64
- end
65
- end
66
-
67
- def create_preview
68
- return self if preview? # no need to create a preview for the preview
69
-
70
- ActiveRecord::Base.connected_to(role: :writing) do
71
- ApplicationRecord.transaction do
72
- new_preview = dup
73
- new_preview.parent = self
74
- new_preview.duplicating = true
75
- new_preview.save!
76
-
77
- sections.includes(:links, { asset_attachment: :blob }, { blocks: [:rich_text_text, :links] }).each do |section|
78
- section.deep_clone(new_preview)
79
- end
80
-
81
- new_preview
82
- end
83
- end
84
- end
85
-
86
- # Promotes the page preview to the main page
87
- def promote
88
- return unless preview?
89
-
90
- ApplicationRecord.transaction do
91
- old_page = parent
92
- old_page.page_links.update_all(linkable_id: id)
93
- update(parent: nil) # clear reference to the old page
94
- Spree::Page.find(old_page.id).destroy # destroy the old page with their other previews, etc.
95
- end
96
- end
97
-
98
- def default_sections
99
- []
100
- end
101
-
102
- def customizable?
103
- false
104
- end
105
-
106
- def linkable?
107
- false
108
- end
109
-
110
- def layout_sections?
111
- true
112
- end
113
-
114
- def preview_url(theme_preview = nil, page_preview = nil)
115
- return if page_builder_url.blank?
116
-
117
- "#{page_builder_url}?#{url_query_params(theme_preview, page_preview).to_query}"
118
- end
119
-
120
- def display_name
121
- if custom?
122
- name
123
- else
124
- name.titleize
125
- end
126
- end
127
-
128
- def custom?
129
- type == 'Spree::Pages::Custom'
130
- end
131
-
132
- def duplicate(target_pageable)
133
- duplicated_page = dup
134
- duplicated_page.duplicating = true
135
- duplicated_page.pageable = target_pageable
136
- duplicated_page.save!
137
-
138
- sections_scope = sections.includes(:links, :blocks, { asset_attachment: :blob },
139
- { blocks: [:rich_text_text, :links, { asset_attachment: :blob }] })
140
- sections_scope.each { |section| section.deep_clone(duplicated_page) }
141
-
142
- duplicated_page
143
- end
144
-
145
- def theme
146
- @theme ||= if pageable.is_a?(Spree::Theme)
147
- pageable
148
- else
149
- pageable.default_theme
150
- end
151
- end
152
-
153
- private
154
-
155
- def create_default_sections
156
- default_sections.each do |section|
157
- section.pageable = self
158
- section.save!
159
- end
160
- end
161
-
162
- def url_query_params(theme_preview, page_preview)
163
- theme_preview_cache = theme_preview.updated_at.to_i.to_s + rand(999_999).to_s if theme_preview
164
-
165
- {
166
- theme_id: theme.id,
167
- page_preview_id: page_preview&.id,
168
- theme_preview_id: theme_preview&.id,
169
- theme_preview_cache: theme_preview_cache
170
- }
171
- end
172
-
173
- def set_name
174
- return if custom?
175
- return if name.present?
176
-
177
- self.name = self.class.name.demodulize
178
- end
179
-
180
- def should_generate_new_friendly_id?
181
- name_changed? && custom?
182
- end
183
-
184
- def page_builder_url_exists?(path)
185
- Spree::Core::Engine.routes.url_helpers.respond_to?(path)
186
- end
187
- end
188
- end
@@ -1,73 +0,0 @@
1
- module Spree
2
- class PageBlock < Spree.base_class
3
- include Spree::HasPageLinks
4
-
5
- #
6
- # Magic methods
7
- #
8
- acts_as_paranoid
9
- acts_as_list scope: :section
10
-
11
- #
12
- # Associations
13
- #
14
- belongs_to :section, class_name: 'Spree::PageSection', inverse_of: :blocks, touch: true
15
- delegate :store, :theme, to: :section
16
-
17
- #
18
- # Rich Text
19
- #
20
- has_rich_text :text
21
-
22
- #
23
- # Attachments
24
- #
25
- has_one_attached :asset, service: Spree.public_storage_service_name
26
-
27
- #
28
- # Validations
29
- #
30
- validates :section, :type, :name, presence: true
31
- validates :asset, content_type: Rails.application.config.active_storage.web_image_content_types
32
-
33
- #
34
- # Callbacks
35
- #
36
- before_validation :set_name_from_type, on: :create
37
-
38
- #
39
- # Preferences
40
- #
41
- TEXT_ALIGNMENT_DEFAULT = 'left'
42
- CONTAINER_ALIGNMENT_DEFAULT = 'left'
43
- SIZE_DEFAULT = 'medium'
44
- WIDTH_DESKTOP_DEFAULT = 100
45
- TOP_PADDING_DEFAULT = 0
46
- BOTTOM_PADDING_DEFAULT = 0
47
-
48
- preference :text_alignment, :string, default: -> { self.class::TEXT_ALIGNMENT_DEFAULT if defined?(self.class::TEXT_ALIGNMENT_DEFAULT) }
49
- preference :container_alignment, :string, default: -> { self.class::CONTAINER_ALIGNMENT_DEFAULT if defined?(self.class::CONTAINER_ALIGNMENT_DEFAULT) }
50
- preference :size, :string, default: -> { self.class::SIZE_DEFAULT if defined?(self.class::SIZE_DEFAULT) }
51
- preference :width_desktop, :integer, default: -> { self.class::WIDTH_DESKTOP_DEFAULT if defined?(self.class::WIDTH_DESKTOP_DEFAULT) }
52
- preference :top_padding, :integer, default: -> { self.class::TOP_PADDING_DEFAULT if defined?(self.class::TOP_PADDING_DEFAULT) }
53
- preference :bottom_padding, :integer, default: -> { self.class::BOTTOM_PADDING_DEFAULT if defined?(self.class::BOTTOM_PADDING_DEFAULT) }
54
-
55
- def display_name
56
- name
57
- end
58
-
59
- def form_partial_name
60
- type.demodulize.underscore
61
- end
62
-
63
- def icon_name
64
- 'fullscreen'
65
- end
66
-
67
- private
68
-
69
- def set_name_from_type
70
- self.name ||= type.demodulize.titleize
71
- end
72
- end
73
- end
@@ -1,29 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class Buttons < Spree::PageBlock
4
- include Spree::HasOneLink
5
-
6
- TEXT_ALIGNMENT_DEFAULT = 'center'
7
-
8
- preference :button_style_1, :string, default: 'primary'
9
- preference :background_color, :string
10
- preference :button_background_color, :string
11
- preference :button_text_color, :string
12
-
13
- # Without link there is no purpose of the button.
14
- def link_destroyed(_link)
15
- return unless page_links_count.zero?
16
-
17
- destroy
18
- end
19
-
20
- def display_name
21
- Spree.t('page_blocks.buttons.display_name')
22
- end
23
-
24
- def icon_name
25
- 'click'
26
- end
27
- end
28
- end
29
- end
@@ -1,18 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class Heading < Spree::PageBlock
4
- SIZE_DEFAULT = 'large'
5
-
6
- preference :text_color, :string
7
- preference :background_color, :string
8
-
9
- def icon_name
10
- 'heading'
11
- end
12
-
13
- def display_name
14
- text.to_plain_text.truncate(30)
15
- end
16
- end
17
- end
18
- end
@@ -1,20 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class Image < Spree::PageBlock
4
- include Spree::HasImageAltText
5
-
6
- alias image asset
7
-
8
- TOP_PADDING_DEFAULT = 20
9
- BOTTOM_PADDING_DEFAULT = 20
10
-
11
- preference :height, :integer, default: 64
12
- preference :mobile_height, :integer, default: 32
13
- preference :image_alt, :string
14
-
15
- def icon_name
16
- 'photo'
17
- end
18
- end
19
- end
20
- end
@@ -1,21 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class Link < Spree::PageBlock
4
- include Spree::HasOneLink
5
-
6
- def icon_name
7
- 'menu-2'
8
- end
9
-
10
- def display_name
11
- link&.label || Spree.t('page_blocks.link.display_name')
12
- end
13
-
14
- def link_destroyed(_link)
15
- return unless page_links_count.zero?
16
-
17
- destroy
18
- end
19
- end
20
- end
21
- end
@@ -1,33 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class MegaNav < Spree::PageBlock
4
- include Spree::HasPageLinks
5
-
6
- has_one :link, ->(ps) { ps.links.where(position: 1) }, class_name: 'Spree::PageLink', as: :parent, dependent: :destroy, inverse_of: :parent
7
- accepts_nested_attributes_for :link
8
-
9
- preference :featured_taxon_id, :string, default: ''
10
-
11
- def featured_taxon
12
- store.taxons.find_by(id: preferred_featured_taxon_id) if preferred_featured_taxon_id.present?
13
- end
14
-
15
- def icon_name
16
- 'layout-navbar-expand'
17
- end
18
-
19
- def display_name
20
- link&.label || Spree.t(:mega_nav)
21
- end
22
-
23
- def default_links
24
- @default_links.presence || [
25
- Spree::PageLink.new(
26
- label: Spree.t(:shop_all),
27
- linkable: theme_or_parent.pages.find_by(type: 'Spree::Pages::ShopAll')
28
- ),
29
- ]
30
- end
31
- end
32
- end
33
- end
@@ -1,32 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class MegaNavWithSubcategories < Spree::PageBlock
4
- preference :taxon_id, :string, default: ''
5
- preference :featured_taxon_id, :string, default: ''
6
-
7
- before_validation :make_taxon_id_valid
8
-
9
- def taxon
10
- store.taxons.find_by(id: preferred_taxon_id) if preferred_taxon_id.present?
11
- end
12
-
13
- def featured_taxon
14
- store.taxons.find_by(id: preferred_featured_taxon_id) if preferred_featured_taxon_id.present?
15
- end
16
-
17
- def icon_name
18
- 'category'
19
- end
20
-
21
- def display_name
22
- taxon&.name || Spree.t(:mega_nav_with_subcategories)
23
- end
24
-
25
- private
26
-
27
- def make_taxon_id_valid
28
- self.preferred_taxon_id = preferred_taxon_id.presence || store.taxons.where(depth: 1).first&.id
29
- end
30
- end
31
- end
32
- end
@@ -1,18 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class Metafields < Spree::PageBlock
4
- RESOURCE_TYPE_DEFAULT = 'Spree::Product'
5
-
6
- preference :resource_type, :string, default: -> { self.class::RESOURCE_TYPE_DEFAULT if defined?(self.class::RESOURCE_TYPE_DEFAULT) }
7
- preference :metafield_definition_ids, :array, default: -> { available_metafield_definitions.pluck(:id) }
8
-
9
- def icon_name
10
- 'list'
11
- end
12
-
13
- def available_metafield_definitions
14
- @available_metafield_definitions ||= Spree::MetafieldDefinition.where(resource_type: preferred_resource_type).available_on_front_end
15
- end
16
- end
17
- end
18
- end
@@ -1,15 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class Nav < Spree::PageBlock
4
- preference :label, :string, default: Spree.t('page_blocks.nav.label_default')
5
-
6
- def icon_name
7
- 'menu-2'
8
- end
9
-
10
- def display_name
11
- preferred_label
12
- end
13
- end
14
- end
15
- end
@@ -1,18 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class NewsletterForm < Spree::PageBlock
4
- preference :button_text, :string, default: Spree.t('page_blocks.newsletter_form.button_text_default')
5
- preference :button_text_color, :string
6
- preference :button_background_color, :string
7
- preference :button_style, :string, default: 'primary'
8
- preference :placeholder, :string, default: Spree.t('page_blocks.newsletter_form.placeholder_default')
9
- preference :justify, :string, default: 'center'
10
-
11
- validates :preferred_button_style, inclusion: { in: ['primary', 'secondary'] }
12
-
13
- def icon_name
14
- 'forms'
15
- end
16
- end
17
- end
18
- end
@@ -1,15 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- module Products
4
- class Brand < Spree::PageBlocks::Heading
5
- preference :text_color, :string
6
-
7
- SIZE_DEFAULT = 'medium'
8
-
9
- def display_name
10
- Spree.t(:brand)
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,24 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- module Products
4
- class BuyButtons < Spree::PageBlock
5
- TOP_PADDING_DEFAULT = 0
6
- BOTTOM_PADDING_DEFAULT = 20
7
-
8
- preference :text_color, :string
9
-
10
- def icon_name
11
- 'shopping-cart-plus'
12
- end
13
-
14
- def display_name
15
- Spree.t('page_blocks.products.buy_buttons.display_name')
16
- end
17
-
18
- def form_partial_name
19
- 'products/buy_buttons'
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,18 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- module Products
4
- class Description < Spree::PageBlocks::Text
5
- TOP_PADDING_DEFAULT = 0
6
- BOTTOM_PADDING_DEFAULT = 20
7
-
8
- def form_partial_name
9
- 'products/description'
10
- end
11
-
12
- def display_name
13
- I18n.t('activerecord.attributes.spree/product.description')
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,18 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- module Products
4
- class Price < Spree::PageBlocks::Text
5
- TOP_PADDING_DEFAULT = 16
6
- BOTTOM_PADDING_DEFAULT = 16
7
-
8
- def icon_name
9
- 'cash'
10
- end
11
-
12
- def display_name
13
- Spree.t(:price)
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,20 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- module Products
4
- class QuantitySelector < Spree::PageBlock
5
- TOP_PADDING_DEFAULT = 0
6
- BOTTOM_PADDING_DEFAULT = 20
7
-
8
- preference :text_color, :string
9
-
10
- def icon_name
11
- 'plus-minus'
12
- end
13
-
14
- def form_partial_name
15
- 'products/quantity_selector'
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,8 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- module Products
4
- class Share < Spree::PageBlocks::Text
5
- end
6
- end
7
- end
8
- end
@@ -1,19 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- module Products
4
- class Title < Spree::PageBlocks::Heading
5
- TOP_PADDING_DEFAULT = 16
6
-
7
- preference :text_color, :string
8
-
9
- def display_name
10
- I18n.t('activerecord.attributes.spree/product.name')
11
- end
12
-
13
- def icon_name
14
- 'h-1'
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,13 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- module Products
4
- class VariantPicker < Spree::PageBlock
5
- preference :text_color, :string
6
-
7
- def icon_name
8
- 'list-details'
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,17 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class Subheading < Spree::PageBlock
4
- SIZE_DEFAULT = 'small'
5
-
6
- preference :text_color, :string
7
-
8
- def icon_name
9
- 'h2'
10
- end
11
-
12
- def display_name
13
- text.to_plain_text.truncate(30)
14
- end
15
- end
16
- end
17
- end