spree_analytics_trackers 1.0.1 → 2.1.1

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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/.bundle/config +2 -0
  3. data/.rubocop.yml +2 -0
  4. data/.travis.yml +30 -15
  5. data/Appraisals +3 -9
  6. data/LICENSE +1 -1
  7. data/README.md +7 -3
  8. data/app/assets/javascripts/spree/frontend/add_to_cart_analytics.js +50 -0
  9. data/app/assets/javascripts/spree/frontend/remove_from_cart_analytics.js +34 -0
  10. data/app/controllers/spree/admin/trackers_controller.rb +8 -0
  11. data/app/controllers/spree_analytics_trackers/checkout_controller_decorator.rb +11 -0
  12. data/app/controllers/spree_analytics_trackers/store_controller_decorator.rb +13 -0
  13. data/app/controllers/spree_analytics_trackers/user_confirmations_controller_decorator.rb +11 -0
  14. data/app/controllers/spree_analytics_trackers/user_passwords_controller_decorator.rb +11 -0
  15. data/app/controllers/spree_analytics_trackers/user_registrations_controller_decorator.rb +11 -0
  16. data/app/controllers/spree_analytics_trackers/user_sessions_controller_decorator.rb +11 -0
  17. data/app/helpers/spree/trackers_helper.rb +79 -16
  18. data/app/models/spree/tracker.rb +11 -5
  19. data/app/models/spree_analytics_trackers/user_decorator.rb +9 -0
  20. data/app/overrides/add_analytics_to_admin_sidebar.rb +2 -3
  21. data/app/overrides/add_cart_viewed_to_orders_edit.rb +1 -1
  22. data/app/overrides/add_checkout_step_viewed_to_checkout_edit.rb +11 -3
  23. data/app/overrides/add_google_analytics_page_view_to_spree_application.rb +10 -0
  24. data/app/overrides/add_google_analytics_to_spree_application.rb +4 -4
  25. data/app/overrides/add_google_purchase_to_orders_show.rb +1 -1
  26. data/app/overrides/add_product_list_filtered_to_taxons_show.rb +1 -1
  27. data/app/overrides/add_product_list_viewed_to_products_list.rb +1 -1
  28. data/app/overrides/add_product_viewed_to_products_show.rb +2 -2
  29. data/app/overrides/add_products_searched_to_products_list.rb +2 -2
  30. data/app/overrides/add_segment_initializer_to_layout.rb +3 -3
  31. data/app/overrides/add_segment_page_viewed_to_layout.rb +10 -0
  32. data/app/presenters/spree_analytics_trackers/base_presenter.rb +14 -0
  33. data/app/presenters/spree_analytics_trackers/segment/order_presenter.rb +32 -0
  34. data/app/presenters/spree_analytics_trackers/segment/product_presenter.rb +40 -0
  35. data/app/views/spree/admin/shared/_analytics_sidebar_menu.html.erb +3 -5
  36. data/app/views/spree/admin/trackers/_form.html.erb +13 -7
  37. data/app/views/spree/admin/trackers/index.html.erb +6 -8
  38. data/app/views/spree/shared/trackers/google_analytics/_checkout_step_viewed.js.erb +19 -0
  39. data/app/views/spree/shared/trackers/google_analytics/_initializer.js.erb +25 -0
  40. data/app/views/spree/shared/trackers/google_analytics/_page_viewed.js.erb +13 -0
  41. data/app/views/spree/shared/trackers/google_analytics/_purchase.js.erb +22 -0
  42. data/app/views/spree/shared/trackers/segment/_cart_viewed.js.erb +24 -19
  43. data/app/views/spree/shared/trackers/segment/_checkout_step_viewed.js.erb +20 -11
  44. data/app/views/spree/shared/trackers/segment/_initializer.js.erb +2 -3
  45. data/app/views/spree/shared/trackers/segment/_order_complete.js.erb +8 -45
  46. data/app/views/spree/shared/trackers/segment/_page_viewed.js.erb +7 -0
  47. data/app/views/spree/shared/trackers/segment/_product_list_filtered.js.erb +19 -28
  48. data/app/views/spree/shared/trackers/segment/_product_list_viewed.js.erb +17 -20
  49. data/app/views/spree/shared/trackers/segment/_product_viewed.js.erb +12 -6
  50. data/app/views/spree/shared/trackers/segment/_products_searched.js.erb +7 -9
  51. data/config/locales/en.yml +0 -2
  52. data/config/locales/zh-TW.yml +19 -0
  53. data/db/migrate/20200721163729_add_store_id_to_spree_trackers.rb +14 -0
  54. data/gemfiles/{spree_3_5.gemfile → spree_4_1.gemfile} +2 -2
  55. data/gemfiles/spree_master.gemfile +0 -1
  56. data/lib/generators/spree_analytics_trackers/install/install_generator.rb +8 -0
  57. data/lib/spree_analytics_trackers.rb +1 -0
  58. data/lib/spree_analytics_trackers/factories.rb +1 -0
  59. data/lib/spree_analytics_trackers/version.rb +3 -9
  60. data/spec/features/admin/configuration/analytics_tracker_spec.rb +18 -7
  61. data/spec/features/checkout_spec.rb +15 -0
  62. data/spec/features/products_spec.rb +315 -0
  63. data/spec/features/user_login_spec.rb +7 -0
  64. data/spec/features/user_password_recovery_spec.rb +7 -0
  65. data/spec/features/user_registration_spec.rb +7 -0
  66. data/spec/fixtures/thinking-cat.jpg +0 -0
  67. data/spec/models/spree/tracker_spec.rb +15 -0
  68. data/spec/presenters/spree_analytics_trackers/segment/order_presenter_spec.rb +34 -0
  69. data/spec/spec_helper.rb +7 -82
  70. data/spec/support/custom_products.rb +26 -0
  71. data/spree_analytics_trackers.gemspec +4 -17
  72. metadata +56 -212
  73. data/app/controllers/spree/store_controller_decorator.rb +0 -5
  74. data/app/models/spree/line_item_decorator.rb +0 -6
  75. data/app/models/spree/order_decorator.rb +0 -7
  76. data/app/models/spree/product_decorator.rb +0 -11
  77. data/app/models/spree/user_decorator.rb +0 -5
  78. data/app/overrides/add_google_checkout_to_checkout_edit.rb +0 -9
  79. data/app/overrides/add_product_added_to_orders_edit.rb +0 -10
  80. data/app/views/spree/shared/_google_add_items.html.erb +0 -13
  81. data/app/views/spree/shared/_google_analytics.html.erb +0 -18
  82. data/app/views/spree/shared/_google_checkout.html.erb +0 -14
  83. data/app/views/spree/shared/_google_purchase.html.erb +0 -19
  84. data/app/views/spree/shared/trackers/segment/_product_added.js.erb +0 -9
  85. data/gemfiles/spree_3_7.gemfile +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73068544992b2ab73b42d2d9973c61217f2e9006b1eeaf82bb487d0c06694253
4
- data.tar.gz: b5487f54f759141810e350a7aabe3c89870a2586d0f79c234c02a9a2f962c96d
3
+ metadata.gz: 39824346c7fd7f4f0369de8f15513e63cb3c3c490ea1ff746ab2022e644c0316
4
+ data.tar.gz: 6df1197ae57739e09de6f7abc91e3f3b44bec114efa608fa1b97c1f0e2b3a6d4
5
5
  SHA512:
6
- metadata.gz: 961549e600a21cb31dad51459269e95f304c2540ad6e4603780a74548e77331507f0ffa9b7e64663915f9ade40107422e105ec4ab3e735b22c269176b7cb0ba6
7
- data.tar.gz: bb01db4431806581753611af24c40f6bfe60b9454c063a3907676bbecce138a2c5260a4e52290cecb9c05cb65e448c32056d6d91da7714b7250d7fd3987a4d22
6
+ metadata.gz: 196444a2a5020015e889c7f8a4f09180338372a900b4f44e0af2c0637cca747ae00249a9afab3d8c7f67c6edb68821ee86bd59b181641b25121d630440ccd773
7
+ data.tar.gz: 73956ab392e0802b1256aac939ea280b846a7464d2fbfaeba5d4bf386622e750fc81cd936226cece3984b1badf8d00679301251609433cb13e37d02121362cad
data/.bundle/config ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_JOBS: "8"
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.5
data/.travis.yml CHANGED
@@ -1,29 +1,44 @@
1
- sudo: required
2
- dist: trusty
1
+ os: linux
2
+ dist: bionic
3
+
4
+ addons:
5
+ apt:
6
+ sources:
7
+ - google-chrome
8
+ packages:
9
+ - google-chrome-stable
10
+
11
+ services:
12
+ - mysql
13
+ - postgresql
3
14
 
4
15
  language: ruby
5
16
 
17
+ rvm:
18
+ - 2.5
19
+ - 2.6
20
+
6
21
  env:
7
- - DB=postgres
8
22
  - DB=mysql
23
+ - DB=postgres
9
24
 
10
25
  gemfile:
11
- - gemfiles/spree_3_5.gemfile
12
- - gemfiles/spree_3_7.gemfile
26
+ - gemfiles/spree_4_1.gemfile
13
27
  - gemfiles/spree_master.gemfile
14
28
 
15
- script:
16
- - bundle exec rake test_app
17
- - bundle exec rake spec
18
-
19
- rvm:
20
- - 2.3.3
21
- - 2.4.2
22
- - 2.5.2
23
-
24
- matrix:
29
+ jobs:
25
30
  allow_failures:
26
31
  - gemfile: gemfiles/spree_master.gemfile
27
32
 
28
33
  before_install:
29
34
  - mysql -u root -e "GRANT ALL ON *.* TO 'travis'@'%';"
35
+
36
+ before_script:
37
+ - CHROME_MAIN_VERSION=`google-chrome-stable --version | sed -E 's/(^Google Chrome |\.[0-9]+ )//g'`
38
+ - CHROMEDRIVER_VERSION=`curl -s "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$CHROME_MAIN_VERSION"`
39
+ - curl "https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip" -O
40
+ - unzip chromedriver_linux64.zip -d ~/bin
41
+
42
+ script:
43
+ - bundle exec rake test_app
44
+ - bundle exec rake spec
data/Appraisals CHANGED
@@ -1,12 +1,6 @@
1
- appraise 'spree-3-5' do
2
- gem 'spree', '~> 3.5.0'
3
- gem 'spree_auth_devise', '~> 3.3.0'
4
- gem 'rails-controller-testing'
5
- end
6
-
7
- appraise 'spree-3-7' do
8
- gem 'spree', '~> 3.7.0'
9
- gem 'spree_auth_devise', '~> 3.5.0'
1
+ appraise 'spree-4-1' do
2
+ gem 'spree', '~> 4.1.0'
3
+ gem 'spree_auth_devise', '~> 4.1.0'
10
4
  gem 'rails-controller-testing'
11
5
  end
12
6
 
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017-2018 Spark Solutions Sp. z o.o.
1
+ Copyright (c) 2017-2020 Spark Solutions Sp. z o.o.
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without modification,
data/README.md CHANGED
@@ -6,6 +6,7 @@ This extensions adds support for [Google Analytics Enhanced Ecommerce](https://d
6
6
  and [Segment Ecommerce](https://segment.com/docs/spec/ecommerce/v2/) tracking to [Spree Commerce](https://spreecommerce.org) stores.
7
7
 
8
8
  Via Segment.com you can plug-in also a lot of additional vendors and services like:
9
+
9
10
  * Mixpanel
10
11
  * Kissmetrics
11
12
  * Google Tag Manager
@@ -18,16 +19,19 @@ No additional development required.
18
19
  ## Installation
19
20
 
20
21
  1. Add this extension to your Gemfile with this line:
22
+
21
23
  ```ruby
22
- gem 'spree_analytics_trackers', '~> 1.0'
24
+ gem 'spree_analytics_trackers', '~> 2.0'
23
25
  ```
24
26
 
25
27
  2. Install the gem using Bundler:
28
+
26
29
  ```ruby
27
30
  bundle install
28
31
  ```
29
32
 
30
33
  3. Copy & run migrations
34
+
31
35
  ```ruby
32
36
  bundle exec rails g spree_analytics_trackers:install
33
37
  ```
@@ -52,10 +56,9 @@ Simply add this require statement to your spec_helper:
52
56
  require 'spree_analytics_trackers/factories'
53
57
  ```
54
58
 
55
-
56
59
  ## License
57
60
 
58
- Spree Analytics Trackers is copyright © 2017-2018
61
+ Spree Analytics Trackers is copyright © 2017-2020
59
62
  [Spark Solutions Sp. z o.o.][spark]. It is free software,
60
63
  and may be redistributed under the terms specified in the
61
64
  [LICENCE](LICENSE) file.
@@ -63,6 +66,7 @@ and may be redistributed under the terms specified in the
63
66
  [LICENSE]: https://github.com/spree-contrib/spree_analytics_trackers/blob/master/LICENSE
64
67
 
65
68
  ## About Spark Solutions
69
+
66
70
  [![Spark Solutions](http://sparksolutions.co/wp-content/uploads/2015/01/logo-ss-tr-221x100.png)][spark]
67
71
 
68
72
  Spree Analytics Trackers is maintained by [Spark Solutions Sp. z o.o.](http://sparksolutions.co?utm_source=github).
@@ -0,0 +1,50 @@
1
+ //= require spree/frontend
2
+
3
+ function gaAddToCart(variant, quantity) {
4
+ clearGAplugins();
5
+ var price = typeof variant.price === 'object' ? variant.price.amount : variant.price
6
+ gtag(
7
+ 'event',
8
+ 'add_to_cart',
9
+ {
10
+ items: [{
11
+ id: variant.sku,
12
+ name: variant.name,
13
+ category: variant.category,
14
+ variant: variant.options_text,
15
+ brand: variant.brand,
16
+ price: price,
17
+ quantity: quantity
18
+ }]
19
+ }
20
+ );
21
+ }
22
+
23
+ function segmentAddtoCart(variant, quantity, currency) {
24
+ analytics.track('Product Added', {
25
+ product_id: variant.id,
26
+ sku: variant.sku,
27
+ category: variant.category,
28
+ name: variant.name,
29
+ brand: variant.brand,
30
+ price: variant.price,
31
+ currency: currency,
32
+ quantity: quantity
33
+ });
34
+ }
35
+
36
+ Spree.ready(function(){
37
+ $('body').on('product_add_to_cart', function(event) {
38
+ var variant = event.variant
39
+ var quantity = event.quantity_increment
40
+ var currency = event.cart.currency
41
+
42
+ if (typeof gtag !== 'undefined') {
43
+ gaAddToCart(variant, quantity)
44
+ }
45
+
46
+ if (typeof analytics !== 'undefined') {
47
+ segmentAddtoCart(variant, quantity, currency)
48
+ }
49
+ })
50
+ });
@@ -0,0 +1,34 @@
1
+ //= require spree/frontend
2
+
3
+ function gaRemoveFromCart(variant) {
4
+ clearGAplugins();
5
+ gtag(
6
+ 'event',
7
+ 'remove_from_cart',
8
+ {
9
+ items: [{
10
+ id: variant.sku,
11
+ name: variant.name,
12
+ price: variant.price,
13
+ variant: variant.options,
14
+ quantity: variant.quantity
15
+ }]
16
+ }
17
+ );
18
+ }
19
+
20
+ Spree.ready(function(){
21
+ $('body').on('product_remove_from_cart', function(event) {
22
+ var variant = {
23
+ sku: event.variant_sku,
24
+ name: event.variant_name,
25
+ price: event.variant_price,
26
+ options: event.variant_options,
27
+ quantity: event.variant_quantity
28
+ }
29
+
30
+ if (typeof gtag !== 'undefined') {
31
+ gaRemoveFromCart(variant)
32
+ }
33
+ })
34
+ })
@@ -1,6 +1,14 @@
1
1
  module Spree
2
2
  module Admin
3
3
  class TrackersController < ResourceController
4
+ before_action :load_data
5
+
6
+ private
7
+
8
+ def load_data
9
+ @engines = Spree::Tracker.engines.keys.sort.map { |k| [k.humanize, k] }
10
+ @stores = Spree::Store.all
11
+ end
4
12
  end
5
13
  end
6
14
  end
@@ -0,0 +1,11 @@
1
+ module SpreeAnalyticsTrackers
2
+ module CheckoutControllerDecorator
3
+ def self.included(base)
4
+ base.helper 'spree/trackers'
5
+ end
6
+ end
7
+ end
8
+
9
+ if defined?(Spree::CheckoutController)
10
+ ::Spree::CheckoutController.include(::SpreeAnalyticsTrackers::CheckoutControllerDecorator)
11
+ end
@@ -0,0 +1,13 @@
1
+ module SpreeAnalyticsTrackers
2
+ module StoreControllerDecorator
3
+ def self.included(base)
4
+ base.include ::Spree::BaseHelper
5
+
6
+ base.helper 'spree/trackers'
7
+ end
8
+ end
9
+ end
10
+
11
+ if defined?(Spree::StoreController)
12
+ ::Spree::StoreController.include(::SpreeAnalyticsTrackers::StoreControllerDecorator)
13
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeAnalyticsTrackers
2
+ module UserConfirmationsControllerDecorator
3
+ def self.included(base)
4
+ base.helper 'spree/trackers'
5
+ end
6
+ end
7
+ end
8
+
9
+ if defined?(Spree::UserConfirmationsController)
10
+ ::Spree::UserConfirmationsController.include(::SpreeAnalyticsTrackers::UserConfirmationsControllerDecorator)
11
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeAnalyticsTrackers
2
+ module UserPasswordsControllerDecorator
3
+ def self.included(base)
4
+ base.helper 'spree/trackers'
5
+ end
6
+ end
7
+ end
8
+
9
+ if defined?(Spree::UserPasswordsController)
10
+ ::Spree::UserPasswordsController.include(::SpreeAnalyticsTrackers::UserPasswordsControllerDecorator)
11
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeAnalyticsTrackers
2
+ module UserRegistrationsControllerDecorator
3
+ def self.included(base)
4
+ base.helper 'spree/trackers'
5
+ end
6
+ end
7
+ end
8
+
9
+ if defined?(Spree::UserRegistrationsController)
10
+ ::Spree::UserRegistrationsController.include(::SpreeAnalyticsTrackers::UserRegistrationsControllerDecorator)
11
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeAnalyticsTrackers
2
+ module UserSessionsControllerDecorator
3
+ def self.included(base)
4
+ base.helper 'spree/trackers'
5
+ end
6
+ end
7
+ end
8
+
9
+ if defined?(Spree::UserSessionsController)
10
+ ::Spree::UserSessionsController.include(::SpreeAnalyticsTrackers::UserSessionsControllerDecorator)
11
+ end
@@ -1,23 +1,86 @@
1
1
  module Spree
2
2
  module TrackersHelper
3
3
  def product_for_segment(product, optional = {})
4
- {
5
- product_id: product.id,
6
- sku: product.sku,
7
- category: product.category.try(:name),
8
- name: product.name,
9
- brand: product.brand.try(:name),
10
- price: product.price.to_f,
11
- currency: product.currency,
12
- url: product_url(product),
13
- }.tap do |hash|
14
- # This method returns either asset_url (Paperclip) or rails_blob_path (ActiveStorage) to return the specified image(s)
15
- if defined?(ActiveStorage) && !Rails.application.config.use_paperclip
16
- hash[:image_url] = request.base_url + Rails.application.routes.url_helpers.rails_blob_path(optional.delete(:image).attachment, only_path: true) if optional[:image]
17
- else
18
- hash[:image_url] = request.base_url + asset_url(optional.delete(:image).attachment) if optional[:image]
19
- end
4
+ cache_key = [
5
+ 'spree-segment-product',
6
+ I18n.locale,
7
+ current_currency,
8
+ product.cache_key_with_version
9
+ ].compact.join('/')
10
+
11
+ product_hash = Rails.cache.fetch(cache_key) do
12
+ {
13
+ product_id: product.id,
14
+ sku: product.sku,
15
+ category: product.category&.name,
16
+ name: product.name,
17
+ brand: product.brand&.name,
18
+ price: product.price_in(current_currency).amount&.to_f,
19
+ currency: current_currency,
20
+ url: spree.product_url(product)
21
+ }
22
+ end
23
+
24
+ product_hash.tap do |hash|
25
+ hash[:image_url] = default_image_for_product_or_variant(product)
20
26
  end.merge(optional).to_json.html_safe
21
27
  end
28
+
29
+ def ga_line_item(line_item)
30
+ variant = line_item.variant
31
+
32
+ cache_key = [
33
+ 'spree-ga-line-item',
34
+ I18n.locale,
35
+ current_currency,
36
+ line_item.cache_key_with_version,
37
+ variant.cache_key_with_version
38
+ ].compact.join('/')
39
+
40
+ Rails.cache.fetch(cache_key) do
41
+ product = line_item.product
42
+ {
43
+ id: variant.sku,
44
+ name: variant.name,
45
+ category: product.category&.name,
46
+ variant: variant.options_text,
47
+ brand: product.brand&.name,
48
+ quantity: line_item.quantity,
49
+ price: variant.price_in(current_currency).amount&.to_f
50
+ }.to_json.html_safe
51
+ end
52
+ end
53
+
54
+ def filtering_param_present?(param)
55
+ params.key?(param) && params.fetch(param).present?
56
+ end
57
+
58
+ def any_filtering_params?
59
+ filtering_params.any? { |p| filtering_param_present?(p) }
60
+ end
61
+
62
+ def filtering_params_with_values
63
+ params_with_values = {}
64
+ filtering_params.each do |param|
65
+ params_with_values[param] = params.fetch(param) if filtering_param_present?(param)
66
+ end
67
+ params_with_values
68
+ end
69
+
70
+ def segment_tracker
71
+ @segment_tracker ||= Spree::Tracker.current(:segment, current_store)
72
+ end
73
+
74
+ def segment_enabled?
75
+ segment_tracker.present?
76
+ end
77
+
78
+ def ga_tracker
79
+ @ga_tracker ||= Spree::Tracker.current(:google_analytics, current_store)
80
+ end
81
+
82
+ def ga_enabled?
83
+ ga_tracker.present?
84
+ end
22
85
  end
23
86
  end
@@ -5,20 +5,26 @@ module Spree
5
5
 
6
6
  after_commit :clear_cache
7
7
 
8
- validates :analytics_id, presence: true, uniqueness: { scope: :engine, case_sensitive: false }
8
+ validates :analytics_id, presence: true, uniqueness: { scope: [:engine, :store_id], case_sensitive: false }
9
+ validates :store, presence: true
9
10
 
10
11
  scope :active, -> { where(active: true) }
11
12
 
12
- def self.current(engine = TRACKING_ENGINES.first)
13
- tracker = Rails.cache.fetch("current_tracker/#{engine}") do
14
- send(engine).active.first
13
+ belongs_to :store
14
+
15
+ def self.current(engine = nil, store = nil)
16
+ engine ||= TRACKING_ENGINES.first
17
+ store ||= Spree::Store.default
18
+
19
+ tracker = Rails.cache.fetch("current_tracker/#{engine}/#{store.id}") do
20
+ active.find_by(store: store, engine: engine)
15
21
  end
16
22
  tracker.analytics_id.present? ? tracker : nil if tracker
17
23
  end
18
24
 
19
25
  def clear_cache
20
26
  TRACKING_ENGINES.each do |engine|
21
- Rails.cache.delete("current_tracker/#{engine}")
27
+ Rails.cache.delete("current_tracker/#{engine}/#{store_id}")
22
28
  end
23
29
  end
24
30
  end