Skip to content

Commit 7574d26

Browse files
authored
Rework event limiter by chunking events on posting to Google Analytics (#12)
2 parents 715ee8a + 2e0574b commit 7574d26

File tree

2 files changed

+94
-113
lines changed

2 files changed

+94
-113
lines changed

src/Analytics.php

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ class Analytics extends Model\ToArray implements Facade\Analytics, Facade\Export
1919
private $debug;
2020
private $measurement_id;
2121
private $api_secret;
22-
private $postOnEventLimit = false;
2322

2423
protected $non_personalized_ads;
2524
protected $timestamp_micros;
@@ -101,12 +100,6 @@ public function setTimestamp($microOrUnix)
101100
return $this;
102101
}
103102

104-
public function postOnEventLimit(bool $push = true)
105-
{
106-
$this->postOnEventLimit = $push;
107-
return $this;
108-
}
109-
110103
/**
111104
* Add user property to your analytics request \
112105
* Maximum is 25 per request
@@ -137,33 +130,19 @@ public function addUserProperty(UserProperty $prop)
137130
*/
138131
public function addEvent(Model\Event $event)
139132
{
140-
if (count($this->events) >= 25) {
141-
throw new GA4Exception("Can't add more than 25 events");
142-
}
143-
144-
$arr = $event->toArray();
145-
if (isset($arr['items'])) {
146-
var_dump($arr);
147-
exit;
148-
}
149-
150133
$this->events[] = $event->toArray();
151134

152-
if (count($this->events) >= 25 && $this->postOnEventLimit === true) {
153-
$this->post();
154-
}
155135
return $this;
156136
}
157137

158138
/**
159139
* Push your current stack to Google Analytics \
160140
* Will reset the events list on success
161141
*
162-
* @var bool $skipReset Avoid resetting events list on success, default: false
163142
* @return bool Whether the request returned status 200
164143
* @throws AlexWestergaard\PhpGa4\GA4Exception
165144
*/
166-
public function post($skipReset = false)
145+
public function post()
167146
{
168147
$errorStack = null;
169148

@@ -174,45 +153,50 @@ public function post($skipReset = false)
174153
$errorStack = $catch['error'];
175154
$reqBody = $catch['data'];
176155

177-
$kB = 1024;
178-
if (mb_strlen(json_encode($reqBody)) > ($kB * 130)) {
179-
$errorStack = new GA4Exception("Request body exceeds 130kB", $errorStack);
180-
}
181156

182-
if ($errorStack instanceof GA4Exception) {
183-
throw $errorStack;
184-
}
157+
$eventsList = array_chunk($reqBody['events'] ?? [], 25);
185158

186-
$guzzle = new Guzzle();
187-
$res = $guzzle->request('POST', $url, ['json' => $reqBody]);
159+
foreach ($eventsList as $events) {
160+
$reqBody['events'] = $events;
188161

189-
$resCode = $res->getStatusCode() ?? 0;
190-
if ($resCode !== 200) {
191-
$errorStack = new GA4Exception("Request received code {$resCode}", $errorStack);
192-
}
162+
$kB = 1024;
163+
if (mb_strlen(json_encode($reqBody)) > ($kB * 130)) {
164+
$errorStack = new GA4Exception("Request body exceeds 130kB", $errorStack);
165+
}
193166

194-
$resBody = $res->getBody()->getContents();
195-
$data = @json_decode($resBody, true);
167+
if ($errorStack instanceof GA4Exception) {
168+
throw $errorStack;
169+
}
170+
171+
$guzzle = new Guzzle();
172+
$res = $guzzle->request('POST', $url, ['json' => $reqBody]);
196173

197-
if (empty($resBody)) {
198-
$errorStack = new GA4Exception("Received not body", $errorStack);
199-
} elseif (json_last_error() != JSON_ERROR_NONE || $data === null) {
200-
$errorStack = new GA4Exception("Could not parse response", $errorStack);
201-
} elseif (!empty($data['validationMessages'])) {
202-
foreach ($data['validationMessages'] as $msg) {
203-
$errorStack = new GA4Exception('Validation Message: ' . $msg['validationCode'] . '[' . $msg['fieldPath'] . ']: ' . $msg['description'], $errorStack);
174+
$resCode = $res->getStatusCode() ?? 0;
175+
if ($resCode !== 200) {
176+
$errorStack = new GA4Exception("Request received code {$resCode}", $errorStack);
177+
}
178+
179+
$resBody = $res->getBody()->getContents();
180+
$data = @json_decode($resBody, true);
181+
182+
if (empty($resBody)) {
183+
$errorStack = new GA4Exception("Received not body", $errorStack);
184+
} elseif (json_last_error() != JSON_ERROR_NONE || $data === null) {
185+
$errorStack = new GA4Exception("Could not parse response", $errorStack);
186+
} elseif (!empty($data['validationMessages'])) {
187+
foreach ($data['validationMessages'] as $msg) {
188+
$errorStack = new GA4Exception('Validation Message: ' . $msg['validationCode'] . '[' . $msg['fieldPath'] . ']: ' . $msg['description'], $errorStack);
189+
}
204190
}
205191
}
206192

207193
if ($errorStack instanceof GA4Exception) {
208194
throw $errorStack;
209195
}
210196

211-
if (!$skipReset) {
212-
$this->events = [];
213-
}
197+
$this->events = []; // Reset events list
214198

215-
return $resCode === 200;
199+
return true;
216200
}
217201

218202
public function toArray(bool $isParent = false, $childErrors = null): array

test/AnalyticsTest.php

Lines changed: 62 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -110,96 +110,93 @@ public function testPrebuildEvents()
110110

111111
$getDefaultEventsByFile = glob(__DIR__ . '/../src/Event/*.php');
112112

113-
foreach (array_chunk($getDefaultEventsByFile, 25) as $chunk) {
113+
foreach ($getDefaultEventsByFile as $file) {
114+
$eventName = 'AlexWestergaard\\PhpGa4\\Event\\' . basename($file, '.php');
114115

115-
foreach ($chunk as $file) {
116-
$eventName = 'AlexWestergaard\\PhpGa4\\Event\\' . basename($file, '.php');
116+
$this->assertTrue(class_exists($eventName), $eventName);
117117

118-
$this->assertTrue(class_exists($eventName), $eventName);
118+
$event = new $eventName;
119+
$required = $event->getRequiredParams();
120+
$params = array_unique(array_merge($event->getParams(), $required));
119121

120-
$event = new $eventName;
121-
$required = $event->getRequiredParams();
122-
$params = array_unique(array_merge($event->getParams(), $required));
122+
$this->assertEquals(
123+
strtolower(basename($file, '.php')),
124+
strtolower(strtr($event->getName(), ['_' => ''])),
125+
strtolower(basename($file, '.php')) . ' is not equal to ' . strtolower(strtr($event->getName(), ['_' => '']))
126+
);
123127

124-
$this->assertEquals(
125-
strtolower(basename($file, '.php')),
126-
strtolower(strtr($event->getName(), ['_' => ''])),
127-
strtolower(basename($file, '.php')) . ' is not equal to ' . strtolower(strtr($event->getName(), ['_' => '']))
128-
);
129-
130-
if (in_array('currency', $params)) {
131-
$event->setCurrency($this->prefill['currency']);
132-
if (in_array('value', $params)) {
133-
$event->setValue(9.99);
134-
}
128+
if (in_array('currency', $params)) {
129+
$event->setCurrency($this->prefill['currency']);
130+
if (in_array('value', $params)) {
131+
$event->setValue(9.99);
135132
}
133+
}
136134

137-
if (in_array('price', $params)) {
138-
$event->setPrice(9.99);
139-
}
135+
if (in_array('price', $params)) {
136+
$event->setPrice(9.99);
137+
}
140138

141-
if (in_array('quantity', $params)) {
142-
$event->setQuantity(9.99);
143-
}
139+
if (in_array('quantity', $params)) {
140+
$event->setQuantity(9.99);
141+
}
144142

145-
if (in_array('payment_type', $params)) {
146-
$event->setPaymentType('credit card');
147-
}
143+
if (in_array('payment_type', $params)) {
144+
$event->setPaymentType('credit card');
145+
}
148146

149-
if (in_array('shipping_tier', $params)) {
150-
$event->setShippingTier('ground');
151-
}
147+
if (in_array('shipping_tier', $params)) {
148+
$event->setShippingTier('ground');
149+
}
152150

153-
if (in_array('items', $params)) {
154-
if (method_exists($event, 'addItem')) {
155-
$event->addItem($this->item);
156-
} elseif (method_exists($event, 'setItem')) {
157-
$event->setItem($this->item);
158-
}
151+
if (in_array('items', $params)) {
152+
if (method_exists($event, 'addItem')) {
153+
$event->addItem($this->item);
154+
} elseif (method_exists($event, 'setItem')) {
155+
$event->setItem($this->item);
159156
}
157+
}
160158

161-
if (in_array('virtual_currency_name', $params)) {
162-
$event->setVirtualCurrencyName($this->prefill['currency_virtual']);
163-
164-
if (in_array('value', $params)) {
165-
$event->setValue(9.99);
166-
}
159+
if (in_array('virtual_currency_name', $params)) {
160+
$event->setVirtualCurrencyName($this->prefill['currency_virtual']);
167161

168-
if (in_array('item_name', $params)) {
169-
$event->setItemName('CookieBite');
170-
}
162+
if (in_array('value', $params)) {
163+
$event->setValue(9.99);
171164
}
172165

173-
if (in_array('character', $params)) {
174-
$event->setCharacter('AlexWestergaard');
175-
176-
if (in_array('level', $params)) {
177-
$event->setLEvel(3);
178-
}
179-
180-
if (in_array('score', $params)) {
181-
$event->setScore(500);
182-
}
166+
if (in_array('item_name', $params)) {
167+
$event->setItemName('CookieBite');
183168
}
169+
}
184170

185-
if (in_array('location_id', $params)) {
186-
$event->setLocationId('ChIJeRpOeF67j4AR9ydy_PIzPuM');
187-
}
171+
if (in_array('character', $params)) {
172+
$event->setCharacter('AlexWestergaard');
188173

189-
if (in_array('transaction_id', $params)) {
190-
$event->setTransactionId('O6435DK');
174+
if (in_array('level', $params)) {
175+
$event->setLEvel(3);
191176
}
192177

193-
if (in_array('achievement_id', $params)) {
194-
$event->setAchievementId('achievement_buy_5_items');
178+
if (in_array('score', $params)) {
179+
$event->setScore(500);
195180
}
181+
}
196182

197-
$this->assertTrue(is_array($event->toArray()), $eventName);
183+
if (in_array('location_id', $params)) {
184+
$event->setLocationId('ChIJeRpOeF67j4AR9ydy_PIzPuM');
185+
}
198186

199-
$this->analytics->addEvent($event);
187+
if (in_array('transaction_id', $params)) {
188+
$event->setTransactionId('O6435DK');
200189
}
201190

202-
$this->assertTrue($this->analytics->post());
191+
if (in_array('achievement_id', $params)) {
192+
$event->setAchievementId('achievement_buy_5_items');
193+
}
194+
195+
$this->assertTrue(is_array($event->toArray()), $eventName);
196+
197+
$this->analytics->addEvent($event);
203198
}
199+
200+
$this->assertTrue($this->analytics->post());
204201
}
205202
}

0 commit comments

Comments
 (0)