spree_core 3.3.6 → 3.4.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.
- checksums.yaml +4 -4
- data/app/helpers/spree/base_helper.rb +17 -18
- data/app/helpers/spree/products_helper.rb +5 -5
- data/app/models/concerns/spree/calculated_adjustments.rb +4 -3
- data/app/models/concerns/spree/default_price.rb +4 -5
- data/app/models/concerns/spree/display_money.rb +1 -1
- data/app/models/concerns/spree/named_type.rb +1 -1
- data/app/models/concerns/spree/ransackable_attributes.rb +5 -6
- data/app/models/concerns/spree/user_address.rb +6 -6
- data/app/models/concerns/spree/user_methods.rb +3 -3
- data/app/models/concerns/spree/user_payment_source.rb +4 -2
- data/app/models/concerns/spree/user_reporting.rb +1 -1
- data/app/models/spree/ability.rb +3 -3
- data/app/models/spree/address.rb +13 -9
- data/app/models/spree/adjustable/adjuster/promotion.rb +1 -1
- data/app/models/spree/adjustable/adjustments_updater.rb +2 -2
- data/app/models/spree/adjustable/promotion_accumulator.rb +6 -4
- data/app/models/spree/adjustment.rb +2 -3
- data/app/models/spree/app_configuration.rb +5 -6
- data/app/models/spree/base.rb +1 -1
- data/app/models/spree/calculator/default_tax.rb +4 -5
- data/app/models/spree/calculator/flat_percent_item_total.rb +1 -1
- data/app/models/spree/calculator/flat_rate.rb +3 -3
- data/app/models/spree/calculator/flexi_rate.rb +5 -5
- data/app/models/spree/calculator/price_sack.rb +9 -9
- data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +1 -1
- data/app/models/spree/calculator/shipping/flat_rate.rb +3 -3
- data/app/models/spree/calculator/shipping/flexi_rate.rb +7 -7
- data/app/models/spree/calculator/shipping/per_item.rb +2 -2
- data/app/models/spree/calculator/shipping/price_sack.rb +4 -4
- data/app/models/spree/calculator/tiered_flat_rate.rb +3 -2
- data/app/models/spree/calculator/tiered_percent.rb +4 -3
- data/app/models/spree/calculator.rb +4 -4
- data/app/models/spree/classification.rb +2 -2
- data/app/models/spree/credit_card.rb +1 -1
- data/app/models/spree/exchange.rb +4 -5
- data/app/models/spree/gateway/bogus.rb +20 -20
- data/app/models/spree/gateway/bogus_simple.rb +2 -4
- data/app/models/spree/gateway.rb +4 -4
- data/app/models/spree/image.rb +3 -3
- data/app/models/spree/inventory_unit.rb +30 -30
- data/app/models/spree/line_item.rb +7 -9
- data/app/models/spree/option_type.rb +1 -1
- data/app/models/spree/order/checkout.rb +5 -5
- data/app/models/spree/order/currency_updater.rb +1 -4
- data/app/models/spree/order/payments.rb +4 -4
- data/app/models/spree/order/store_credit.rb +2 -2
- data/app/models/spree/order.rb +11 -29
- data/app/models/spree/order_contents.rb +6 -5
- data/app/models/spree/order_inventory.rb +3 -4
- data/app/models/spree/order_updater.rb +13 -14
- data/app/models/spree/payment/processing.rb +25 -26
- data/app/models/spree/payment.rb +72 -79
- data/app/models/spree/payment_capture_event.rb +1 -1
- data/app/models/spree/payment_method/check.rb +1 -1
- data/app/models/spree/payment_method/store_credit.rb +5 -5
- data/app/models/spree/payment_method.rb +7 -7
- data/app/models/spree/preferences/configuration.rb +6 -9
- data/app/models/spree/preferences/preferable.rb +11 -11
- data/app/models/spree/preferences/preferable_class_methods.rb +2 -3
- data/app/models/spree/preferences/scoped_store.rb +6 -5
- data/app/models/spree/preferences/store.rb +9 -14
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product/scopes.rb +49 -49
- data/app/models/spree/product.rb +16 -16
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +2 -1
- data/app/models/spree/promotion/actions/free_shipping.rb +1 -1
- data/app/models/spree/promotion/rules/first_order.rb +7 -6
- data/app/models/spree/promotion/rules/item_total.rb +3 -5
- data/app/models/spree/promotion/rules/one_use_per_user.rb +1 -2
- data/app/models/spree/promotion/rules/option_value.rb +14 -6
- data/app/models/spree/promotion/rules/product.rb +4 -4
- data/app/models/spree/promotion/rules/taxon.rb +6 -6
- data/app/models/spree/promotion/rules/user.rb +3 -3
- data/app/models/spree/promotion/rules/user_logged_in.rb +1 -1
- data/app/models/spree/promotion.rb +15 -16
- data/app/models/spree/promotion_action.rb +1 -1
- data/app/models/spree/promotion_handler/cart.rb +3 -2
- data/app/models/spree/promotion_handler/free_shipping.rb +1 -3
- data/app/models/spree/promotion_handler/page.rb +3 -3
- data/app/models/spree/promotion_rule.rb +5 -4
- data/app/models/spree/refund.rb +8 -8
- data/app/models/spree/reimbursement/credit.rb +1 -1
- data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -3
- data/app/models/spree/reimbursement.rb +4 -8
- data/app/models/spree/reimbursement_performer.rb +0 -5
- data/app/models/spree/reimbursement_tax_calculator.rb +5 -12
- data/app/models/spree/reimbursement_type.rb +2 -2
- data/app/models/spree/return_authorization.rb +22 -26
- data/app/models/spree/return_item/eligibility_validator/default.rb +3 -3
- data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/order_completed.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/rma_required.rb +2 -3
- data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +2 -2
- data/app/models/spree/return_item.rb +15 -19
- data/app/models/spree/returns_calculator.rb +1 -2
- data/app/models/spree/shipment.rb +14 -35
- data/app/models/spree/shipment_handler.rb +10 -12
- data/app/models/spree/shipping_calculator.rb +5 -6
- data/app/models/spree/shipping_method.rb +3 -3
- data/app/models/spree/shipping_rate.rb +2 -2
- data/app/models/spree/state.rb +2 -2
- data/app/models/spree/stock/availability_validator.rb +1 -1
- data/app/models/spree/stock/content_item.rb +2 -3
- data/app/models/spree/stock/coordinator.rb +3 -2
- data/app/models/spree/stock/differentiator.rb +3 -2
- data/app/models/spree/stock/estimator.rb +7 -5
- data/app/models/spree/stock/package.rb +5 -5
- data/app/models/spree/stock/packer.rb +1 -1
- data/app/models/spree/stock/prioritizer.rb +5 -7
- data/app/models/spree/stock/quantifier.rb +0 -1
- data/app/models/spree/stock/splitter/backordered.rb +2 -4
- data/app/models/spree/stock/splitter/base.rb +3 -2
- data/app/models/spree/stock/splitter/shipping_category.rb +2 -1
- data/app/models/spree/stock_item.rb +1 -1
- data/app/models/spree/stock_location.rb +12 -11
- data/app/models/spree/stock_movement.rb +1 -3
- data/app/models/spree/stock_transfer.rb +1 -1
- data/app/models/spree/store.rb +4 -4
- data/app/models/spree/store_credit.rb +3 -3
- data/app/models/spree/tax_category.rb +1 -1
- data/app/models/spree/tax_rate.rb +10 -10
- data/app/models/spree/taxon.rb +13 -13
- data/app/models/spree/taxonomy.rb +9 -8
- data/app/models/spree/validations/db_maximum_length_validator.rb +2 -3
- data/app/models/spree/variant.rb +30 -41
- data/app/models/spree/zone.rb +10 -10
- data/app/validators/db_maximum_length_validator.rb +5 -5
- data/config/initializers/acts_as_taggable_on.rb +3 -3
- data/config/initializers/assets.rb +1 -1
- data/config/initializers/friendly_id.rb +1 -1
- data/config/initializers/premailer_assets.rb +1 -1
- data/config/locales/en.yml +8 -2
- data/db/default/spree/states.rb +1 -0
- data/lib/generators/spree/custom_user/custom_user_generator.rb +12 -15
- data/lib/generators/spree/install/install_generator.rb +45 -32
- data/lib/spree/core/components.rb +3 -3
- data/lib/spree/core/controller_helpers/auth.rb +5 -10
- data/lib/spree/core/controller_helpers/common.rb +2 -3
- data/lib/spree/core/controller_helpers/order.rb +3 -7
- data/lib/spree/core/controller_helpers/respond_with.rb +4 -4
- data/lib/spree/core/engine.rb +3 -3
- data/lib/spree/core/environment/calculators.rb +0 -1
- data/lib/spree/core/environment_extension.rb +8 -8
- data/lib/spree/core/importer/order.rb +64 -67
- data/lib/spree/core/importer/product.rb +10 -9
- data/lib/spree/core/product_filters.rb +17 -18
- data/lib/spree/core/routes.rb +2 -6
- data/lib/spree/core/search/base.rb +62 -59
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +4 -6
- data/lib/spree/i18n.rb +3 -5
- data/lib/spree/localized_number.rb +0 -2
- data/lib/spree/migrations.rb +8 -7
- data/lib/spree/money.rb +3 -7
- data/lib/spree/permitted_attributes.rb +2 -2
- data/lib/spree/responder.rb +4 -5
- data/lib/spree/testing_support/authorization_helpers.rb +3 -3
- data/lib/spree/testing_support/caching.rb +5 -5
- data/lib/spree/testing_support/capybara_ext.rb +16 -18
- data/lib/spree/testing_support/common_rake.rb +8 -9
- data/lib/spree/testing_support/controller_requests.rb +6 -6
- data/lib/spree/testing_support/extension_rake.rb +2 -3
- data/lib/spree/testing_support/factories/address_factory.rb +1 -1
- data/lib/spree/testing_support/factories/adjustment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/calculator_factory.rb +1 -1
- data/lib/spree/testing_support/factories/country_factory.rb +1 -1
- data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
- data/lib/spree/testing_support/factories/customer_return_factory.rb +1 -3
- data/lib/spree/testing_support/factories/image_factory.rb +2 -2
- data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
- data/lib/spree/testing_support/factories/line_item_factory.rb +2 -2
- data/lib/spree/testing_support/factories/options_factory.rb +1 -1
- data/lib/spree/testing_support/factories/order_factory.rb +1 -1
- data/lib/spree/testing_support/factories/payment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/payment_method_factory.rb +4 -4
- data/lib/spree/testing_support/factories/price_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_option_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/promotion_category_factory.rb +1 -2
- data/lib/spree/testing_support/factories/promotion_factory.rb +1 -2
- data/lib/spree/testing_support/factories/promotion_rule_factory.rb +1 -1
- data/lib/spree/testing_support/factories/property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/prototype_factory.rb +1 -1
- data/lib/spree/testing_support/factories/refund_factory.rb +1 -1
- data/lib/spree/testing_support/factories/reimbursement_factory.rb +2 -2
- data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/return_authorization_factory.rb +1 -1
- data/lib/spree/testing_support/factories/return_item_factory.rb +1 -1
- data/lib/spree/testing_support/factories/role_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +2 -2
- data/lib/spree/testing_support/factories/shipping_category_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +3 -3
- data/lib/spree/testing_support/factories/state_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_item_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_location_factory.rb +2 -2
- data/lib/spree/testing_support/factories/stock_movement_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_category_factory.rb +2 -2
- data/lib/spree/testing_support/factories/store_credit_event_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tag_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tax_category_factory.rb +2 -2
- data/lib/spree/testing_support/factories/tax_rate_factory.rb +1 -1
- data/lib/spree/testing_support/factories/taxon_factory.rb +1 -1
- data/lib/spree/testing_support/factories/taxonomy_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tracker_factory.rb +1 -1
- data/lib/spree/testing_support/factories/user_factory.rb +1 -1
- data/lib/spree/testing_support/factories/variant_factory.rb +1 -2
- data/lib/spree/testing_support/factories/zone_factory.rb +1 -1
- data/lib/spree/testing_support/factories/zone_member_factory.rb +1 -1
- data/lib/spree/testing_support/factories.rb +3 -3
- data/lib/spree/testing_support/flash.rb +1 -3
- data/lib/spree/testing_support/i18n.rb +5 -6
- data/lib/spree/testing_support/kernel.rb +1 -2
- data/lib/spree/testing_support/order_walkthrough.rb +12 -15
- data/lib/spree/testing_support/preferences.rb +0 -1
- data/lib/tasks/core.rake +47 -56
- data/lib/tasks/email.rake +2 -2
- data/lib/tasks/exchanges.rake +5 -5
- data/spree_core.gemspec +1 -1
- metadata +5 -9
- data/app/models/spree/calculator/percent_per_item.rb +0 -51
- data/config/initializers/premailer_rails.rb +0 -3
- data/lib/spree/core/delegate_belongs_to.rb +0 -99
- data/lib/spree/testing_support/microdata.rb +0 -192
@@ -1,51 +0,0 @@
|
|
1
|
-
module Spree
|
2
|
-
|
3
|
-
# A calculator for promotions that calculates a percent-off discount
|
4
|
-
# for all matching products in an order. This should not be used as a
|
5
|
-
# shipping calculator since it would be the same thing as a flat percent
|
6
|
-
# off the entire order.
|
7
|
-
|
8
|
-
class Calculator::PercentPerItem < Calculator
|
9
|
-
preference :percent, :decimal, default: 0
|
10
|
-
|
11
|
-
def self.description
|
12
|
-
Spree.t(:percent_per_item)
|
13
|
-
end
|
14
|
-
|
15
|
-
def compute(object=nil)
|
16
|
-
ActiveSupport::Deprecation.warn(<<-EOS, caller)
|
17
|
-
Spree::Calculator::PercentPerItem will be removed in Spree 3.4
|
18
|
-
There is now a Promotion Action which deals with these types of promotions instead
|
19
|
-
EOS
|
20
|
-
return 0 if object.nil?
|
21
|
-
object.line_items.reduce(0) do |sum, line_item|
|
22
|
-
sum += value_for_line_item(line_item)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
# Returns all products that match this calculator, but only if the calculator
|
29
|
-
# is attached to a promotion. If attached to a ShippingMethod, nil is returned.
|
30
|
-
# Copied from per_item.rb
|
31
|
-
def matching_products
|
32
|
-
if compute_on_promotion?
|
33
|
-
self.calculable.promotion.rules.map do |rule|
|
34
|
-
rule.respond_to?(:products) ? rule.products : []
|
35
|
-
end.flatten
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def value_for_line_item(line_item)
|
40
|
-
if compute_on_promotion?
|
41
|
-
return 0 unless matching_products.blank? or matching_products.include?(line_item.product)
|
42
|
-
end
|
43
|
-
((line_item.price * line_item.quantity) * preferred_percent) / 100
|
44
|
-
end
|
45
|
-
|
46
|
-
# Determines wether or not the calculable object is a promotion
|
47
|
-
def compute_on_promotion?
|
48
|
-
@compute_on_promotion ||= self.calculable.respond_to?(:promotion)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# Creates methods on object which delegate to an association proxy.
|
3
|
-
# see delegate_belongs_to for two uses
|
4
|
-
#
|
5
|
-
# Todo - integrate with ActiveRecord::Dirty to make sure changes to delegate object are noticed
|
6
|
-
# Should do
|
7
|
-
# class User < Spree::Base; delegate_belongs_to :contact, :firstname; end
|
8
|
-
# class Contact < Spree::Base; end
|
9
|
-
# u = User.first
|
10
|
-
# u.changed? # => false
|
11
|
-
# u.firstname = 'Bobby'
|
12
|
-
# u.changed? # => true
|
13
|
-
#
|
14
|
-
# Right now the second call to changed? would return false
|
15
|
-
#
|
16
|
-
# Todo - add has_one support. fairly straightforward addition
|
17
|
-
##
|
18
|
-
module DelegateBelongsTo
|
19
|
-
extend ActiveSupport::Concern
|
20
|
-
|
21
|
-
module ClassMethods
|
22
|
-
|
23
|
-
@@default_rejected_delegate_columns = ['created_at','created_on','updated_at','updated_on','lock_version','type','id','position','parent_id','lft','rgt']
|
24
|
-
mattr_accessor :default_rejected_delegate_columns
|
25
|
-
|
26
|
-
##
|
27
|
-
# Creates methods for accessing and setting attributes on an association. Uses same
|
28
|
-
# default list of attributes as delegates_to_association.
|
29
|
-
# @todo Integrate this with ActiveRecord::Dirty, so if you set a property through one of these setters and then call save on this object, it will save the associated object automatically.
|
30
|
-
# delegate_belongs_to :contact
|
31
|
-
# delegate_belongs_to :contact, [:defaults] ## same as above, and useless
|
32
|
-
# delegate_belongs_to :contact, [:defaults, :address, :fullname], class_name: 'VCard'
|
33
|
-
##
|
34
|
-
def delegate_belongs_to(association, *attrs)
|
35
|
-
ActiveSupport::Deprecation.warn(<<-EOS, caller)
|
36
|
-
DelegateBelongsTo module is deprecated and will be removed in Spree 3.4
|
37
|
-
EOS
|
38
|
-
|
39
|
-
opts = attrs.extract_options!
|
40
|
-
initialize_association :belongs_to, association, opts
|
41
|
-
attrs = get_association_column_names(association) if attrs.empty?
|
42
|
-
attrs.concat get_association_column_names(association) if attrs.delete :defaults
|
43
|
-
attrs.each do |attr|
|
44
|
-
class_def attr do |*args|
|
45
|
-
send(:delegator_for, association, attr, *args)
|
46
|
-
end
|
47
|
-
|
48
|
-
class_def "#{attr}=" do |val|
|
49
|
-
send(:delegator_for_setter, association, attr, val)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
protected
|
55
|
-
|
56
|
-
def get_association_column_names(association, without_default_rejected_delegate_columns=true)
|
57
|
-
begin
|
58
|
-
association_klass = reflect_on_association(association).klass
|
59
|
-
methods = association_klass.column_names
|
60
|
-
methods.reject!{|x|default_rejected_delegate_columns.include?(x.to_s)} if without_default_rejected_delegate_columns
|
61
|
-
return methods
|
62
|
-
rescue
|
63
|
-
return []
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
##
|
68
|
-
# initialize_association :belongs_to, :contact
|
69
|
-
def initialize_association(type, association, opts={})
|
70
|
-
raise 'Illegal or unimplemented association type.' unless [:belongs_to].include?(type.to_s.to_sym)
|
71
|
-
send type, association, opts if reflect_on_association(association).nil?
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
75
|
-
def class_def(name, method=nil, &blk)
|
76
|
-
class_eval { method.nil? ? define_method(name, &blk) : define_method(name, method) }
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def delegator_for(association, attr, *args)
|
81
|
-
return if self.class.column_names.include?(attr.to_s)
|
82
|
-
send "build_#{association}" if send(association).nil?
|
83
|
-
if args.empty?
|
84
|
-
send(association).send(attr)
|
85
|
-
else
|
86
|
-
send(association).send(attr, *args)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def delegator_for_setter(association, attr, val)
|
91
|
-
return if self.class.column_names.include?(attr.to_s)
|
92
|
-
send "build_#{association}" if send(association).nil?
|
93
|
-
send(association).send("#{attr}=", val)
|
94
|
-
end
|
95
|
-
protected :delegator_for
|
96
|
-
protected :delegator_for_setter
|
97
|
-
end
|
98
|
-
|
99
|
-
ActiveRecord::Base.include DelegateBelongsTo
|
@@ -1,192 +0,0 @@
|
|
1
|
-
module Spree
|
2
|
-
module TestingSupport
|
3
|
-
module Microdata
|
4
|
-
# code extracted and modified from 'microdata' gem
|
5
|
-
class Document
|
6
|
-
attr_reader :items, :doc
|
7
|
-
|
8
|
-
def initialize(content)
|
9
|
-
ActiveSupport::Deprecation.warn(<<-EOS, caller)
|
10
|
-
Spree::TestingSupport::Microdata will be removed in Spree 3.4
|
11
|
-
EOS
|
12
|
-
@doc = Nokogiri::HTML(content)
|
13
|
-
@items = extract_items
|
14
|
-
end
|
15
|
-
|
16
|
-
def extract_items
|
17
|
-
itemscopes = @doc.search('//*[@itemscope and not(@itemprop)]')
|
18
|
-
return nil unless itemscopes
|
19
|
-
|
20
|
-
itemscopes.map do |itemscope|
|
21
|
-
Item.new(itemscope)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class Item
|
27
|
-
attr_reader :type, :properties, :id
|
28
|
-
|
29
|
-
def initialize(top_node)
|
30
|
-
@top_node = top_node
|
31
|
-
@type = extract_item_type
|
32
|
-
@id = extract_item_id
|
33
|
-
@properties = {}
|
34
|
-
add_item_ref_properties(@top_node)
|
35
|
-
parse_elements(extract_elements(@top_node))
|
36
|
-
end
|
37
|
-
|
38
|
-
def to_hash
|
39
|
-
hash = {}
|
40
|
-
hash[:id] = id if id
|
41
|
-
hash[:type] = type if type
|
42
|
-
hash[:properties] = {}
|
43
|
-
properties.each do |name, values|
|
44
|
-
final_values = values.map do |value|
|
45
|
-
if value.reponds_to?(:to_hash)
|
46
|
-
value.to_hash
|
47
|
-
else
|
48
|
-
value
|
49
|
-
end
|
50
|
-
end
|
51
|
-
hash[:properties][name] = final_values
|
52
|
-
end
|
53
|
-
hash
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def extract_elements(node)
|
59
|
-
node.search('./*')
|
60
|
-
end
|
61
|
-
|
62
|
-
def extract_item_id
|
63
|
-
(value = @top_node.attribute('itemid')) ? value.value : nil
|
64
|
-
end
|
65
|
-
|
66
|
-
def extract_item_type
|
67
|
-
(value = @top_node.attribute('itemtype')) ? value.value.split(' ') : nil
|
68
|
-
end
|
69
|
-
|
70
|
-
def parse_elements(elements)
|
71
|
-
elements.each { |element| parse_element(element) }
|
72
|
-
end
|
73
|
-
|
74
|
-
def parse_element(element)
|
75
|
-
item_scope = element.attribute('itemscope')
|
76
|
-
item_prop = element.attribute('itemprop')
|
77
|
-
internal_elements = extract_elements(element)
|
78
|
-
add_item_prop(element) if item_scope || item_prop
|
79
|
-
parse_elements(internal_elements) if internal_elements && !item_scope
|
80
|
-
end
|
81
|
-
|
82
|
-
# Add an 'itemprop' to the properties
|
83
|
-
def add_item_prop(item_prop)
|
84
|
-
properties = Itemprop.parse(item_prop, @page_url)
|
85
|
-
properties.each { |name, value| (@properties[name] ||= []) << value }
|
86
|
-
end
|
87
|
-
|
88
|
-
# Add any properties referred to by 'itemref'
|
89
|
-
def add_item_ref_properties(element)
|
90
|
-
item_ref = element.attribute('itemref')
|
91
|
-
if item_ref
|
92
|
-
item_ref.value.split(' ').each { |id| parse_elements(find_with_id(id)) }
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# Find an element with a matching id
|
97
|
-
def find_with_id(id)
|
98
|
-
@top_node.search("//*[@id='#{id}']")
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
class Itemprop
|
103
|
-
NON_TEXTCONTENT_ELEMENTS = {
|
104
|
-
'a' => 'href', 'area' => 'href',
|
105
|
-
'audio' => 'src', 'embed' => 'src',
|
106
|
-
'iframe' => 'src', 'img' => 'src',
|
107
|
-
'link' => 'href', 'meta' => 'content',
|
108
|
-
'object' => 'data', 'source' => 'src',
|
109
|
-
'time' => 'datetime', 'track' => 'src',
|
110
|
-
'video' => 'src'
|
111
|
-
}.freeze
|
112
|
-
URL_ATTRIBUTES = ['data', 'href', 'src'].freeze
|
113
|
-
|
114
|
-
# A Hash representing the properties.
|
115
|
-
# Hash is of the form {'property name' => 'value'}
|
116
|
-
attr_reader :properties
|
117
|
-
|
118
|
-
# Create a new Itemprop object
|
119
|
-
# [element] The itemprop element to be parsed
|
120
|
-
# [page_url] The url of the page, including filename, used to form
|
121
|
-
# absolute urls
|
122
|
-
def initialize(element, page_url = nil)
|
123
|
-
@element = element
|
124
|
-
@page_url = page_url
|
125
|
-
@properties = extract_properties
|
126
|
-
end
|
127
|
-
|
128
|
-
# Parse the element and return a hash representing the properties.
|
129
|
-
# Hash is of the form {'property name' => 'value'}
|
130
|
-
# [element] The itemprop element to be parsed
|
131
|
-
# [page_url] The url of the page, including filename, used to form
|
132
|
-
# absolute urls
|
133
|
-
def self.parse(element, page_url = nil)
|
134
|
-
new(element, page_url).properties
|
135
|
-
end
|
136
|
-
|
137
|
-
private
|
138
|
-
|
139
|
-
def extract_properties
|
140
|
-
prop_names = extract_property_names
|
141
|
-
prop_names.each_with_object({}) do |name, memo|
|
142
|
-
memo[name] = extract_property
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
# This returns an empty string if can't form a valid
|
147
|
-
# absolute url as per the Microdata spec.
|
148
|
-
|
149
|
-
def make_absolute_url(url)
|
150
|
-
return url unless URI.parse(url).relative?
|
151
|
-
begin
|
152
|
-
URI.parse(@page_url).merge(url).to_s
|
153
|
-
rescue URI::Error
|
154
|
-
url
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def non_textcontent_element?(element)
|
159
|
-
NON_TEXTCONTENT_ELEMENTS.has_key?(element)
|
160
|
-
end
|
161
|
-
|
162
|
-
def url_attribute?(attribute)
|
163
|
-
URL_ATTRIBUTES.include?(attribute)
|
164
|
-
end
|
165
|
-
|
166
|
-
def extract_property_names
|
167
|
-
itemprop_attr = @element.attribute('itemprop')
|
168
|
-
itemprop_attr ? itemprop_attr.value.split : []
|
169
|
-
end
|
170
|
-
|
171
|
-
def extract_property_value
|
172
|
-
element = @element.name
|
173
|
-
if non_textcontent_element?(element)
|
174
|
-
attribute = NON_TEXTCONTENT_ELEMENTS[element]
|
175
|
-
value = @element.attribute(attribute).value
|
176
|
-
url_attribute?(attribute) ? make_absolute_url(value) : value
|
177
|
-
else
|
178
|
-
@element.inner_text.strip
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def extract_property
|
183
|
-
if @element.attribute('itemscope')
|
184
|
-
Item.new(@element)
|
185
|
-
else
|
186
|
-
extract_property_value
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|