Skip to content

Commit d4f8357

Browse files
committed
Set idgoal to 0 on ecommerce parameters (#162)
1 parent 7f250e8 commit d4f8357

File tree

12 files changed

+279
-146
lines changed

12 files changed

+279
-146
lines changed

core/src/main/java/org/matomo/java/tracking/MatomoRequest.java

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
/**
4343
* A class that implements the <a href="https://developer.matomo.org/api-reference/tracking-api">
44-
* Matomo Tracking HTTP API</a>. These requests can be sent using {@link MatomoTracker}.
44+
* Matomo Tracking HTTP API</a>. These requests can be sent using {@link MatomoTracker}.
4545
*
4646
* @author brettcsorba
4747
*/
@@ -55,17 +55,20 @@ public class MatomoRequest {
5555

5656
/**
5757
* The ID of the website we're tracking a visit/action for. Only needed, if no default site id is
58-
* configured
58+
* configured.
5959
*/
6060
@TrackingParameter(name = "rec")
6161
@Default
6262
private Boolean required = true;
6363

6464
/**
6565
* The ID of the website we're tracking a visit/action for. Only needed, if no default site id is
66-
* configured
66+
* configured.
6767
*/
68-
@TrackingParameter(name = "idsite")
68+
@TrackingParameter(
69+
name = "idsite",
70+
min = 1
71+
)
6972
private Integer siteId;
7073

7174
/**
@@ -130,7 +133,7 @@ public class MatomoRequest {
130133
* database). Then you would manually increment the counts by one on each new visit or "session",
131134
* depending on how you choose to define a visit.
132135
*/
133-
@TrackingParameter(name = "_idvc")
136+
@TrackingParameter(name = "_idvc", min = 0)
134137
private Integer visitorVisitCount;
135138

136139
/**
@@ -156,9 +159,9 @@ public class MatomoRequest {
156159
/**
157160
* The campaign keyword (see
158161
* <a href="https://matomo.org/docs/tracking-campaigns/">Tracking Campaigns</a>). Used to
159-
* populate
160-
* the <em>Referrers &gt; Campaigns</em> report (clicking on a campaign loads all keywords for
161-
* this campaign). This parameter will only be used for the first pageview of a visit.
162+
* populate the <em>Referrers &gt; Campaigns</em> report (clicking on a campaign loads all
163+
* keywords for this campaign). This parameter will only be used for the first pageview of a
164+
* visit.
162165
*/
163166
@TrackingParameter(name = "_rck")
164167
private String campaignKeyword;
@@ -172,19 +175,31 @@ public class MatomoRequest {
172175
/**
173176
* The current hour (local time).
174177
*/
175-
@TrackingParameter(name = "h")
178+
@TrackingParameter(
179+
name = "h",
180+
min = 0,
181+
max = 23
182+
)
176183
private Integer currentHour;
177184

178185
/**
179186
* The current minute (local time).
180187
*/
181-
@TrackingParameter(name = "m")
188+
@TrackingParameter(
189+
name = "m",
190+
min = 0,
191+
max = 59
192+
)
182193
private Integer currentMinute;
183194

184195
/**
185196
* The current second (local time).
186197
*/
187-
@TrackingParameter(name = "s")
198+
@TrackingParameter(
199+
name = "s",
200+
min = 0,
201+
max = 59
202+
)
188203
private Integer currentSecond;
189204

190205
/**
@@ -321,7 +336,10 @@ public class MatomoRequest {
321336
* results displayed on the results page. When keywords are tracked with &search_count=0 they will
322337
* appear in the "No Result Search Keyword" report.
323338
*/
324-
@TrackingParameter(name = "search_count")
339+
@TrackingParameter(
340+
name = "search_count",
341+
min = 0
342+
)
325343
private Long searchResultsCount;
326344

327345
/**
@@ -335,9 +353,9 @@ public class MatomoRequest {
335353

336354
/**
337355
* If specified, the tracking request will trigger a conversion for the goal of the website being
338-
* tracked with this ID.
356+
* tracked with this ID. The value 0 tracks an ecommerce interaction.
339357
*/
340-
@TrackingParameter(name = "idgoal")
358+
@TrackingParameter(name = "idgoal", min = 0)
341359
private Integer goalId;
342360

343361
/**
@@ -365,39 +383,39 @@ public class MatomoRequest {
365383
/**
366384
* How long it took to connect to server.
367385
*/
368-
@TrackingParameter(name = "pf_net")
386+
@TrackingParameter(name = "pf_net", min = 0)
369387
private Long networkTime;
370388

371389
/**
372390
* How long it took the server to generate page.
373391
*/
374-
@TrackingParameter(name = "pf_srv")
392+
@TrackingParameter(name = "pf_srv", min = 0)
375393
private Long serverTime;
376394

377395
/**
378396
* How long it takes the browser to download the response from the server.
379397
*/
380-
@TrackingParameter(name = "pf_tfr")
398+
@TrackingParameter(name = "pf_tfr", min = 0)
381399
private Long transferTime;
382400

383401
/**
384402
* How long the browser spends loading the webpage after the response was fully received until the
385403
* user can start interacting with it.
386404
*/
387-
@TrackingParameter(name = "pf_dm1")
405+
@TrackingParameter(name = "pf_dm1", min = 0)
388406
private Long domProcessingTime;
389407

390408
/**
391409
* How long it takes for the browser to load media and execute any Javascript code listening for
392410
* the DOMContentLoaded event.
393411
*/
394-
@TrackingParameter(name = "pf_dm2")
412+
@TrackingParameter(name = "pf_dm2", min = 0)
395413
private Long domCompletionTime;
396414

397415
/**
398416
* How long it takes the browser to execute Javascript code waiting for the window.load event.
399417
*/
400-
@TrackingParameter(name = "pf_onl")
418+
@TrackingParameter(name = "pf_onl", min = 0)
401419
private Long onloadTime;
402420

403421
/**
@@ -450,8 +468,7 @@ public class MatomoRequest {
450468

451469
/**
452470
* The unique string identifier for the ecommerce order (required when tracking an ecommerce
453-
* order). you must set &idgoal=0 in the request to track an ecommerce interaction: cart update or
454-
* an ecommerce order.
471+
* order).
455472
*/
456473
@TrackingParameter(name = "ec_id")
457474
private String ecommerceId;
@@ -546,13 +563,13 @@ public class MatomoRequest {
546563
/**
547564
* An override value for the visitor's latitude, eg 22.456.
548565
*/
549-
@TrackingParameter(name = "lat")
566+
@TrackingParameter(name = "lat", min = -90, max = 90)
550567
private Double visitorLatitude;
551568

552569
/**
553570
* An override value for the visitor's longitude, eg 22.456.
554571
*/
555-
@TrackingParameter(name = "long")
572+
@TrackingParameter(name = "long", min = -180, max = 180)
556573
private Double visitorLongitude;
557574

558575
/**
@@ -670,23 +687,22 @@ public class MatomoRequest {
670687
*
671688
* <p>Optional for crash analytics
672689
*/
673-
@TrackingParameter(name = "cra_rl")
690+
@TrackingParameter(name = "cra_rl", min = 0)
674691
private Integer crashLine;
675692

676693
/**
677694
* The column within the line where the crash occurred.
678695
*
679696
* <p>Optional for crash analytics
680697
*/
681-
@TrackingParameter(name = "cra_rc")
698+
@TrackingParameter(name = "cra_rc", min = 0)
682699
private Integer crashColumn;
683700

684701
/**
685702
* The Matomo session ID sent as a cookie {@code MATOMO_SESSID}.
686703
*
687704
* <p>If not null a cookie with the name {@code MATOMO_SESSID} will be sent with the value of
688-
* this
689-
* parameter.
705+
* this parameter.
690706
*/
691707
private String sessionId;
692708

core/src/main/java/org/matomo/java/tracking/MatomoTracker.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public MatomoTracker(
142142
public void sendRequest(@NonNull MatomoRequest request) {
143143
if (trackerConfiguration.isEnabled()) {
144144
log.debug("Sending request via GET: {}", request);
145-
validate(request);
145+
applyGoalIdAndCheckSiteId(request);
146146
initializeSender();
147147
sender.sendSingle(request);
148148
} else {
@@ -192,7 +192,7 @@ public <T> CompletableFuture<T> sendRequestAsync(
192192
@NonNull Function<MatomoRequest, T> callback
193193
) {
194194
if (trackerConfiguration.isEnabled()) {
195-
validate(request);
195+
applyGoalIdAndCheckSiteId(request);
196196
log.debug("Sending async request via GET: {}", request);
197197
initializeSender();
198198
CompletableFuture<MatomoRequest> future = sender.sendSingleAsync(request);
@@ -202,9 +202,17 @@ public <T> CompletableFuture<T> sendRequestAsync(
202202
return CompletableFuture.completedFuture(null);
203203
}
204204

205-
private void validate(
205+
private void applyGoalIdAndCheckSiteId(
206206
@NonNull MatomoRequest request
207207
) {
208+
if (request.getGoalId() == null && (
209+
request.getEcommerceId() != null || request.getEcommerceRevenue() != null
210+
|| request.getEcommerceDiscount() != null || request.getEcommerceItems() != null
211+
|| request.getEcommerceLastOrderTimestamp() != null
212+
|| request.getEcommerceShippingCost() != null || request.getEcommerceSubtotal() != null
213+
|| request.getEcommerceTax() != null)) {
214+
request.setGoalId(0);
215+
}
208216
if (trackerConfiguration.getDefaultSiteId() == null && request.getSiteId() == null) {
209217
throw new IllegalArgumentException("No default site ID and no request site ID is given");
210218
}
@@ -256,7 +264,7 @@ public void sendBulkRequest(
256264
) {
257265
if (trackerConfiguration.isEnabled()) {
258266
for (MatomoRequest request : requests) {
259-
validate(request);
267+
applyGoalIdAndCheckSiteId(request);
260268
}
261269
log.debug("Sending requests via POST: {}", requests);
262270
initializeSender();
@@ -311,7 +319,7 @@ public CompletableFuture<Void> sendBulkRequestAsync(
311319
) {
312320
if (trackerConfiguration.isEnabled()) {
313321
for (MatomoRequest request : requests) {
314-
validate(request);
322+
applyGoalIdAndCheckSiteId(request);
315323
}
316324
log.debug("Sending async requests via POST: {}", requests);
317325
initializeSender();

core/src/main/java/org/matomo/java/tracking/QueryCreator.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
@RequiredArgsConstructor
2929
class QueryCreator {
3030

31-
private static final TrackingParameterMethod[] TRACKING_PARAMETER_METHODS = initializeTrackingParameterMethods();
31+
private static final TrackingParameterMethod[] TRACKING_PARAMETER_METHODS =
32+
initializeTrackingParameterMethods();
3233

3334
private final TrackerConfiguration trackerConfiguration;
3435

@@ -44,15 +45,20 @@ private static TrackingParameterMethod[] initializeTrackingParameterMethods() {
4445
}
4546

4647
private static void addMethods(
47-
Collection<TrackingParameterMethod> methods, Member member, TrackingParameter trackingParameter
48+
Collection<TrackingParameterMethod> methods,
49+
Member member,
50+
TrackingParameter trackingParameter
4851
) {
4952
try {
50-
for (PropertyDescriptor pd : Introspector.getBeanInfo(MatomoRequest.class).getPropertyDescriptors()) {
53+
for (PropertyDescriptor pd : Introspector.getBeanInfo(MatomoRequest.class)
54+
.getPropertyDescriptors()) {
5155
if (member.getName().equals(pd.getName())) {
5256
String regex = trackingParameter.regex();
5357
methods.add(TrackingParameterMethod
5458
.builder()
5559
.parameterName(trackingParameter.name())
60+
.min(trackingParameter.min())
61+
.max(trackingParameter.max())
5662
.maxLength(trackingParameter.maxLength())
5763
.method(pd.getReadMethod())
5864
.pattern(regex == null || regex.isEmpty() || regex.trim().isEmpty() ? null :
@@ -97,7 +103,10 @@ String createQuery(
97103
for (Entry<Long, Object> entry : request.getDimensions().entrySet()) {
98104
if (entry.getKey() != null && entry.getValue() != null) {
99105
appendAmpersand(query);
100-
query.append("dimension").append(entry.getKey()).append('=').append(encode(entry.getValue().toString()));
106+
query.append("dimension")
107+
.append(entry.getKey())
108+
.append('=')
109+
.append(encode(entry.getValue().toString()));
101110
}
102111
}
103112
}

core/src/main/java/org/matomo/java/tracking/RequestValidator.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,16 @@ static void validate(
2525
@Nullable
2626
CharSequence authToken
2727
) {
28-
if (request.getSiteId() != null && request.getSiteId() < 0) {
29-
throw new IllegalArgumentException("Site ID must not be negative");
30-
}
31-
if (request.getGoalId() == null && (
32-
request.getEcommerceId() != null || request.getEcommerceRevenue() != null
33-
|| request.getEcommerceDiscount() != null || request.getEcommerceItems() != null
34-
|| request.getEcommerceLastOrderTimestamp() != null
35-
|| request.getEcommerceShippingCost() != null || request.getEcommerceSubtotal() != null
36-
|| request.getEcommerceTax() != null)) {
37-
throw new MatomoException("Goal ID must be set if ecommerce parameters are used");
38-
}
28+
3929
if (request.getSearchResultsCount() != null && request.getSearchQuery() == null) {
4030
throw new MatomoException("Search query must be set if search results count is set");
4131
}
4232
if (authToken == null) {
4333
if (request.getVisitorLongitude() != null || request.getVisitorLatitude() != null
4434
|| request.getVisitorRegion() != null || request.getVisitorCity() != null
45-
|| request.getVisitorCountry() != null) {
35+
|| request.getVisitorCountry() != null || request.getVisitorIp() != null) {
4636
throw new MatomoException(
47-
"Auth token must be present if longitude, latitude, region, city or country are set");
37+
"Auth token must be present if visitor longitude, latitude, region, city, country or IP are set");
4838
}
4939
if (request.getRequestTimestamp() != null && request
5040
.getRequestTimestamp()

core/src/main/java/org/matomo/java/tracking/TrackingParameter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
String regex() default "";
2222

23+
double min() default Double.MIN_VALUE;
24+
25+
double max() default Double.MAX_VALUE;
26+
2327
int maxLength() default Integer.MAX_VALUE;
2428

2529
}

core/src/main/java/org/matomo/java/tracking/TrackingParameterMethod.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ class TrackingParameterMethod {
2323

2424
Pattern pattern;
2525

26+
double min;
27+
28+
double max;
29+
2630
int maxLength;
2731

2832
void validateParameterValue(@NonNull Object parameterValue) {
@@ -34,12 +38,30 @@ void validateParameterValue(@NonNull Object parameterValue) {
3438
pattern
3539
));
3640
}
37-
if (parameterValue.toString().length() > maxLength) {
41+
if (maxLength != 0 && parameterValue.toString().length() > maxLength) {
3842
throw new MatomoException(String.format("Invalid value for %s. Must be less or equal than %d characters",
3943
parameterName,
4044
maxLength
4145
));
4246
}
47+
if (parameterValue instanceof Number) {
48+
Number number = (Number) parameterValue;
49+
if (number.doubleValue() < min) {
50+
throw new MatomoException(String.format(
51+
"Invalid value for %s. Must be greater or equal than %s",
52+
parameterName,
53+
min % 1 == 0 ? Long.toString((long) min) : min
54+
));
55+
56+
}
57+
if (number.doubleValue() > max) {
58+
throw new MatomoException(String.format(
59+
"Invalid value for %s. Must be less or equal than %s",
60+
parameterName,
61+
max % 1 == 0 ? Long.toString((long) max) : max
62+
));
63+
}
64+
}
4365
}
4466

4567
}

0 commit comments

Comments
 (0)