Skip to content

Commit

Permalink
Ecommerce implementation (matomo-org#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yury Krainik committed Aug 8, 2018
1 parent 5b88662 commit 6a54bf9
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 0 deletions.
20 changes: 20 additions & 0 deletions MatomoTracker.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
1FDC917F1F1A65150046F506 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FDC917D1F1A65150046F506 /* Application.swift */; };
1FDC91801F1A65150046F506 /* Device.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FDC917E1F1A65150046F506 /* Device.swift */; };
5804E9A4755E642D58301330 /* Pods_MatomoTrackerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63DC1BA4812B98CA8037194A /* Pods_MatomoTrackerTests.framework */; };
6E2B7439211AE65600E8BD0D /* EcommerceItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E2B7438211AE65600E8BD0D /* EcommerceItem.swift */; };
6E2B743B211B004700E8BD0D /* EcommerceOrder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E2B743A211B004700E8BD0D /* EcommerceOrder.swift */; };
6E2B743D211B08FC00E8BD0D /* EcommerceUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E2B743C211B08FC00E8BD0D /* EcommerceUpdate.swift */; };
FDCA325A2093BFFB007D6B42 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = FDCA32592093BFFB007D6B42 /* README.md */; };
FDE4330E209367A000A9CC36 /* .travis.yml in Resources */ = {isa = PBXBuildFile; fileRef = FDE4330D209367A000A9CC36 /* .travis.yml */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -85,6 +88,9 @@
2FD38CC515C49A9A8922407D /* Pods-MatomoTrackerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatomoTrackerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-MatomoTrackerTests/Pods-MatomoTrackerTests.release.xcconfig"; sourceTree = "<group>"; };
63DC1BA4812B98CA8037194A /* Pods_MatomoTrackerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MatomoTrackerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
68F0C25DEF98C13D32CC46DD /* Pods_PiwikTrackerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PiwikTrackerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6E2B7438211AE65600E8BD0D /* EcommerceItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EcommerceItem.swift; sourceTree = "<group>"; };
6E2B743A211B004700E8BD0D /* EcommerceOrder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EcommerceOrder.swift; sourceTree = "<group>"; };
6E2B743C211B08FC00E8BD0D /* EcommerceUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EcommerceUpdate.swift; sourceTree = "<group>"; };
8F688B0F18F298B5E61552AC /* Pods-PiwikTrackerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PiwikTrackerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PiwikTrackerTests/Pods-PiwikTrackerTests.release.xcconfig"; sourceTree = "<group>"; };
ECADEAA1E653EE3DA30A1FDC /* Pods-MatomoTrackerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatomoTrackerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MatomoTrackerTests/Pods-MatomoTrackerTests.debug.xcconfig"; sourceTree = "<group>"; };
FD284F50B998823EAFB0CEE9 /* Pods-PiwikTrackerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PiwikTrackerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PiwikTrackerTests/Pods-PiwikTrackerTests.debug.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -164,6 +170,7 @@
1FCA6D3D1DBE0B2F0033F01C /* MatomoTracker */ = {
isa = PBXGroup;
children = (
6EDE180B211AE5F60017CCC9 /* Ecommerce */,
1F80856D1E6B4B8000A61AAF /* Extensions */,
1F0A15CC1E6335CA00FEAE72 /* Event */,
1F092C191E26B44500394B30 /* Dispatcher.swift */,
Expand Down Expand Up @@ -212,6 +219,16 @@
name = Pods;
sourceTree = "<group>";
};
6EDE180B211AE5F60017CCC9 /* Ecommerce */ = {
isa = PBXGroup;
children = (
6E2B7438211AE65600E8BD0D /* EcommerceItem.swift */,
6E2B743A211B004700E8BD0D /* EcommerceOrder.swift */,
6E2B743C211B08FC00E8BD0D /* EcommerceUpdate.swift */,
);
name = Ecommerce;
sourceTree = "<group>";
};
ADAE39D28F21B08F51A5C6A8 /* Frameworks */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -385,12 +402,15 @@
1FDC91801F1A65150046F506 /* Device.swift in Sources */,
1F3CA58C1E09A30600121FDC /* Queue.swift in Sources */,
1F0A15D01E6335E900FEAE72 /* Session.swift in Sources */,
6E2B743D211B08FC00E8BD0D /* EcommerceUpdate.swift in Sources */,
6E2B743B211B004700E8BD0D /* EcommerceOrder.swift in Sources */,
1F092C1A1E26B44500394B30 /* Dispatcher.swift in Sources */,
1F38EBF81EE568D10021FBF8 /* Logger.swift in Sources */,
1FC2B429201F8C010061F5AD /* CustomVariable.swift in Sources */,
1FCFF0241F82C7A50038BC17 /* CustomDimension.swift in Sources */,
1F7C667F1F8C096F0066CC64 /* MainThread.swift in Sources */,
1F80856F1E6B4B9800A61AAF /* Locale+HttpAcceptLanguage.swift in Sources */,
6E2B7439211AE65600E8BD0D /* EcommerceItem.swift in Sources */,
1FD9E01C201B22A8006C3AD3 /* EventSerializer.swift in Sources */,
1F0A15CE1E6335D800FEAE72 /* Visitor.swift in Sources */,
1FDC917F1F1A65150046F506 /* Application.swift in Sources */,
Expand Down
33 changes: 33 additions & 0 deletions MatomoTracker/EcommerceItem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// EcommerceItem.swift
// MatomoTracker
//
// Created by Yury Krainik on 8/8/18.
// Copyright © 2018 Yury Krainik. All rights reserved.
//

import Foundation

public struct EcommerceItem {
let sku: String
let name: String?
let category: String?
let price: Double
let quantity: Double
let formatter: NumberFormatter

public func jsonObject() -> Any {

var dict = ["sku": sku, "quantity": formatter.string(from: quantity as NSNumber), "price": formatter.string(from: price as NSNumber)]

if let name = name {
dict["name"] = name
}

if let category = category {
dict["category"] = category
}

return dict
}
}
53 changes: 53 additions & 0 deletions MatomoTracker/EcommerceOrder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// EcommerceOrder.swift
// MatomoTracker
//
// Created by Yury Krainik on 8/8/18.
// Copyright © 2018 Yury Krainik. All rights reserved.
//

import Foundation

public class EcommerceOrder: EcommerceUpdate {
public let orderId: String
public var subtotal: Double?
public var shipping: Double?
public var discount: Double?
public var tax: Double?

init(orderId: String, formatter: NumberFormatter) {
self.orderId = orderId
super.init(formatter: formatter)
}

public override func jsonDict() -> [String : Any] {
var dict = super.jsonDict()
dict["id"] = orderId

if let subtotal = subtotal {
dict["ec_st"] = formatter.string(from: subtotal as NSNumber)
}

if let shipping = shipping {
dict["ec_sh"] = formatter.string(from: shipping as NSNumber)
}

if let discount = discount {
dict["ec_dt"] = formatter.string(from: discount as NSNumber)
}

if let tax = tax {
dict["ec_tx"] = formatter.string(from: tax as NSNumber)
}

return dict
}

public override func clearAll() {
super.clearAll()
subtotal = nil
shipping = nil
discount = nil
tax = nil
}
}
54 changes: 54 additions & 0 deletions MatomoTracker/EcommerceUpdate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// EcommerceUpdate.swift
// MatomoTracker
//
// Created by Yury Krainik on 8/8/18.
// Copyright © 2018 Matomo. All rights reserved.
//

import Foundation

public class EcommerceUpdate {
public var items: [String: EcommerceItem] = [:]
public var revenue: Double = 0
public let formatter: NumberFormatter

init(formatter: NumberFormatter) {
self.formatter = formatter
}

public func jsonDict() -> [String: Any] {

let jsonItems = items.map { item -> Any in
item.value.jsonObject()
}

return ["idgoal": "0", "ec_items": jsonItems, "revenue": formatter.string(from: revenue as NSNumber) ?? "0"]
}

public func variables() throws -> [CustomVariable] {

return try jsonDict().enumerated().map { (arg) -> CustomVariable in

let (offset, element) = arg

let data = try JSONSerialization.data(withJSONObject: element.value, options: [])
let jsonValue = String.init(data: data, encoding: String.Encoding.utf8) ?? ""

return CustomVariable(index: UInt(offset), name: element.key, value: jsonValue)
}
}

public func addItem(_ item: EcommerceItem) {
items[item.sku] = item
}

public func removeItem(_ item: EcommerceItem) {
items.removeValue(forKey: item.sku)
}

public func clearAll() {
items.removeAll()
revenue = 0
}
}
17 changes: 17 additions & 0 deletions MatomoTracker/MatomoTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,23 @@ extension MatomoTracker {
}
}

extension MatomoTracker {
public func cartUpdate(_ ecommerceUpdate: EcommerceUpdate) {
do {
let variables = try ecommerceUpdate.variables()
let event = Event(tracker: self, action: [], variables: variables)
queue(event: event)
} catch let error {
self.logger.warning("Failed dispatching events with error \(error)")
}

print("Here: \(ecommerceUpdate.jsonDict())")
}

public func cartOrder(_ ecommerceOrder: EcommerceOrder) {
print("Here: \(ecommerceOrder.jsonDict())")
}
}

extension MatomoTracker {

Expand Down

0 comments on commit 6a54bf9

Please sign in to comment.