spree_core 3.3.6 → 3.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|