spree_core 5.2.6 → 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 (294) 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 +7 -1
  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/checkout.rb +7 -2
  47. data/app/models/spree/order/emails.rb +3 -11
  48. data/app/models/spree/order/store_credit.rb +5 -1
  49. data/app/models/spree/order.rb +80 -31
  50. data/app/models/spree/order_updater.rb +28 -9
  51. data/app/models/spree/payment/custom_events.rb +37 -0
  52. data/app/models/spree/payment.rb +13 -4
  53. data/app/models/spree/payment_capture_event.rb +0 -4
  54. data/app/models/spree/payment_method.rb +1 -1
  55. data/app/models/spree/permission_sets/default_customer.rb +3 -3
  56. data/app/models/spree/policy.rb +1 -8
  57. data/app/models/spree/post.rb +2 -7
  58. data/app/models/spree/post_category.rb +2 -0
  59. data/app/models/spree/price.rb +8 -6
  60. data/app/models/spree/price_list.rb +263 -0
  61. data/app/models/spree/price_rule.rb +26 -0
  62. data/app/models/spree/price_rules/customer_group_rule.rb +21 -0
  63. data/app/models/spree/price_rules/user_rule.rb +19 -0
  64. data/app/models/spree/price_rules/volume_rule.rb +21 -0
  65. data/app/models/spree/price_rules/zone_rule.rb +19 -0
  66. data/app/models/spree/product.rb +117 -76
  67. data/app/models/spree/product_property.rb +2 -2
  68. data/app/models/spree/promotion/rules/customer_group.rb +22 -0
  69. data/app/models/spree/promotion/rules/user.rb +2 -2
  70. data/app/models/spree/promotion.rb +3 -4
  71. data/app/models/spree/promotion_handler/coupon.rb +3 -3
  72. data/app/models/spree/property.rb +3 -6
  73. data/app/models/spree/prototype.rb +0 -3
  74. data/app/models/spree/refund.rb +2 -3
  75. data/app/models/spree/reimbursement.rb +5 -3
  76. data/app/models/spree/report.rb +7 -1
  77. data/app/models/spree/reports/products_performance.rb +1 -1
  78. data/app/models/spree/reports/sales_total.rb +1 -1
  79. data/app/models/spree/return_authorization.rb +7 -3
  80. data/app/models/spree/return_item.rb +15 -4
  81. data/app/models/spree/shipment/custom_events.rb +47 -0
  82. data/app/models/spree/shipment.rb +12 -5
  83. data/app/models/spree/shipping_category.rb +0 -3
  84. data/app/models/spree/shipping_method.rb +0 -3
  85. data/app/models/spree/stock/quantifier.rb +1 -1
  86. data/app/models/spree/stock_item.rb +2 -0
  87. data/app/models/spree/stock_location.rb +0 -3
  88. data/app/models/spree/stock_movement/custom_events.rb +44 -0
  89. data/app/models/spree/stock_movement.rb +3 -0
  90. data/app/models/spree/stock_transfer.rb +2 -3
  91. data/app/models/spree/store.rb +64 -92
  92. data/app/models/spree/store_credit.rb +3 -4
  93. data/app/models/spree/store_product.rb +14 -0
  94. data/app/models/spree/subscriber.rb +186 -0
  95. data/app/models/spree/tax_category.rb +0 -4
  96. data/app/models/spree/tax_rate.rb +0 -3
  97. data/app/models/spree/taxon.rb +3 -36
  98. data/app/models/spree/taxonomy.rb +0 -3
  99. data/app/models/spree/variant.rb +114 -21
  100. data/app/models/spree/webhook_delivery.rb +60 -0
  101. data/app/models/spree/webhook_endpoint.rb +53 -0
  102. data/app/models/spree/wished_item.rb +2 -4
  103. data/app/models/spree/wishlist.rb +2 -3
  104. data/app/models/spree/zone.rb +0 -9
  105. data/app/paginators/spree/shared/paginate.rb +4 -0
  106. data/app/serializers/spree/events/asset_serializer.rb +22 -0
  107. data/app/serializers/spree/events/base_serializer.rb +61 -0
  108. data/app/serializers/spree/events/customer_return_serializer.rb +20 -0
  109. data/app/serializers/spree/events/digital_link_serializer.rb +20 -0
  110. data/app/serializers/spree/events/digital_serializer.rb +18 -0
  111. data/app/serializers/spree/events/export_serializer.rb +22 -0
  112. data/app/serializers/spree/events/gift_card_batch_serializer.rb +24 -0
  113. data/app/serializers/spree/events/gift_card_serializer.rb +29 -0
  114. data/app/serializers/spree/events/image_serializer.rb +9 -0
  115. data/app/serializers/spree/events/import_row_serializer.rb +23 -0
  116. data/app/serializers/spree/events/import_serializer.rb +24 -0
  117. data/app/serializers/spree/events/invitation_serializer.rb +28 -0
  118. data/app/serializers/spree/events/line_item_serializer.rb +31 -0
  119. data/app/serializers/spree/events/newsletter_subscriber_serializer.rb +21 -0
  120. data/app/serializers/spree/events/order_serializer.rb +39 -0
  121. data/app/serializers/spree/events/payment_serializer.rb +24 -0
  122. data/app/serializers/spree/events/post_category_serializer.rb +20 -0
  123. data/app/serializers/spree/events/post_serializer.rb +26 -0
  124. data/app/serializers/spree/events/price_serializer.rb +22 -0
  125. data/app/serializers/spree/events/product_serializer.rb +24 -0
  126. data/app/serializers/spree/events/promotion_serializer.rb +32 -0
  127. data/app/serializers/spree/events/refund_serializer.rb +23 -0
  128. data/app/serializers/spree/events/reimbursement_serializer.rb +22 -0
  129. data/app/serializers/spree/events/report_serializer.rb +23 -0
  130. data/app/serializers/spree/events/return_authorization_serializer.rb +22 -0
  131. data/app/serializers/spree/events/return_item_serializer.rb +27 -0
  132. data/app/serializers/spree/events/shipment_serializer.rb +24 -0
  133. data/app/serializers/spree/events/stock_item_serializer.rb +22 -0
  134. data/app/serializers/spree/events/stock_movement_serializer.rb +22 -0
  135. data/app/serializers/spree/events/stock_transfer_serializer.rb +22 -0
  136. data/app/serializers/spree/events/store_credit_serializer.rb +30 -0
  137. data/app/serializers/spree/events/user_serializer.rb +18 -0
  138. data/app/serializers/spree/events/variant_serializer.rb +34 -0
  139. data/app/serializers/spree/events/wished_item_serializer.rb +20 -0
  140. data/app/serializers/spree/events/wishlist_serializer.rb +22 -0
  141. data/app/services/spree/addresses/update.rb +1 -1
  142. data/app/services/spree/cart/add_item.rb +1 -1
  143. data/app/services/spree/coupon_codes/coupon_codes_handler.rb +2 -1
  144. data/app/services/spree/data_feeds/google/required_attributes.rb +4 -4
  145. data/app/services/spree/newsletter/verify.rb +5 -0
  146. data/app/services/spree/products/auto_match_taxons.rb +1 -1
  147. data/app/services/spree/seeds/all.rb +1 -1
  148. data/app/services/spree/taxons/add_products.rb +8 -4
  149. data/app/services/spree/taxons/regenerate_products.rb +8 -0
  150. data/app/services/spree/taxons/remove_products.rb +12 -7
  151. data/app/subscribers/spree/event_log_subscriber.rb +64 -0
  152. data/app/subscribers/spree/export_subscriber.rb +26 -0
  153. data/app/subscribers/spree/invitation_email_subscriber.rb +40 -0
  154. data/app/subscribers/spree/product_metrics_subscriber.rb +29 -0
  155. data/app/subscribers/spree/report_subscriber.rb +26 -0
  156. data/config/locales/en.yml +126 -0
  157. data/db/migrate/20251110120000_create_spree_price_lists.rb +22 -0
  158. data/db/migrate/20251110120001_create_spree_price_rules.rb +13 -0
  159. data/db/migrate/20251110120002_add_price_list_id_to_spree_prices.rb +6 -0
  160. data/db/migrate/20251110120003_add_price_list_id_to_spree_line_items.rb +5 -0
  161. data/db/migrate/20251201172118_fix_indexes_on_friendly_id_slugs.rb +8 -0
  162. data/db/migrate/20251214000001_create_spree_webhook_endpoints.rb +19 -0
  163. data/db/migrate/20251214000002_create_spree_webhook_deliveries.rb +23 -0
  164. data/db/migrate/20251222000000_add_performance_indexes_to_spree_adjustments.rb +25 -0
  165. data/db/migrate/20260112000000_fix_spree_prices_unique_indexes.rb +33 -0
  166. data/db/migrate/20260115120000_create_spree_customer_groups.rb +14 -0
  167. data/db/migrate/20260115120001_create_spree_customer_group_users.rb +14 -0
  168. data/db/migrate/20260117140831_remove_not_null_constraint_from_policy_name.rb +5 -0
  169. data/db/migrate/20260118120000_add_statistics_to_store_products.rb +11 -0
  170. data/db/migrate/20260119120000_add_counter_caches_to_spree_products.rb +9 -0
  171. data/db/migrate/20260119170000_add_counter_caches_to_spree_taxons.rb +9 -0
  172. data/db/migrate/20260120120000_add_image_count_to_spree_variants.rb +9 -0
  173. data/lib/generators/spree/dummy/dummy_generator.rb +14 -2
  174. data/lib/spree/core/configuration.rb +1 -0
  175. data/lib/spree/core/controller_helpers/auth.rb +0 -15
  176. data/lib/spree/core/controller_helpers/currency.rb +13 -9
  177. data/lib/spree/core/controller_helpers/search.rb +1 -1
  178. data/lib/spree/core/controller_helpers/store.rb +5 -1
  179. data/lib/spree/core/engine.rb +61 -78
  180. data/lib/spree/core/importer/order.rb +1 -1
  181. data/lib/spree/core/importer/product.rb +1 -1
  182. data/lib/spree/core/preferences/preferable.rb +14 -1
  183. data/lib/spree/core/pricing/context.rb +63 -0
  184. data/lib/spree/core/pricing/resolver.rb +129 -0
  185. data/lib/spree/core/search/base.rb +1 -1
  186. data/lib/spree/core/token_generator.rb +1 -1
  187. data/lib/spree/core/version.rb +1 -1
  188. data/lib/spree/core.rb +42 -47
  189. data/lib/spree/events/adapters/active_support_notifications.rb +112 -0
  190. data/lib/spree/events/adapters/base.rb +193 -0
  191. data/lib/spree/events/registry.rb +99 -0
  192. data/lib/spree/events.rb +240 -0
  193. data/lib/spree/permitted_attributes.rb +13 -2
  194. data/lib/spree/testing_support/common_rake.rb +68 -35
  195. data/lib/spree/testing_support/factories/customer_group_factory.rb +6 -0
  196. data/lib/spree/testing_support/factories/customer_group_user_factory.rb +6 -0
  197. data/lib/spree/testing_support/factories/price_factory.rb +4 -0
  198. data/lib/spree/testing_support/factories/price_list_factory.rb +34 -0
  199. data/lib/spree/testing_support/factories/price_rule_factory.rb +49 -0
  200. data/lib/spree/testing_support/factories/promotion_rule_factory.rb +12 -0
  201. data/lib/spree/testing_support/factories/stock_item_factory.rb +6 -4
  202. data/lib/spree/testing_support/factories/store_product_factory.rb +6 -0
  203. data/lib/spree/testing_support/factories/taxon_factory.rb +0 -1
  204. data/lib/spree/testing_support/factories/webhook_delivery_factory.rb +48 -0
  205. data/lib/spree/testing_support/factories/webhook_endpoint_factory.rb +22 -0
  206. data/lib/spree/testing_support/lifecycle_events.rb +38 -0
  207. data/lib/spree/testing_support/store.rb +4 -2
  208. data/lib/spree/webhooks.rb +22 -0
  209. data/lib/tasks/products.rake +40 -0
  210. data/lib/tasks/taxons.rake +19 -0
  211. data/lib/tasks/variants.rake +18 -0
  212. metadata +112 -114
  213. data/app/jobs/spree/themes/duplicate_components_job.rb +0 -59
  214. data/app/jobs/spree/themes/screenshot_job.rb +0 -81
  215. data/app/models/concerns/spree/has_page_links.rb +0 -53
  216. data/app/models/spree/page.rb +0 -188
  217. data/app/models/spree/page_block.rb +0 -73
  218. data/app/models/spree/page_blocks/buttons.rb +0 -29
  219. data/app/models/spree/page_blocks/heading.rb +0 -18
  220. data/app/models/spree/page_blocks/image.rb +0 -20
  221. data/app/models/spree/page_blocks/link.rb +0 -21
  222. data/app/models/spree/page_blocks/mega_nav.rb +0 -33
  223. data/app/models/spree/page_blocks/mega_nav_with_subcategories.rb +0 -32
  224. data/app/models/spree/page_blocks/metafields.rb +0 -18
  225. data/app/models/spree/page_blocks/nav.rb +0 -15
  226. data/app/models/spree/page_blocks/newsletter_form.rb +0 -18
  227. data/app/models/spree/page_blocks/products/brand.rb +0 -15
  228. data/app/models/spree/page_blocks/products/buy_buttons.rb +0 -24
  229. data/app/models/spree/page_blocks/products/description.rb +0 -18
  230. data/app/models/spree/page_blocks/products/price.rb +0 -18
  231. data/app/models/spree/page_blocks/products/quantity_selector.rb +0 -20
  232. data/app/models/spree/page_blocks/products/share.rb +0 -8
  233. data/app/models/spree/page_blocks/products/title.rb +0 -19
  234. data/app/models/spree/page_blocks/products/variant_picker.rb +0 -13
  235. data/app/models/spree/page_blocks/subheading.rb +0 -17
  236. data/app/models/spree/page_blocks/text.rb +0 -16
  237. data/app/models/spree/page_link.rb +0 -60
  238. data/app/models/spree/page_section.rb +0 -222
  239. data/app/models/spree/page_sections/announcement_bar.rb +0 -28
  240. data/app/models/spree/page_sections/breadcrumbs.rb +0 -12
  241. data/app/models/spree/page_sections/collection_banner.rb +0 -18
  242. data/app/models/spree/page_sections/custom_code.rb +0 -11
  243. data/app/models/spree/page_sections/featured_posts.rb +0 -45
  244. data/app/models/spree/page_sections/featured_product.rb +0 -50
  245. data/app/models/spree/page_sections/featured_taxon.rb +0 -90
  246. data/app/models/spree/page_sections/featured_taxons.rb +0 -45
  247. data/app/models/spree/page_sections/footer.rb +0 -101
  248. data/app/models/spree/page_sections/header.rb +0 -62
  249. data/app/models/spree/page_sections/image_banner.rb +0 -55
  250. data/app/models/spree/page_sections/image_with_text.rb +0 -65
  251. data/app/models/spree/page_sections/main_password_footer.rb +0 -18
  252. data/app/models/spree/page_sections/main_password_header.rb +0 -20
  253. data/app/models/spree/page_sections/newsletter.rb +0 -54
  254. data/app/models/spree/page_sections/page_title.rb +0 -19
  255. data/app/models/spree/page_sections/post_details.rb +0 -19
  256. data/app/models/spree/page_sections/post_grid.rb +0 -19
  257. data/app/models/spree/page_sections/product_details.rb +0 -53
  258. data/app/models/spree/page_sections/product_grid.rb +0 -13
  259. data/app/models/spree/page_sections/related_products.rb +0 -58
  260. data/app/models/spree/page_sections/rich_text.rb +0 -31
  261. data/app/models/spree/page_sections/taxon_banner.rb +0 -18
  262. data/app/models/spree/page_sections/taxon_grid.rb +0 -17
  263. data/app/models/spree/page_sections/video.rb +0 -107
  264. data/app/models/spree/pages/account.rb +0 -19
  265. data/app/models/spree/pages/cart.rb +0 -19
  266. data/app/models/spree/pages/checkout.rb +0 -15
  267. data/app/models/spree/pages/custom.rb +0 -38
  268. data/app/models/spree/pages/homepage.rb +0 -72
  269. data/app/models/spree/pages/login.rb +0 -19
  270. data/app/models/spree/pages/password.rb +0 -59
  271. data/app/models/spree/pages/post.rb +0 -27
  272. data/app/models/spree/pages/post_list.rb +0 -36
  273. data/app/models/spree/pages/product_details.rb +0 -30
  274. data/app/models/spree/pages/search_results.rb +0 -43
  275. data/app/models/spree/pages/shop_all.rb +0 -40
  276. data/app/models/spree/pages/taxon.rb +0 -29
  277. data/app/models/spree/pages/taxon_list.rb +0 -41
  278. data/app/models/spree/pages/wishlist.rb +0 -15
  279. data/app/models/spree/theme.rb +0 -233
  280. data/app/models/spree/themes/default.rb +0 -97
  281. data/app/services/spree/taxons/touch_featured_sections.rb +0 -21
  282. data/db/migrate/20250120094216_create_page_builder_models.rb +0 -78
  283. data/db/migrate/20250305121352_remove_page_builder_indices.rb +0 -11
  284. data/db/migrate/20250825175217_add_missing_page_builder_indexes.rb +0 -7
  285. data/db/migrate/20250913130044_add_page_links_counter_cache_to_spree_stores.rb +0 -10
  286. data/lib/generators/spree/dummy/templates/initializers/devise.rb +0 -3
  287. data/lib/generators/spree/install/install_generator.rb +0 -219
  288. data/lib/generators/spree/install/templates/config/initializers/spree.rb +0 -126
  289. data/lib/spree/core/webhooks.rb +0 -21
  290. data/lib/spree/testing_support/factories/page_block_factory.rb +0 -22
  291. data/lib/spree/testing_support/factories/page_factory.rb +0 -33
  292. data/lib/spree/testing_support/factories/page_link_factory.rb +0 -7
  293. data/lib/spree/testing_support/factories/page_section_factory.rb +0 -27
  294. data/lib/spree/testing_support/factories/theme_factory.rb +0 -14
@@ -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
@@ -1,16 +0,0 @@
1
- module Spree
2
- module PageBlocks
3
- class Text < Spree::PageBlock
4
- preference :text_color, :string
5
- preference :background_color, :string
6
-
7
- def icon_name
8
- 'align-justified'
9
- end
10
-
11
- def display_name
12
- text.to_plain_text.truncate(30)
13
- end
14
- end
15
- end
16
- end
@@ -1,60 +0,0 @@
1
- module Spree
2
- class PageLink < Spree.base_class
3
- #
4
- # Magic methods
5
- #
6
- acts_as_list scope: :parent
7
-
8
- #
9
- # Associations
10
- #
11
- belongs_to :parent, polymorphic: true, touch: true, counter_cache: true # Block or Section
12
- belongs_to :linkable, polymorphic: true, optional: true # Page, Product, etc.
13
- has_one :theme, through: :parent
14
-
15
- #
16
- # Validations
17
- #
18
- validates :label, :parent, presence: true
19
- validates :url, presence: true, unless: :linkable
20
-
21
- #
22
- # Callbacks
23
- #
24
- after_destroy :notify_parent
25
- before_validation :set_label, on: [:create, :update]
26
-
27
- def linkable_url
28
- @linkable_url ||= linkable&.page_builder_url || formatted_url
29
- end
30
-
31
- def formatted_url
32
- return if url.blank?
33
- return url if %w[mailto: tel:].any? { |protocol| url.start_with?(protocol) }
34
-
35
- @formatted_url ||= url.match(/http:\/\/|https:\/\//) ? url : "http://#{url}"
36
- end
37
-
38
- private
39
-
40
- def notify_parent
41
- return unless parent.present?
42
- return unless parent.respond_to?(:link_destroyed)
43
-
44
- parent.link_destroyed(self)
45
- end
46
-
47
- def set_label
48
- return if label.present? && new_record?
49
- return unless linkable_id_changed?
50
-
51
- if linkable.respond_to?(:title)
52
- self.label = linkable.title
53
- elsif linkable.respond_to?(:display_name)
54
- self.label = linkable.display_name
55
- elsif linkable.respond_to?(:name)
56
- self.label = linkable.name
57
- end
58
- end
59
- end
60
- end
@@ -1,222 +0,0 @@
1
- module Spree
2
- class PageSection < Spree.base_class
3
- include Spree::HasPageLinks
4
- #
5
- # Magic methods
6
- #
7
- acts_as_paranoid
8
- acts_as_list scope: [:pageable_type, :pageable_id, { deleted_at: nil }]
9
-
10
- #
11
- # Associations
12
- #
13
- belongs_to :pageable, polymorphic: true, touch: true # this can be either Page or Theme
14
- has_many :blocks, lambda {
15
- order(position: :asc)
16
- }, class_name: 'Spree::PageBlock', dependent: :destroy, inverse_of: :section, foreign_key: :section_id
17
- alias page_blocks blocks
18
- delegate :store, to: :pageable
19
-
20
- #
21
- # Attachments
22
- #
23
- has_one_attached :asset, service: Spree.public_storage_service_name
24
- alias image asset
25
-
26
- #
27
- # Rich Text
28
- #
29
- has_rich_text :text
30
- has_rich_text :description
31
-
32
- #
33
- # Validations
34
- #
35
- validates :name, :pageable, presence: true
36
- validates :asset, content_type: Rails.application.config.active_storage.web_image_content_types
37
-
38
- #
39
- # Callbacks
40
- #
41
- before_validation :set_name, on: :create
42
- after_create :create_blocks, unless: :do_not_create_blocks
43
-
44
- #
45
- # Scopes
46
- #
47
- scope :published, -> { where(pageable_type: 'Spree::Page') }
48
- scope :related_products, -> { where(type: 'Spree::PageSections::RelatedProducts') }
49
-
50
- #
51
- # Preferences
52
- #
53
- TEXT_COLOR_DEFAULT = nil
54
- BACKGROUND_COLOR_DEFAULT = nil
55
- BORDER_COLOR_DEFAULT = nil
56
- TOP_PADDING_DEFAULT = 40
57
- BOTTOM_PADDING_DEFAULT = 40
58
- TOP_BORDER_WIDTH_DEFAULT = 1
59
- BOTTOM_BORDER_WIDTH_DEFAULT = 0
60
-
61
- preference :text_color, :string, default: -> { self.class::TEXT_COLOR_DEFAULT if defined?(self.class::TEXT_COLOR_DEFAULT) }
62
- preference :background_color, :string, default: -> { self.class::BACKGROUND_COLOR_DEFAULT if defined?(self.class::BACKGROUND_COLOR_DEFAULT) }
63
- preference :border_color, :string, default: -> { self.class::BORDER_COLOR_DEFAULT if defined?(self.class::BORDER_COLOR_DEFAULT) }
64
- preference :top_padding, :integer, default: -> { self.class::TOP_PADDING_DEFAULT if defined?(self.class::TOP_PADDING_DEFAULT) }
65
- preference :bottom_padding, :integer, default: -> { self.class::BOTTOM_PADDING_DEFAULT if defined?(self.class::BOTTOM_PADDING_DEFAULT) }
66
- preference :top_border_width, :integer, default: -> { self.class::TOP_BORDER_WIDTH_DEFAULT if defined?(self.class::TOP_BORDER_WIDTH_DEFAULT) }
67
- preference :bottom_border_width, :integer, default: -> { self.class::BOTTOM_BORDER_WIDTH_DEFAULT if defined?(self.class::BOTTOM_BORDER_WIDTH_DEFAULT) }
68
-
69
- #
70
- # Virtual attributes
71
- #
72
- attribute :do_not_create_blocks, :boolean, default: false
73
- attr_accessor :default_blocks
74
-
75
- def to_partial_path
76
- "spree/page_sections/#{type.to_s.demodulize.underscore}"
77
- end
78
-
79
- # this should be overridden in subclasses
80
- def default_blocks
81
- @default_blocks.presence || []
82
- end
83
-
84
- def blocks_available?
85
- false
86
- end
87
-
88
- def available_blocks_to_add
89
- []
90
- end
91
-
92
- def can_sort_blocks?
93
- false
94
- end
95
-
96
- # this should be overridden in subclasses
97
- # content - can be managed by the user
98
- # system - main parts of the page eg. product details, login form
99
- # header - header section
100
- # footer - footer section
101
- def self.role
102
- 'content'
103
- end
104
-
105
- def role
106
- self.class.role
107
- end
108
-
109
- def theme
110
- @theme ||= if pageable.is_a?(Spree::Theme)
111
- pageable
112
- else
113
- pageable.theme
114
- end
115
- end
116
-
117
- def icon_name
118
- 'text-caption'
119
- end
120
-
121
- def can_be_deleted?
122
- role == 'content'
123
- end
124
-
125
- def can_be_sorted?
126
- true
127
- end
128
-
129
- def lazy?
130
- false
131
- end
132
-
133
- def lazy_path(variables)
134
- url_options = variables[:url_options] || {}
135
-
136
- Spree::Core::Engine.routes.url_helpers.page_section_path(self, **url_options)
137
- end
138
-
139
- def rich_text_fields
140
- self.class.rich_text_association_names.map { |rt| rt.to_s.sub('rich_text_', '') }
141
- end
142
-
143
- def copy_rich_text_fields_from(other)
144
- rich_text_fields.each do |field|
145
- send(field).body = other.send(field).body
146
- end
147
- end
148
-
149
- def deep_clone(target)
150
- new_section = type.constantize.new(
151
- preferences: preferences,
152
- position: position,
153
- pageable: target
154
- )
155
- new_section.copy_rich_text_fields_from(self)
156
- new_section.do_not_create_blocks = true
157
- new_section.do_not_create_links = true
158
- new_section.save!
159
-
160
- new_section.asset.attach(asset.blob) if asset.attached?
161
-
162
- blocks.includes(:links, asset_attachment: :blob).each do |block|
163
- new_block = block.type.constantize.new(
164
- preferences: block.preferences,
165
- position: block.position,
166
- section: new_section
167
- )
168
- new_block.do_not_create_links = true
169
- new_block.text = block.text if block.respond_to?(:text) # we need to copy ActionText content
170
- new_block.save!
171
-
172
- new_block.asset.attach(block.asset.blob) if block.asset.attached?
173
-
174
- deep_clone_links(block, new_block)
175
- end
176
-
177
- deep_clone_links(self, new_section)
178
- end
179
-
180
- def deep_clone_links(section_or_block, new_section_or_block)
181
- section_or_block.links.each do |link|
182
- new_link = link.dup
183
- new_link.parent = new_section_or_block
184
- new_link.save!
185
- end
186
- end
187
-
188
- # Turns out #dup doesn't not copy rich text content to the new record.
189
- # https://github.com/rails/rails/issues/36683
190
- def dup
191
- super.tap do |object|
192
- object.copy_rich_text_fields_from(self)
193
- end
194
- end
195
-
196
- def restore_design_settings_to_defaults
197
- restore_preferences_for(design_settings_to_restore)
198
- save
199
- end
200
-
201
- def display_name
202
- name
203
- end
204
-
205
- private
206
-
207
- def design_settings_to_restore
208
- [:text_color, :background_color, :border_color, :top_padding, :bottom_padding, :top_border_width, :bottom_border_width]
209
- end
210
-
211
- def create_blocks
212
- default_blocks.each do |block|
213
- block.section = self
214
- block.save!
215
- end
216
- end
217
-
218
- def set_name
219
- self.name ||= type.to_s.demodulize.titleize
220
- end
221
- end
222
- end
@@ -1,28 +0,0 @@
1
- module Spree
2
- module PageSections
3
- class AnnouncementBar < Spree::PageSection
4
- before_validation :set_default_text, on: :create
5
-
6
- BACKGROUND_COLOR_DEFAULT = '#F5F5F4'
7
- TOP_PADDING_DEFAULT = 8
8
- BOTTOM_PADDING_DEFAULT = 8
9
- TOP_BORDER_WIDTH_DEFAULT = 0
10
-
11
- def self.role
12
- 'header'
13
- end
14
-
15
- def icon_name
16
- 'speakerphone'
17
- end
18
-
19
- private
20
-
21
- def set_default_text
22
- return unless text.blank?
23
-
24
- self.text = Spree.t('page_sections.announcement_bar.default_text')
25
- end
26
- end
27
- end
28
- end
@@ -1,12 +0,0 @@
1
- module Spree
2
- module PageSections
3
- class Breadcrumbs < Spree::PageSection
4
- TOP_PADDING_DEFAULT = 20
5
- BOTTOM_PADDING_DEFAULT = 20
6
-
7
- def icon_name
8
- 'chevron-right'
9
- end
10
- end
11
- end
12
- end
@@ -1,18 +0,0 @@
1
- module Spree
2
- module PageSections
3
- class CollectionBanner < Spree::PageSection
4
- TOP_PADDING_DEFAULT = 20
5
- BOTTOM_PADDING_DEFAULT = 20
6
- TOP_BORDER_WIDTH_DEFAULT = 0
7
- BOTTOM_BORDER_WIDTH_DEFAULT = 1
8
-
9
- def icon_name
10
- 'heading'
11
- end
12
-
13
- def self.role
14
- 'system'
15
- end
16
- end
17
- end
18
- end
@@ -1,11 +0,0 @@
1
- module Spree
2
- module PageSections
3
- class CustomCode < Spree::PageSection
4
- preference :custom_code, :string, default: ''
5
-
6
- def icon_name
7
- 'code'
8
- end
9
- end
10
- end
11
- end
@@ -1,45 +0,0 @@
1
- module Spree
2
- module PageSections
3
- class FeaturedPosts < Spree::PageSection
4
- before_validation :make_heading_size_valid
5
- before_validation :make_max_posts_to_show_valid
6
- before_validation :make_alignment_valid
7
- before_validation :make_posts_to_show_valid
8
-
9
- preference :heading, :string, default: ''
10
- preference :heading_size, :string, default: 'large'
11
- preference :heading_alignment, :string, default: 'left'
12
- preference :description_alignment, :string, default: 'left'
13
- preference :posts_to_show, :string, default: 'newest'
14
- preference :max_posts_to_show, :integer, default: 4
15
-
16
- def icon_name
17
- 'news'
18
- end
19
-
20
- def posts
21
- Spree::Post.published.by_newest.limit(preferred_max_posts_to_show)
22
- end
23
-
24
- private
25
-
26
- def make_posts_to_show_valid
27
- self.preferred_posts_to_show = 'newest' unless %w[newest most_popular].include?(preferred_posts_to_show)
28
- end
29
-
30
- def make_alignment_valid
31
- self.preferred_heading_alignment = 'left' unless %w[left center right].include?(preferred_heading_alignment)
32
- self.preferred_description_alignment = 'left' unless %w[left center right].include?(preferred_description_alignment)
33
- end
34
-
35
- def make_max_posts_to_show_valid
36
- self.preferred_max_posts_to_show = 2 if preferred_max_posts_to_show < 2
37
- self.preferred_max_posts_to_show = 8 if preferred_max_posts_to_show > 8
38
- end
39
-
40
- def make_heading_size_valid
41
- self.preferred_heading_size = 'small' unless %w[small medium large].include?(preferred_heading_size)
42
- end
43
- end
44
- end
45
- end
@@ -1,50 +0,0 @@
1
- module Spree
2
- module PageSections
3
- class FeaturedProduct < Spree::PageSection
4
- preference :product_id, :string, default: ''
5
-
6
- def icon_name
7
- 'star'
8
- end
9
-
10
- def product
11
- return @product if defined?(@product)
12
-
13
- includes = [
14
- { variants: { images: [], prices: [], stock_items: [], stock_locations: [], option_values: :option_type } },
15
- ]
16
-
17
- @product ||= store.products.includes(includes).find_by(id: preferred_product_id)
18
- end
19
-
20
- def vendor_name
21
- return unless defined?(Spree::Vendor)
22
-
23
- @vendor_name ||= product&.vendor&.display_name || 'Brand'
24
- end
25
-
26
- def product_name
27
- product&.name
28
- end
29
-
30
- def default_blocks
31
- [
32
- Spree::PageBlocks::Products::Title.new,
33
- Spree::PageBlocks::Products::Price.new(text: 'Price', preferred_text_alignment: 'left'),
34
- Spree::PageBlocks::Products::VariantPicker.new,
35
- Spree::PageBlocks::Products::QuantitySelector.new,
36
- Spree::PageBlocks::Products::BuyButtons.new,
37
- Spree::PageBlocks::Products::Share.new(text: 'Share')
38
- ]
39
- end
40
-
41
- def blocks_available?
42
- true
43
- end
44
-
45
- def can_sort_blocks?
46
- true
47
- end
48
- end
49
- end
50
- end