spree_core 4.5.5 → 4.6.0

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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/app/finders/spree/option_values/find_available.rb +1 -1
  3. data/app/finders/spree/product_properties/find_available.rb +1 -1
  4. data/app/finders/spree/products/find.rb +20 -12
  5. data/app/finders/spree/taxons/find.rb +10 -7
  6. data/app/helpers/spree/base_helper.rb +2 -2
  7. data/app/models/concerns/spree/product_scopes.rb +27 -23
  8. data/app/models/concerns/spree/translatable_resource.rb +25 -0
  9. data/app/models/concerns/spree/translatable_resource_scopes.rb +24 -0
  10. data/app/models/concerns/spree/translatable_resource_slug.rb +17 -0
  11. data/app/models/spree/address.rb +1 -1
  12. data/app/models/spree/asset.rb +1 -1
  13. data/app/models/spree/base.rb +1 -0
  14. data/app/models/spree/calculator/default_tax.rb +1 -1
  15. data/app/models/spree/cms_page.rb +1 -1
  16. data/app/models/spree/cms_section.rb +1 -1
  17. data/app/models/spree/credit_card.rb +1 -1
  18. data/app/models/spree/customer_return.rb +2 -2
  19. data/app/models/spree/data_feed/google.rb +15 -0
  20. data/app/models/spree/data_feed.rb +40 -0
  21. data/app/models/spree/line_item.rb +1 -1
  22. data/app/models/spree/option_type.rb +5 -1
  23. data/app/models/spree/option_value.rb +5 -1
  24. data/app/models/spree/order/store_credit.rb +0 -8
  25. data/app/models/spree/order.rb +3 -3
  26. data/app/models/spree/payment.rb +3 -3
  27. data/app/models/spree/payment_method.rb +1 -1
  28. data/app/models/spree/payment_source.rb +1 -1
  29. data/app/models/spree/price.rb +1 -1
  30. data/app/models/spree/product.rb +44 -13
  31. data/app/models/spree/product_property.rb +12 -3
  32. data/app/models/spree/promotion.rb +2 -2
  33. data/app/models/spree/property.rb +8 -2
  34. data/app/models/spree/prototype.rb +1 -1
  35. data/app/models/spree/refund.rb +1 -1
  36. data/app/models/spree/reimbursement.rb +1 -1
  37. data/app/models/spree/return_authorization.rb +1 -1
  38. data/app/models/spree/shipment.rb +5 -5
  39. data/app/models/spree/shipping_method.rb +1 -1
  40. data/app/models/spree/stock/estimator.rb +1 -1
  41. data/app/models/spree/stock_item.rb +1 -1
  42. data/app/models/spree/stock_transfer.rb +3 -3
  43. data/app/models/spree/store.rb +20 -1
  44. data/app/models/spree/store_credit.rb +1 -1
  45. data/app/models/spree/taxon.rb +23 -7
  46. data/app/models/spree/taxonomy.rb +5 -1
  47. data/app/models/spree/variant.rb +6 -9
  48. data/app/services/spree/data_feeds/google/optional_attributes.rb +23 -0
  49. data/app/services/spree/data_feeds/google/optional_sub_attributes.rb +21 -0
  50. data/app/services/spree/data_feeds/google/products_list.rb +14 -0
  51. data/app/services/spree/data_feeds/google/required_attributes.rb +67 -0
  52. data/app/services/spree/data_feeds/google/rss.rb +107 -0
  53. data/app/sorters/spree/products/sort.rb +23 -0
  54. data/brakeman.ignore +326 -18
  55. data/config/initializers/friendly_id.rb +2 -0
  56. data/config/initializers/mobility.rb +18 -0
  57. data/config/locales/en.yml +1 -0
  58. data/db/migrate/20220706112554_create_product_name_and_description_translations_for_mobility_table_backend.rb +27 -0
  59. data/db/migrate/20220715083542_create_spree_product_translations_for_mobility.rb +7 -0
  60. data/db/migrate/20220715120222_change_product_name_null_to_true.rb +5 -0
  61. data/db/migrate/20220718100743_create_spree_taxon_name_and_description_translations_for_mobility_table_backend.rb +27 -0
  62. data/db/migrate/20220718100948_change_taxon_name_null_to_true.rb +5 -0
  63. data/db/migrate/20220802070609_add_locale_to_friendly_id_slugs.rb +11 -0
  64. data/db/migrate/20220802073225_create_spree_product_slug_translations_for_mobility_table_backend.rb +5 -0
  65. data/db/migrate/20220804073928_transfer_data_to_translatable_tables.rb +66 -0
  66. data/db/migrate/20221215151408_add_selected_locale_to_spree_users.rb +8 -0
  67. data/db/migrate/20221219123957_add_deleted_at_to_product_translations.rb +6 -0
  68. data/db/migrate/20221220133432_add_uniqueness_constraint_to_product_translations.rb +5 -0
  69. data/db/migrate/20221229132350_create_spree_data_feed_settings.rb +14 -0
  70. data/db/migrate/20230103144439_create_option_type_translations.rb +26 -0
  71. data/db/migrate/20230103151034_create_option_value_translations.rb +26 -0
  72. data/db/migrate/20230109084253_create_product_property_translations.rb +25 -0
  73. data/db/migrate/20230109094907_transfer_options_data_to_translatable_tables.rb +58 -0
  74. data/db/migrate/20230109105943_create_property_translations.rb +26 -0
  75. data/db/migrate/20230109110840_transfer_property_data_to_translatable_tables.rb +59 -0
  76. data/db/migrate/20230110142344_backfill_friendly_id_slug_locale.rb +15 -0
  77. data/db/migrate/20230111121534_add_additional_taxon_translation_fields.rb +8 -0
  78. data/db/migrate/20230111122511_transfer_product_and_taxon_data_to_translatable_tables.rb +82 -0
  79. data/db/migrate/20230117115531_create_taxonomy_translations.rb +24 -0
  80. data/db/migrate/20230117120430_allow_null_taxonomy_name.rb +5 -0
  81. data/db/migrate/20230117121303_transfer_taxonomy_data_to_translatable_tables.rb +11 -0
  82. data/db/migrate/20230210142732_create_store_translations.rb +50 -0
  83. data/db/migrate/20230210142849_transfer_store_data_to_translatable_tables.rb +11 -0
  84. data/db/migrate/20230210230434_add_deleted_at_to_store_translations.rb +6 -0
  85. data/db/migrate/20230415155958_rename_data_feed_settings_table.rb +5 -0
  86. data/db/migrate/20230415160828_rename_data_feed_table_columns.rb +7 -0
  87. data/db/migrate/20230415161226_add_indexes_to_data_feeds_table.rb +5 -0
  88. data/db/migrate/20230512094803_rename_data_feeds_column_provider_to_type.rb +5 -0
  89. data/db/migrate/20230514162157_add_index_on_locale_and_permalink_to_spree_taxons.rb +5 -0
  90. data/lib/spree/core/configuration.rb +1 -0
  91. data/lib/spree/core/controller_helpers/locale.rb +26 -2
  92. data/lib/spree/core/dependencies.rb +70 -94
  93. data/lib/spree/core/dependencies_helper.rb +19 -0
  94. data/lib/spree/core/engine.rb +6 -1
  95. data/lib/spree/core/product_duplicator.rb +1 -1
  96. data/lib/spree/core/product_filters.rb +7 -4
  97. data/lib/spree/core/search/base.rb +1 -1
  98. data/lib/spree/core/version.rb +1 -1
  99. data/lib/spree/core.rb +2 -0
  100. data/lib/spree/permitted_attributes.rb +1 -1
  101. data/lib/spree/testing_support/factories/google_data_feed_factory.rb +8 -0
  102. data/lib/spree/testing_support/factories/product_factory.rb +6 -0
  103. data/lib/spree/testing_support/factories/product_translation_factory.rb +6 -0
  104. data/lib/spree/testing_support/factories/store_factory.rb +1 -0
  105. data/lib/spree/testing_support/factories/variant_factory.rb +4 -0
  106. data/lib/spree/translation_migrations.rb +40 -0
  107. data/spree_core.gemspec +3 -0
  108. metadata +93 -6
  109. data/app/models/spree/order_contents.rb +0 -31
@@ -11,6 +11,8 @@ module Spree
11
11
  products = by_price(products)
12
12
  products = by_sku(products)
13
13
 
14
+ products = select_translatable_fields(products)
15
+
14
16
  products.distinct
15
17
  end
16
18
 
@@ -46,6 +48,27 @@ module Spree
46
48
  def sort_by?(field)
47
49
  sort.detect { |s| s[0] == field }
48
50
  end
51
+
52
+ # Add translatable fields to SELECT statement to avoid InvalidColumnReference error (workaround for Mobility issue #596)
53
+ def select_translatable_fields(scope)
54
+ translatable_fields = translatable_sortable_fields
55
+ return scope if translatable_fields.empty?
56
+
57
+ # if sorting by 'sku' or 'price', spree_products.* is already included in SELECT statement
58
+ if sort_by?('sku') || sort_by?('price')
59
+ scope.i18n.select(*translatable_fields)
60
+ else
61
+ scope.i18n.select("#{Product.table_name}.*").select(*translatable_fields)
62
+ end
63
+ end
64
+
65
+ def translatable_sortable_fields
66
+ fields = []
67
+ Product.translatable_fields.each do |field|
68
+ fields << field if sort_by?(field.to_s)
69
+ end
70
+ fields
71
+ end
49
72
  end
50
73
  end
51
74
  end
data/brakeman.ignore CHANGED
@@ -1,20 +1,328 @@
1
1
  {
2
- "ignored_warnings": [
3
- {
4
- "fingerprint": "011b2643940ba1112f7a737e403abe3616ad91764703c801cc35a48d36b721da",
5
- "note": "interpolating table name"
6
- },
7
- {
8
- "fingerprint": "965d3919f811ab63b7b8d62da528559a7f38dc122c57efea7136e7ec5ef1f062",
9
- "note": "interpolating table name"
10
- },
11
- {
12
- "fingerprint": "abd8e90e7a7dfbcdcd6d44fd3fb550598aee6d7a9ef2bb132ad1a18a3c50be30",
13
- "note": "interpolating table name"
14
- },
15
- {
16
- "fingerprint": "efcc57e1a5648d7db59d1beaf5e399d2278539a8667b19c520b305a6ca7e15e8",
17
- "note": "interpolating table name"
18
- }
19
- ]
2
+ "ignored_warnings": [
3
+ {
4
+ "warning_type": "SQL Injection",
5
+ "warning_code": 0,
6
+ "fingerprint": "011b2643940ba1112f7a737e403abe3616ad91764703c801cc35a48d36b721da",
7
+ "check_name": "SQL",
8
+ "message": "Possible SQL injection",
9
+ "file": "app/models/concerns/spree/product_scopes.rb",
10
+ "line": 64,
11
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
12
+ "code": "where(\"#{price_table_name}.amount <= ?\", price)",
13
+ "render_path": null,
14
+ "location": {
15
+ "type": "method",
16
+ "class": "Spree",
17
+ "method": null
18
+ },
19
+ "user_input": "price_table_name",
20
+ "confidence": "Medium",
21
+ "cwe_id": [
22
+ 89
23
+ ],
24
+ "note": "interpolating table name"
25
+ },
26
+ {
27
+ "warning_type": "Redirect",
28
+ "warning_code": 18,
29
+ "fingerprint": "05d3870f66d650510c859a8949d5686b05eb028825083b096d0f65fedf80b118",
30
+ "check_name": "Redirect",
31
+ "message": "Possible unprotected redirect",
32
+ "file": "lib/spree/core/controller_helpers/auth.rb",
33
+ "line": 25,
34
+ "link": "https://brakemanscanner.org/docs/warning_types/redirect/",
35
+ "code": "redirect_to((session[\"spree_user_return_to\"] or (request.env[\"HTTP_REFERER\"] or default)))",
36
+ "render_path": null,
37
+ "location": {
38
+ "type": "method",
39
+ "class": "Spree::Core::ControllerHelpers::Auth",
40
+ "method": "redirect_back_or_default"
41
+ },
42
+ "user_input": "request.env[\"HTTP_REFERER\"]",
43
+ "confidence": "High",
44
+ "cwe_id": [
45
+ 601
46
+ ],
47
+ "note": ""
48
+ },
49
+ {
50
+ "warning_type": "SQL Injection",
51
+ "warning_code": 0,
52
+ "fingerprint": "1c12fcb833b0ddffa07880acb7e604922c0d1d52de598316186241baf16551cd",
53
+ "check_name": "SQL",
54
+ "message": "Possible SQL injection",
55
+ "file": "app/finders/spree/taxons/find.rb",
56
+ "line": 75,
57
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
58
+ "code": "taxons.joins(\"INNER JOIN #{Spree::Taxon.table_name} AS parent_taxon ON parent_taxon.id = #{Spree::Taxon.table_name}.parent_id\").join_translation_table(Taxon, \"parent_taxon\").where([\"#{Taxon.translation_table_alias}.permalink = ?\", parent_permalink])",
59
+ "render_path": null,
60
+ "location": {
61
+ "type": "method",
62
+ "class": "Spree::Taxons::Find",
63
+ "method": "by_parent_permalink"
64
+ },
65
+ "user_input": "Taxon.translation_table_alias",
66
+ "confidence": "Weak",
67
+ "cwe_id": [
68
+ 89
69
+ ],
70
+ "note": ""
71
+ },
72
+ {
73
+ "warning_type": "SQL Injection",
74
+ "warning_code": 0,
75
+ "fingerprint": "1f02952550c2f54d044c9577a45e7ba7c7990c8b8a59d1dac83a96790237f507",
76
+ "check_name": "SQL",
77
+ "message": "Possible SQL injection",
78
+ "file": "app/models/concerns/spree/product_scopes.rb",
79
+ "line": 139,
80
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
81
+ "code": "joins(:properties).join_translation_table(Property).join_translation_table(ProductProperty).where(\"#{ProductProperty.translation_table_alias}.value = ?\", value)",
82
+ "render_path": null,
83
+ "location": {
84
+ "type": "method",
85
+ "class": "Spree::ProductScopes",
86
+ "method": null
87
+ },
88
+ "user_input": "ProductProperty.translation_table_alias",
89
+ "confidence": "Weak",
90
+ "cwe_id": [
91
+ 89
92
+ ],
93
+ "note": ""
94
+ },
95
+ {
96
+ "warning_type": "SQL Injection",
97
+ "warning_code": 0,
98
+ "fingerprint": "7928c0813a0bf084ead091b4554ef6abea9ae9c7167936f5c62da9e328b9f736",
99
+ "check_name": "SQL",
100
+ "message": "Possible SQL injection",
101
+ "file": "app/models/concerns/spree/product_scopes.rb",
102
+ "line": 139,
103
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
104
+ "code": "joins(:properties).join_translation_table(Property).join_translation_table(ProductProperty).where(\"#{ProductProperty.translation_table_alias}.value = ?\", value)",
105
+ "render_path": null,
106
+ "location": {
107
+ "type": "method",
108
+ "class": "Spree",
109
+ "method": null
110
+ },
111
+ "user_input": "ProductProperty.translation_table_alias",
112
+ "confidence": "Weak",
113
+ "cwe_id": [
114
+ 89
115
+ ],
116
+ "note": ""
117
+ },
118
+ {
119
+ "warning_type": "SQL Injection",
120
+ "warning_code": 0,
121
+ "fingerprint": "857c335935a00f584137f31dbcb1a4532af5c8bb5cf53a86058b4af98c6597dc",
122
+ "check_name": "SQL",
123
+ "message": "Possible SQL injection",
124
+ "file": "lib/spree/translation_migrations.rb",
125
+ "line": 21,
126
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
127
+ "code": "ActiveRecord::Base.connection.execute(\"\\n UPDATE #{resource_class.table_name}\\n SET #{resource_class.translatable_fields.map do\n \"#{f}=null\"\n end.join(\", \")};\\n \")",
128
+ "render_path": null,
129
+ "location": {
130
+ "type": "method",
131
+ "class": "Spree::TranslationMigrations",
132
+ "method": "transfer_translation_data"
133
+ },
134
+ "user_input": "resource_class.translatable_fields.map do\n \"#{f}=null\"\n end.join(\", \")",
135
+ "confidence": "Medium",
136
+ "cwe_id": [
137
+ 89
138
+ ],
139
+ "note": ""
140
+ },
141
+ {
142
+ "warning_type": "SQL Injection",
143
+ "warning_code": 0,
144
+ "fingerprint": "965d3919f811ab63b7b8d62da528559a7f38dc122c57efea7136e7ec5ef1f062",
145
+ "check_name": "SQL",
146
+ "message": "Possible SQL injection",
147
+ "file": "app/models/concerns/spree/product_scopes.rb",
148
+ "line": 68,
149
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
150
+ "code": "where(\"#{price_table_name}.amount >= ?\", price)",
151
+ "render_path": null,
152
+ "location": {
153
+ "type": "method",
154
+ "class": "Spree::ProductScopes",
155
+ "method": null
156
+ },
157
+ "user_input": "price_table_name",
158
+ "confidence": "Medium",
159
+ "cwe_id": [
160
+ 89
161
+ ],
162
+ "note": "interpolating table name"
163
+ },
164
+ {
165
+ "warning_type": "SQL Injection",
166
+ "warning_code": 0,
167
+ "fingerprint": "98607ecfb86c2d3c2567390f813861edbc42d6ffa9f482afb7c0b3464eaf6e73",
168
+ "check_name": "SQL",
169
+ "message": "Possible SQL injection",
170
+ "file": "app/models/concerns/spree/translatable_resource_scopes.rb",
171
+ "line": 18,
172
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
173
+ "code": "joins(\"LEFT OUTER JOIN #{translatable_class::Translation.table_name} #{translatable_class.translation_table_alias}\\n ON #{translatable_class.translation_table_alias}.#{\"#{translatable_class.table_name.singularize}_id\"} = #{(translatable_class.table_name or join_on_table_alias)}.id\\n AND #{translatable_class.translation_table_alias}.locale = '#{Mobility.locale}'\")",
174
+ "render_path": null,
175
+ "location": {
176
+ "type": "method",
177
+ "class": "Spree::TranslatableResourceScopes",
178
+ "method": "join_translation_table"
179
+ },
180
+ "user_input": "translatable_class.translation_table_alias",
181
+ "confidence": "Medium",
182
+ "cwe_id": [
183
+ 89
184
+ ],
185
+ "note": ""
186
+ },
187
+ {
188
+ "warning_type": "SQL Injection",
189
+ "warning_code": 0,
190
+ "fingerprint": "abd8e90e7a7dfbcdcd6d44fd3fb550598aee6d7a9ef2bb132ad1a18a3c50be30",
191
+ "check_name": "SQL",
192
+ "message": "Possible SQL injection",
193
+ "file": "app/models/concerns/spree/product_scopes.rb",
194
+ "line": 64,
195
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
196
+ "code": "where(\"#{price_table_name}.amount <= ?\", price)",
197
+ "render_path": null,
198
+ "location": {
199
+ "type": "method",
200
+ "class": "Spree::ProductScopes",
201
+ "method": null
202
+ },
203
+ "user_input": "price_table_name",
204
+ "confidence": "Medium",
205
+ "cwe_id": [
206
+ 89
207
+ ],
208
+ "note": "interpolating table name"
209
+ },
210
+ {
211
+ "warning_type": "SQL Injection",
212
+ "warning_code": 0,
213
+ "fingerprint": "c1c97347a2d74ea41d46519e3bfbd94c511a1bd9c285f3f2a1fa0cb7e624d232",
214
+ "check_name": "SQL",
215
+ "message": "Possible SQL injection",
216
+ "file": "lib/spree/translation_migrations.rb",
217
+ "line": 32,
218
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
219
+ "code": "ActiveRecord::Base.connection.execute(\"\\n UPDATE #{resource_class.table_name}\\n SET (#{resource_class.translatable_fields.join(\", \")}) = #{(\"ROW\" or \"\")}(#{resource_class.translatable_fields.map do\n \"#{resource_class::Translation.table_name}.#{f}\"\n end.join(\", \")})\\n FROM #{resource_class::Translation.table_name}\\n WHERE #{resource_class::Translation.table_name}.#{\"#{resource_class.table_name.singularize}_id\"} = #{resource_class.table_name}.id\\n \")",
220
+ "render_path": null,
221
+ "location": {
222
+ "type": "method",
223
+ "class": "Spree::TranslationMigrations",
224
+ "method": "revert_translation_data_transfer"
225
+ },
226
+ "user_input": "resource_class.translatable_fields.join(\", \")",
227
+ "confidence": "Medium",
228
+ "cwe_id": [
229
+ 89
230
+ ],
231
+ "note": ""
232
+ },
233
+ {
234
+ "warning_type": "SQL Injection",
235
+ "warning_code": 0,
236
+ "fingerprint": "c2bc48d98076b7c4fc3314c6a85f7bd1132efe5fcc346da4d28df7c25f93633f",
237
+ "check_name": "SQL",
238
+ "message": "Possible SQL injection",
239
+ "file": "app/models/spree/variant.rb",
240
+ "line": 126,
241
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
242
+ "code": "joins(:product).join_translation_table(Product).where(\"LOWER(#{Product.translation_table_alias}.name) LIKE LOWER(:query)\\n OR LOWER(sku) LIKE LOWER(:query)\", :query => (\"%#{query}%\"))",
243
+ "render_path": null,
244
+ "location": {
245
+ "type": "method",
246
+ "class": "Spree::Variant",
247
+ "method": "Spree::Variant.product_name_or_sku_cont"
248
+ },
249
+ "user_input": "Product.translation_table_alias",
250
+ "confidence": "Weak",
251
+ "cwe_id": [
252
+ 89
253
+ ],
254
+ "note": ""
255
+ },
256
+ {
257
+ "warning_type": "SQL Injection",
258
+ "warning_code": 0,
259
+ "fingerprint": "ed253ae6b1b4ea3fe3d87d3652380fecab80133319b1ed041d98d163fd16b815",
260
+ "check_name": "SQL",
261
+ "message": "Possible SQL injection",
262
+ "file": "app/finders/spree/taxons/find.rb",
263
+ "line": 71,
264
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
265
+ "code": "taxons.joins(:parent).join_translation_table(Taxon, \"parents_spree_taxons\").where([\"#{Taxon.translation_table_alias}.permalink = ?\", parent_permalink])",
266
+ "render_path": null,
267
+ "location": {
268
+ "type": "method",
269
+ "class": "Spree::Taxons::Find",
270
+ "method": "by_parent_permalink"
271
+ },
272
+ "user_input": "Taxon.translation_table_alias",
273
+ "confidence": "Weak",
274
+ "cwe_id": [
275
+ 89
276
+ ],
277
+ "note": ""
278
+ },
279
+ {
280
+ "warning_type": "SQL Injection",
281
+ "warning_code": 0,
282
+ "fingerprint": "efcc57e1a5648d7db59d1beaf5e399d2278539a8667b19c520b305a6ca7e15e8",
283
+ "check_name": "SQL",
284
+ "message": "Possible SQL injection",
285
+ "file": "app/models/concerns/spree/product_scopes.rb",
286
+ "line": 68,
287
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
288
+ "code": "where(\"#{price_table_name}.amount >= ?\", price)",
289
+ "render_path": null,
290
+ "location": {
291
+ "type": "method",
292
+ "class": "Spree",
293
+ "method": null
294
+ },
295
+ "user_input": "price_table_name",
296
+ "confidence": "Medium",
297
+ "cwe_id": [
298
+ 89
299
+ ],
300
+ "note": "interpolating table name"
301
+ },
302
+ {
303
+ "warning_type": "SQL Injection",
304
+ "warning_code": 0,
305
+ "fingerprint": "f14dd62fac0dd1e9d5532dd5efc770e2eb873a8db80faf366b6295378634754a",
306
+ "check_name": "SQL",
307
+ "message": "Possible SQL injection",
308
+ "file": "lib/spree/translation_migrations.rb",
309
+ "line": 16,
310
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
311
+ "code": "ActiveRecord::Base.connection.execute(\"\\n INSERT INTO #{resource_class::Translation.table_name} (#{resource_class.translatable_fields.join(\", \")}, #{\"#{resource_class.table_name.singularize}_id\"}, locale, created_at, updated_at)\\n SELECT #{resource_class.translatable_fields.join(\", \")}, id, '#{default_locale}' as locale, created_at, updated_at FROM #{resource_class.table_name};\\n \")",
312
+ "render_path": null,
313
+ "location": {
314
+ "type": "method",
315
+ "class": "Spree::TranslationMigrations",
316
+ "method": "transfer_translation_data"
317
+ },
318
+ "user_input": "resource_class.translatable_fields.join(\", \")",
319
+ "confidence": "Medium",
320
+ "cwe_id": [
321
+ 89
322
+ ],
323
+ "note": ""
324
+ }
325
+ ],
326
+ "updated": "2023-03-22 20:11:32 +0100",
327
+ "brakeman_version": "5.4.1"
20
328
  }
@@ -1,3 +1,5 @@
1
+ require 'friendly_id/mobility'
2
+
1
3
  # To learn more, check out the guide:
2
4
  # http://norman.github.io/friendly_id/file.Guide.html
3
5
  FriendlyId.defaults do |config|
@@ -0,0 +1,18 @@
1
+ Mobility.configure do |config|
2
+ config.plugins do
3
+ ransack
4
+ backend :table
5
+ active_record
6
+ reader
7
+ writer
8
+ backend_reader
9
+ query
10
+ cache
11
+ fallbacks
12
+ locale_accessors
13
+ presence
14
+ dirty
15
+ end
16
+
17
+ config.defaults[:fallbacks] = true
18
+ end
@@ -1112,6 +1112,7 @@ en:
1112
1112
  notice_messages:
1113
1113
  icon_removed: Image has been successfully removed
1114
1114
  prices_saved: Prices successfully saved
1115
+ translations_saved: Translations successfully saved
1115
1116
  product_cloned: Product has been cloned
1116
1117
  product_deleted: Product has been deleted
1117
1118
  product_not_cloned: "Product could not be cloned. Reason: %{error}"
@@ -0,0 +1,27 @@
1
+ class CreateProductNameAndDescriptionTranslationsForMobilityTableBackend < ActiveRecord::Migration[6.1]
2
+ def change
3
+ # create translation table only if spree_globalize has not already created it
4
+ if ActiveRecord::Base.connection.table_exists? 'spree_product_translations'
5
+ # manually check for index since Rails if_exists does not always work correctly
6
+ if ActiveRecord::Migration.connection.index_exists?(:spree_product_translations, :spree_product_id)
7
+ remove_index :spree_product_translations, name: "index_spree_product_translations_on_spree_product_id", if_exists: true
8
+ end
9
+ else
10
+ create_table :spree_product_translations do |t|
11
+
12
+ # Translated attribute(s)
13
+ t.string :name
14
+ t.text :description
15
+
16
+ t.string :locale, null: false
17
+ t.references :spree_product, null: false, foreign_key: true, index: false
18
+
19
+ t.timestamps null: false
20
+ end
21
+
22
+ add_index :spree_product_translations, :locale, name: :index_spree_product_translations_on_locale
23
+ end
24
+
25
+ add_index :spree_product_translations, [:spree_product_id, :locale], name: :unique_product_id_per_locale, unique: true
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ class CreateSpreeProductTranslationsForMobility < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :spree_product_translations, :meta_description, :text, if_not_exists: true
4
+ add_column :spree_product_translations, :meta_keywords, :string, if_not_exists: true
5
+ add_column :spree_product_translations, :meta_title, :string, if_not_exists: true
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class ChangeProductNameNullToTrue < ActiveRecord::Migration[6.1]
2
+ def change
3
+ change_column_null :spree_products, :name, true
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ class CreateSpreeTaxonNameAndDescriptionTranslationsForMobilityTableBackend < ActiveRecord::Migration[6.1]
2
+ def change
3
+ # create translation table only if spree_globalize has not already created it
4
+ if ActiveRecord::Base.connection.table_exists? 'spree_taxon_translations'
5
+ # manually check for index since Rails if_exists does not always work correctly
6
+ if ActiveRecord::Migration.connection.index_exists?(:spree_taxon_translations, :spree_taxon_id)
7
+ # replacing this with index on spree_taxon_id and locale
8
+ remove_index :spree_taxon_translations, name: "index_spree_taxon_translations_on_spree_taxon_id", if_exists: true
9
+ end
10
+ else
11
+ create_table :spree_taxon_translations do |t|
12
+ # Translated attribute(s)
13
+ t.string :name
14
+ t.text :description
15
+
16
+ t.string :locale, null: false
17
+ t.references :spree_taxon, null: false, foreign_key: true, index: false
18
+
19
+ t.timestamps null: false
20
+ end
21
+
22
+ add_index :spree_taxon_translations, :locale, name: :index_spree_taxon_translations_on_locale
23
+ end
24
+
25
+ add_index :spree_taxon_translations, [:spree_taxon_id, :locale], name: :index_spree_taxon_translations_on_spree_taxon_id_and_locale, unique: true
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ class ChangeTaxonNameNullToTrue < ActiveRecord::Migration[6.1]
2
+ def change
3
+ change_column_null :spree_taxons, :name, true
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class AddLocaleToFriendlyIdSlugs < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :friendly_id_slugs, :locale, :string, null: :false, after: :scope
4
+
5
+ remove_index :friendly_id_slugs, [:slug, :sluggable_type]
6
+ add_index :friendly_id_slugs, [:slug, :sluggable_type, :locale], length: { slug: 140, sluggable_type: 50, locale: 2 }
7
+ remove_index :friendly_id_slugs, [:slug, :sluggable_type, :scope]
8
+ add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope, :locale], length: { slug: 70, sluggable_type: 50, scope: 70, locale: 2 }, unique: true, name: :index_friendly_id_slugs_unique
9
+ add_index :friendly_id_slugs, :locale
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class CreateSpreeProductSlugTranslationsForMobilityTableBackend < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :spree_product_translations, :slug, :string
4
+ end
5
+ end
@@ -0,0 +1,66 @@
1
+ class TransferDataToTranslatableTables < ActiveRecord::Migration[6.1]
2
+ DEFAULT_LOCALE = 'en'
3
+ PRODUCTS_TABLE = 'spree_products'
4
+ PRODUCT_TRANSLATIONS_TABLE = 'spree_product_translations'
5
+ TAXONS_TABLE = 'spree_taxons'
6
+ TAXON_TRANSLATIONS_TABLE = 'spree_taxon_translations'
7
+
8
+ def up
9
+ # Products
10
+ ActiveRecord::Base.connection.execute("
11
+ INSERT INTO #{PRODUCT_TRANSLATIONS_TABLE} (name, description, locale, spree_product_id, created_at, updated_at, meta_description, meta_keywords, meta_title, slug)
12
+ SELECT name, description, '#{DEFAULT_LOCALE}' as locale, id, created_at, updated_at, meta_description, meta_keywords, meta_title, slug FROM #{PRODUCTS_TABLE}
13
+ ")
14
+ ActiveRecord::Base.connection.execute("
15
+ UPDATE #{PRODUCTS_TABLE}
16
+ SET name=null, description=null, meta_description=null, meta_keywords=null, meta_title=null, slug=null;
17
+ ")
18
+ #Taxons
19
+ ActiveRecord::Base.connection.execute("
20
+ INSERT INTO #{TAXON_TRANSLATIONS_TABLE} (name, description, locale, spree_taxon_id, created_at, updated_at)
21
+ SELECT name, description, '#{DEFAULT_LOCALE}' as locale, id, created_at, updated_at FROM #{TAXONS_TABLE}
22
+ ")
23
+ ActiveRecord::Base.connection.execute("
24
+ UPDATE #{TAXONS_TABLE}
25
+ SET name=null, description=null
26
+ ")
27
+ end
28
+
29
+ def down
30
+ ActiveRecord::Base.connection.execute("
31
+ UPDATE #{PRODUCTS_TABLE} as products
32
+ SET (name,
33
+ description,
34
+ meta_description,
35
+ meta_keywords,
36
+ meta_title,
37
+ slug) =
38
+ (t_products.name,
39
+ t_products.description,
40
+ t_products.meta_description,
41
+ t_products.meta_keywords,
42
+ t_products.meta_title,
43
+ t_products.slug)
44
+ FROM #{PRODUCT_TRANSLATIONS_TABLE} AS t_products
45
+ WHERE t_products.spree_product_id = products.id
46
+ ")
47
+
48
+ ActiveRecord::Base.connection.execute("
49
+ TRUNCATE TABLE #{PRODUCT_TRANSLATIONS_TABLE}
50
+ ")
51
+
52
+ ActiveRecord::Base.connection.execute("
53
+ UPDATE #{TAXONS_TABLE} as taxons
54
+ SET (name,
55
+ description) =
56
+ (t_taxons.name,
57
+ t_taxons.description)
58
+ FROM #{TAXON_TRANSLATIONS_TABLE} AS t_taxons
59
+ WHERE t_taxons.spree_taxon_id = taxons.id
60
+ ")
61
+
62
+ ActiveRecord::Base.connection.execute("
63
+ TRUNCATE TABLE #{TAXON_TRANSLATIONS_TABLE}
64
+ ")
65
+ end
66
+ end
@@ -0,0 +1,8 @@
1
+ class AddSelectedLocaleToSpreeUsers < ActiveRecord::Migration[6.1]
2
+ def change
3
+ if Spree.user_class.present?
4
+ users_table_name = Spree.user_class.table_name
5
+ add_column users_table_name, :selected_locale, :string unless column_exists?(users_table_name, :selected_locale)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ class AddDeletedAtToProductTranslations < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :spree_product_translations, :deleted_at, :datetime
4
+ add_index :spree_product_translations, :deleted_at
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddUniquenessConstraintToProductTranslations < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_index :spree_product_translations, [:locale, :slug], unique: true, name: 'unique_slug_per_locale'
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ class CreateSpreeDataFeedSettings < ActiveRecord::Migration[6.0]
2
+ def change
3
+ create_table :spree_data_feed_settings do |t|
4
+ t.references :spree_store
5
+
6
+ t.string :name
7
+ t.string :provider
8
+ t.string :uuid, unique: true
9
+ t.boolean :enabled, default: true
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ class CreateOptionTypeTranslations < ActiveRecord::Migration[6.1]
2
+ def change
3
+ if ActiveRecord::Base.connection.table_exists? 'spree_option_type_translations'
4
+ # manually check for index since Rails if_exists does not always work correctly
5
+ if ActiveRecord::Migration.connection.index_exists?(:spree_option_type_translations, :spree_option_type_id)
6
+ remove_index :spree_option_type_translations, name: "index_spree_option_type_translations_on_spree_option_type_id", if_exists: true
7
+ end
8
+ else
9
+ create_table :spree_option_type_translations do |t|
10
+
11
+ # Translated attribute(s)
12
+ t.string :name
13
+ t.string :presentation
14
+
15
+ t.string :locale, null: false
16
+ t.references :spree_option_type, null: false, foreign_key: true, index: false
17
+
18
+ t.timestamps
19
+ end
20
+
21
+ add_index :spree_option_type_translations, :locale, name: :index_spree_option_type_translations_on_locale
22
+ end
23
+
24
+ add_index :spree_option_type_translations, [:spree_option_type_id, :locale], name: :unique_option_type_id_per_locale, unique: true
25
+ end
26
+ end