spree_core 1.3.3 → 1.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/admin/admin.js.erb +9 -5
- data/app/assets/javascripts/store/product.js.coffee +6 -1
- data/app/assets/stylesheets/store/screen.css.scss +1 -1
- data/app/controllers/spree/admin/images_controller.rb +4 -0
- data/app/controllers/spree/admin/resource_controller.rb +6 -2
- data/app/controllers/spree/orders_controller.rb +1 -1
- data/app/helpers/spree/admin/navigation_helper.rb +3 -1
- data/app/models/spree/classification.rb +3 -0
- data/app/models/spree/credit_card.rb +13 -0
- data/app/models/spree/order.rb +20 -11
- data/app/models/spree/payment.rb +1 -1
- data/app/models/spree/payment/processing.rb +5 -0
- data/app/models/spree/product.rb +1 -1
- data/app/models/spree/product/scopes.rb +5 -8
- data/app/views/spree/admin/adjustments/index.html.erb +2 -2
- data/app/views/spree/admin/payments/_form.html.erb +3 -1
- data/app/views/spree/checkout/edit.html.erb +4 -0
- data/app/views/spree/orders/_line_item.html.erb +5 -3
- data/config/initializers/user_class_extensions.rb +1 -1
- data/config/locales/en.yml +6 -0
- data/config/routes.rb +1 -1
- data/db/migrate/20130626232741_add_cvv_result_code_and_cvv_result_message_to_spree_payments.rb +6 -0
- data/db/migrate/20130628021056_add_unique_index_to_permalink_on_spree_products.rb +5 -0
- data/db/migrate/20130628022817_add_unique_index_to_orders_shipments_and_stock_transfers.rb +6 -0
- data/db/migrate/20130813140619_expand_order_number_size.rb +9 -0
- data/lib/generators/spree/dummy/templates/rails/database.yml +0 -3
- data/lib/spree/core/permalinks.rb +17 -13
- data/lib/spree/core/s3_support.rb +1 -1
- data/lib/spree/core/testing_support/factories/variant_factory.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- data/vendor/assets/javascripts/jquery.validate/additional-methods.min.js +6 -22
- data/vendor/assets/javascripts/jquery.validate/jquery.validate.min.js +6 -45
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ar.js +23 -22
- data/vendor/assets/javascripts/jquery.validate/localization/messages_bg.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ca.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_cs.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_da.js +19 -17
- data/vendor/assets/javascripts/jquery.validate/localization/messages_de.js +19 -18
- data/vendor/assets/javascripts/jquery.validate/localization/messages_el.js +22 -21
- data/vendor/assets/javascripts/jquery.validate/localization/messages_es.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_et.js +23 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_eu.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_fa.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_fi.js +20 -18
- data/vendor/assets/javascripts/jquery.validate/localization/messages_fr.js +44 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_he.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_hr.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_hu.js +21 -18
- data/vendor/assets/javascripts/jquery.validate/localization/messages_it.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ja.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ka.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_kk.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ko.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_lt.js +23 -21
- data/vendor/assets/javascripts/jquery.validate/localization/messages_lv.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_my.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_nl.js +32 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_no.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_pl.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_pt_BR.js +26 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_pt_PT.js +26 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ro.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ru.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_si.js +21 -19
- data/vendor/assets/javascripts/jquery.validate/localization/messages_sk.js +19 -18
- data/vendor/assets/javascripts/jquery.validate/localization/messages_sl.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_sr.js +23 -21
- data/vendor/assets/javascripts/jquery.validate/localization/messages_sv.js +23 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_th.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_tr.js +22 -21
- data/vendor/assets/javascripts/jquery.validate/localization/messages_uk.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_vi.js +22 -20
- data/vendor/assets/javascripts/jquery.validate/localization/messages_zh.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_zh_TW.js +26 -0
- data/vendor/assets/javascripts/jquery.validate/localization/methods_de.js +6 -6
- data/vendor/assets/javascripts/jquery.validate/localization/methods_nl.js +3 -3
- data/vendor/assets/javascripts/jquery.validate/localization/methods_pt.js +3 -3
- metadata +30 -14
- data/app/views/spree/orders/new.html.erb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c5bf35a8b95692aa7ff0d8680f50c4c09fca20c
|
4
|
+
data.tar.gz: bb49344e459351d49fd48e2f611efb632c91df74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cc6f3c95ba0dce27047501a44aa7434479df796de8e30349d929e24bc1566729d915d53cf5e6c7503c157829784b2070f2e37929009d497f75aeb892b3d2ba7
|
7
|
+
data.tar.gz: 357cfcbbe86573ef29d1611cd3260957cb5650827724626b5348d2ef38ea356b30746c317ef4f94b59d448dbfb758b2832c60f3ed5a22e4f29d8d1af45360cae
|
@@ -157,11 +157,11 @@ $(document).ready(function(){
|
|
157
157
|
var target = $(this).data("target");
|
158
158
|
var new_table_row = $(target + ' tr:visible:last').clone();
|
159
159
|
var new_id = new Date().getTime();
|
160
|
-
new_table_row.find("input").each(function () {
|
160
|
+
new_table_row.find("input, select").each(function () {
|
161
161
|
var el = $(this);
|
162
162
|
el.val("");
|
163
|
-
el.attr("id", el.attr("id").replace(/\d+/, new_id))
|
164
|
-
el.attr("name", el.attr("name").replace(/\d+/, new_id))
|
163
|
+
if (typeof el.attr("id") !== 'undefined') el.attr("id", el.attr("id").replace(/\d+/, new_id))
|
164
|
+
if (typeof el.attr("name") !== 'undefined') el.attr("name", el.attr("name").replace(/\d+/, new_id))
|
165
165
|
})
|
166
166
|
// When cloning a new row, set the href of all icons to be an empty "#"
|
167
167
|
// This is so that clicking on them does not perform the actions for the
|
@@ -185,7 +185,9 @@ $(document).ready(function(){
|
|
185
185
|
},
|
186
186
|
dataType: 'script',
|
187
187
|
success: function(response) {
|
188
|
-
el.parents("tr").fadeOut('hide')
|
188
|
+
el.parents("tr").fadeOut('hide', function() {
|
189
|
+
$(this).remove();
|
190
|
+
})
|
189
191
|
},
|
190
192
|
error: function(response, textStatus, errorThrown) {
|
191
193
|
show_flash_error(response.responseText);
|
@@ -199,7 +201,9 @@ $(document).ready(function(){
|
|
199
201
|
el = $(this);
|
200
202
|
el.prev("input[type=hidden]").val("1");
|
201
203
|
el.closest(".fields").hide();
|
202
|
-
if (el.attr("href")) {
|
204
|
+
if (el.attr("href") == '#') {
|
205
|
+
el.parents("tr").fadeOut('hide');
|
206
|
+
}else if (el.attr("href")) {
|
203
207
|
$.ajax({
|
204
208
|
type: 'POST',
|
205
209
|
url: el.attr("href"),
|
@@ -35,8 +35,13 @@ update_variant_price = (variant) ->
|
|
35
35
|
($ '.price.selling').text(variant_price) if variant_price
|
36
36
|
|
37
37
|
$ ->
|
38
|
+
radios = ($ '#product-variants input[type="radio"]')
|
38
39
|
add_image_handlers()
|
39
|
-
|
40
|
+
|
41
|
+
if radios.length > 0
|
42
|
+
show_variant_images radios.eq(0).attr('value')
|
43
|
+
update_variant_price radios.first()
|
44
|
+
|
40
45
|
($ '#product-variants input[type="radio"]').click (event) ->
|
41
46
|
show_variant_images @value
|
42
47
|
update_variant_price ($ this)
|
@@ -300,7 +300,7 @@ mark {background-color: $link_text_color; color: $layout_background_color; font-
|
|
300
300
|
&#link-to-cart {
|
301
301
|
float: right;
|
302
302
|
padding-left: 24px;
|
303
|
-
background: url("cart.png") no-repeat left center;
|
303
|
+
background: asset-url("cart.png", image) no-repeat left center;
|
304
304
|
|
305
305
|
&:hover {
|
306
306
|
border-color: $link_text_color;
|
@@ -70,13 +70,13 @@ class Spree::Admin::ResourceController < Spree::Admin::BaseController
|
|
70
70
|
invoke_callbacks(:destroy, :after)
|
71
71
|
flash[:success] = flash_message_for(@object, :successfully_removed)
|
72
72
|
respond_with(@object) do |format|
|
73
|
-
format.html { redirect_to
|
73
|
+
format.html { redirect_to location_after_destroy }
|
74
74
|
format.js { render :partial => "spree/admin/shared/destroy" }
|
75
75
|
end
|
76
76
|
else
|
77
77
|
invoke_callbacks(:destroy, :fails)
|
78
78
|
respond_with(@object) do |format|
|
79
|
-
format.html { redirect_to
|
79
|
+
format.html { redirect_to location_after_destroy }
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -198,6 +198,10 @@ class Spree::Admin::ResourceController < Spree::Admin::BaseController
|
|
198
198
|
end
|
199
199
|
end
|
200
200
|
|
201
|
+
def location_after_destroy
|
202
|
+
collection_url
|
203
|
+
end
|
204
|
+
|
201
205
|
def location_after_save
|
202
206
|
collection_url
|
203
207
|
end
|
@@ -26,7 +26,7 @@ module Spree
|
|
26
26
|
respond_with(@order) do |format|
|
27
27
|
format.html do
|
28
28
|
if params.has_key?(:checkout)
|
29
|
-
@order.next_transition.run_callbacks
|
29
|
+
@order.next_transition.run_callbacks if @order.cart?
|
30
30
|
redirect_to checkout_state_path(@order.checkout_steps.first)
|
31
31
|
else
|
32
32
|
redirect_to cart_path
|
@@ -143,7 +143,9 @@ module Spree
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def configurations_sidebar_menu_item(link_text, url, options = {})
|
146
|
-
is_active = url.ends_with?(controller.controller_name) ||
|
146
|
+
is_active = url.ends_with?(controller.controller_name) ||
|
147
|
+
url.ends_with?("#{controller.controller_name}/edit") ||
|
148
|
+
url.ends_with?("#{controller.controller_name.singularize}/edit")
|
147
149
|
options.merge!(:class => is_active ? 'active' : nil)
|
148
150
|
content_tag(:li, options) do
|
149
151
|
link_to(link_text, url)
|
@@ -3,5 +3,8 @@ module Spree
|
|
3
3
|
self.table_name = 'spree_products_taxons'
|
4
4
|
belongs_to :product, :class_name => "Spree::Product"
|
5
5
|
belongs_to :taxon, :class_name => "Spree::Taxon"
|
6
|
+
|
7
|
+
# For #3494
|
8
|
+
validates_uniqueness_of :taxon_id, :scope => :product_id, :message => :already_linked
|
6
9
|
end
|
7
10
|
end
|
@@ -28,6 +28,19 @@ module Spree
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
# Some payment gateways, such as USA EPay, only support an ActiveMerchant::Billing::CreditCard
|
32
|
+
# object, rather than an object *like* that. So we need to convert it.
|
33
|
+
def to_active_merchant
|
34
|
+
ActiveMerchant::Billing::CreditCard.new(
|
35
|
+
:number => number,
|
36
|
+
:month => month,
|
37
|
+
:year => year,
|
38
|
+
:verification_value => verification_value,
|
39
|
+
:first_name => first_name,
|
40
|
+
:last_name => last_name
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
31
44
|
# sets self.cc_type while we still have the card number
|
32
45
|
def set_card_type
|
33
46
|
self.cc_type ||= CardDetector.brand?(number)
|
data/app/models/spree/order.rb
CHANGED
@@ -17,7 +17,8 @@ module Spree
|
|
17
17
|
go_to_state :delivery
|
18
18
|
go_to_state :payment, :if => lambda { |order|
|
19
19
|
# Fix for #2191
|
20
|
-
|
20
|
+
# See #3708 also
|
21
|
+
if order.total.to_f <= 0 && order.shipping_method
|
21
22
|
order.create_shipment!
|
22
23
|
order.update_totals
|
23
24
|
end
|
@@ -168,8 +169,13 @@ module Spree
|
|
168
169
|
end
|
169
170
|
|
170
171
|
# Used by the checkout state machine to check for unprocessed payments
|
171
|
-
# The Order should be
|
172
|
+
# The Order should be only be able to proceed to complete if there are unprocessed
|
172
173
|
# payments and there is payment required.
|
174
|
+
#
|
175
|
+
# The reason for this is directly before an order transitions to complete, all
|
176
|
+
# of the order's payments have `process!` called on it (look in order/checkout.rb).
|
177
|
+
# If payment *is* required and there's no payments which haven't already been tried,
|
178
|
+
# then the order cannot be paid for and therefore should not be able to become complete.
|
173
179
|
def has_unprocessed_payments?
|
174
180
|
payments.with_state('checkout').reload.exists?
|
175
181
|
end
|
@@ -340,7 +346,7 @@ module Spree
|
|
340
346
|
def create_shipment!
|
341
347
|
shipping_method(true)
|
342
348
|
if shipment.present?
|
343
|
-
shipment.update_attributes!(:shipping_method => shipping_method)
|
349
|
+
shipment.update_attributes!({:shipping_method => shipping_method, :inventory_units => self.inventory_units}, :without_protection => true)
|
344
350
|
else
|
345
351
|
self.shipments << Shipment.create!({ :order => self,
|
346
352
|
:shipping_method => shipping_method,
|
@@ -383,7 +389,7 @@ module Spree
|
|
383
389
|
|
384
390
|
# update payment and shipment(s) states, and save
|
385
391
|
updater.update_payment_state
|
386
|
-
shipments.each { |shipment| shipment.update!(self) }
|
392
|
+
shipments.reload.each { |shipment| shipment.update!(self) }
|
387
393
|
updater.update_shipment_state
|
388
394
|
save
|
389
395
|
updater.run_hooks
|
@@ -491,8 +497,8 @@ module Spree
|
|
491
497
|
end
|
492
498
|
|
493
499
|
def empty!
|
494
|
-
line_items.destroy_all
|
495
500
|
adjustments.destroy_all
|
501
|
+
line_items.destroy_all
|
496
502
|
end
|
497
503
|
|
498
504
|
# destroy any previous adjustments.
|
@@ -510,12 +516,15 @@ module Spree
|
|
510
516
|
state = "#{name}_state"
|
511
517
|
if persisted?
|
512
518
|
old_state = self.send("#{state}_was")
|
513
|
-
self.
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
+
new_state = self.send(state)
|
520
|
+
if old_state != new_state
|
521
|
+
self.state_changes.create({
|
522
|
+
:previous_state => old_state,
|
523
|
+
:next_state => self.send(state),
|
524
|
+
:name => name,
|
525
|
+
:user_id => self.user_id
|
526
|
+
}, :without_protection => true)
|
527
|
+
end
|
519
528
|
end
|
520
529
|
end
|
521
530
|
|
data/app/models/spree/payment.rb
CHANGED
@@ -8,7 +8,7 @@ module Spree
|
|
8
8
|
has_many :offsets, :class_name => "Spree::Payment", :foreign_key => :source_id, :conditions => "source_type = 'Spree::Payment' AND amount < 0 AND state = 'completed'"
|
9
9
|
has_many :log_entries, :as => :source
|
10
10
|
|
11
|
-
|
11
|
+
before_create :set_unique_identifier
|
12
12
|
|
13
13
|
after_save :create_payment_profile, :if => :profiles_supported?
|
14
14
|
|
@@ -155,6 +155,11 @@ module Spree
|
|
155
155
|
unless response.authorization.nil?
|
156
156
|
self.response_code = response.authorization
|
157
157
|
self.avs_response = response.avs_result['code']
|
158
|
+
|
159
|
+
if response.cvv_result
|
160
|
+
self.cvv_response_code = response.cvv_result['code']
|
161
|
+
self.cvv_response_message = response.cvv_result['message']
|
162
|
+
end
|
158
163
|
end
|
159
164
|
self.send("#{success_state}!")
|
160
165
|
else
|
data/app/models/spree/product.rb
CHANGED
@@ -290,7 +290,7 @@ module Spree
|
|
290
290
|
# there's a weird quirk with the delegate stuff that does not automatically save the delegate object
|
291
291
|
# when saving so we force a save using a hook.
|
292
292
|
def save_master
|
293
|
-
master.save if master && (master.changed? || master.new_record? || (master.default_price && (master.default_price.changed || master.default_price.new_record)))
|
293
|
+
master.save if master && (master.changed? || master.new_record? || (master.default_price && (master.default_price.changed? || master.default_price.new_record?)))
|
294
294
|
end
|
295
295
|
|
296
296
|
def ensure_master
|
@@ -68,14 +68,11 @@ module Spree
|
|
68
68
|
#
|
69
69
|
# SELECT COUNT(*) ...
|
70
70
|
add_search_scope :in_taxon do |taxon|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
scope.joins(:taxons).
|
78
|
-
where(Taxon.table_name => { :id => taxon.self_and_descendants.map(&:id) })
|
71
|
+
select("spree_products.id, spree_products.*").
|
72
|
+
where(id: Classification.select('spree_products_taxons.product_id').
|
73
|
+
joins(:taxon).
|
74
|
+
where(Taxon.table_name => { :id => taxon.self_and_descendants.pluck(:id) })
|
75
|
+
)
|
79
76
|
end
|
80
77
|
|
81
78
|
# This scope selects products in all taxons AND all its descendants
|
@@ -4,11 +4,11 @@
|
|
4
4
|
<i class="icon-arrow-right"></i> <%= t(:adjustments) %>
|
5
5
|
<% end %>
|
6
6
|
|
7
|
-
<% content_for :page_actions do %>
|
7
|
+
<% content_for :page_actions do %>
|
8
8
|
<li><%= button_link_to t(:new_adjustment), new_admin_order_adjustment_url(@order), :icon => 'icon-plus' %></li>
|
9
9
|
<li><%= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left' %></li>
|
10
10
|
<% end %>
|
11
11
|
|
12
12
|
<%= render :partial => 'adjustments_table' %>
|
13
13
|
|
14
|
-
<%= button_link_to t(:continue), @order.
|
14
|
+
<%= button_link_to t(:continue), @order.payment? ? new_admin_order_payment_url(@order) : admin_orders_url, :icon => 'icon-arrow-right' %>
|
@@ -20,7 +20,9 @@
|
|
20
20
|
</ul>
|
21
21
|
<div class="payment-method-settings">
|
22
22
|
<% @payment_methods.each do |method| %>
|
23
|
-
|
23
|
+
<% if method.source_required? %>
|
24
|
+
<%= render :partial => "spree/admin/payments/source_forms/#{method.method_type}", :locals => { :payment_method => method } %>
|
25
|
+
<% end %>
|
24
26
|
<% end %>
|
25
27
|
</div>
|
26
28
|
</div>
|
@@ -11,10 +11,12 @@
|
|
11
11
|
<%= variant.options_text %>
|
12
12
|
<% if @order.insufficient_stock_lines.include? line_item %>
|
13
13
|
<span class="out-of-stock">
|
14
|
-
<%= variant.in_stock? ? t(:insufficient_stock, :on_hand => variant.on_hand) : t(:out_of_stock)
|
15
|
-
</span
|
14
|
+
<%= variant.in_stock? ? t(:insufficient_stock, :on_hand => variant.on_hand) : t(:out_of_stock) %>
|
15
|
+
</span><br />
|
16
16
|
<% end %>
|
17
|
-
|
17
|
+
<span class="line-item-description" data-hook="line_item_description">
|
18
|
+
<%= line_item_description(variant) %>
|
19
|
+
</span>
|
18
20
|
</td>
|
19
21
|
<td class="cart-item-price" data-hook="cart_item_price">
|
20
22
|
<%= line_item.single_money.to_html %>
|
data/config/locales/en.yml
CHANGED
@@ -209,6 +209,12 @@ en:
|
|
209
209
|
spree/zone:
|
210
210
|
one: Zone
|
211
211
|
other: Zones
|
212
|
+
errors:
|
213
|
+
models:
|
214
|
+
spree/classification:
|
215
|
+
attributes:
|
216
|
+
taxon_id:
|
217
|
+
already_linked: "is already linked to this product"
|
212
218
|
add: Add
|
213
219
|
add_category: "Add Category"
|
214
220
|
add_country: "Add Country"
|
data/config/routes.rb
CHANGED
@@ -22,7 +22,7 @@ Spree::Core::Engine.routes.draw do
|
|
22
22
|
get '/orders/populate', :via => :get, :to => populate_redirect
|
23
23
|
match '/orders/:id/token/:token' => 'orders#show', :via => :get, :as => :token_order
|
24
24
|
|
25
|
-
resources :orders do
|
25
|
+
resources :orders, :except => [:new, :create] do
|
26
26
|
post :populate, :on => :collection
|
27
27
|
end
|
28
28
|
|
@@ -0,0 +1,6 @@
|
|
1
|
+
class AddUniqueIndexToOrdersShipmentsAndStockTransfers < ActiveRecord::Migration
|
2
|
+
def add
|
3
|
+
add_index "spree_orders", ["number"], :name => "number_idx_unique", :unique => true
|
4
|
+
add_index "spree_shipments", ["number"], :name => "number_idx_unique", :unique => true
|
5
|
+
end
|
6
|
+
end
|
@@ -16,17 +16,14 @@ production:
|
|
16
16
|
development:
|
17
17
|
adapter: mysql2
|
18
18
|
database: <%= database_prefix %>spree_development
|
19
|
-
username:
|
20
19
|
encoding: utf8
|
21
20
|
test:
|
22
21
|
adapter: mysql2
|
23
22
|
database: <%= database_prefix %>spree_test
|
24
|
-
username:
|
25
23
|
encoding: utf8
|
26
24
|
production:
|
27
25
|
adapter: mysql2
|
28
26
|
database: <%= database_prefix %>spree_production
|
29
|
-
username:
|
30
27
|
encoding: utf8
|
31
28
|
<% when 'postgres' %>
|
32
29
|
development:
|
@@ -14,9 +14,9 @@ module Spree
|
|
14
14
|
options[:field] ||= :permalink
|
15
15
|
self.permalink_options = options
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
if self.table_exists? && self.column_names.include?(permalink_options[:field].to_s)
|
18
|
+
before_validation(:on => :create) { save_permalink }
|
19
|
+
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def find_by_param(value, *args)
|
@@ -38,16 +38,20 @@ module Spree
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def save_permalink(permalink_value=self.to_param)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
#
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
41
|
+
self.with_lock do
|
42
|
+
permalink_value ||= generate_permalink
|
43
|
+
|
44
|
+
field = self.class.permalink_field
|
45
|
+
# Do other links exist with this permalink?
|
46
|
+
other = self.class.select(field).where("#{self.class.table_name}.#{field} LIKE ?", "#{permalink_value}%")
|
47
|
+
if other.any?
|
48
|
+
# Find the existing permalink with the highest number, and increment that number.
|
49
|
+
# (If none of the existing permalinks have a number, this will evaluate to 1.)
|
50
|
+
number = other.map { |o| o.send(field)[/-(\d+)$/, 1].to_i }.max + 1
|
51
|
+
permalink_value += "-#{number.to_s}"
|
52
|
+
end
|
53
|
+
write_attribute(field, permalink_value)
|
54
|
+
end
|
51
55
|
end
|
52
56
|
end
|
53
57
|
end
|