Skip to content

Commit fa8b354

Browse files
authored
Merge pull request #4 from FastPix/fix/data-event-remap
fix : remap data events
2 parents d692bb5 + fb74024 commit fa8b354

7 files changed

Lines changed: 139 additions & 95 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## [1.0.2]
4+
### Fixed
5+
- Fixed data event field remapping in hooks.
6+
37
## [1.0.1]
48
### Fixed
59
- Fixed missing parameters in multiple API methods.

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fastpix/sdk",
3-
"version": "1.0.1",
3+
"version": "1.0.2",
44
"type": "library",
55
"autoload": {
66
"psr-4": {

src/Hooks/EventsFieldRemapHook.php

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FastPix\Sdk\Hooks;
6+
7+
use GuzzleHttp\Psr7\Utils;
8+
use Psr\Http\Message\ResponseInterface;
9+
10+
/**
11+
* AfterSuccess hook for the `get_video_view_details` operation.
12+
*
13+
* The live API at GET /v1/data/viewlist/{viewId} returns abbreviated wire
14+
* keys on each element of data.events[] while the OpenAPI spec documents
15+
* the fully spelled-out names. Without this hook the strongly-typed
16+
* deserializer drops every event key and the caller sees empty events.
17+
*
18+
* This hook rewrites the JSON body so the generated deserializer sees
19+
* spec-shaped keys. It is a no-op for every other operation.
20+
*/
21+
class EventsFieldRemapHook implements AfterSuccessHook
22+
{
23+
private const OPERATION_ID = 'get_video_view_details';
24+
25+
/**
26+
* @var array<string, string>
27+
*/
28+
private const OUTER_MAP = [
29+
'pt' => 'player_playhead_time',
30+
'e' => 'event_name',
31+
'd' => 'event_details',
32+
'vt' => 'viewer_time',
33+
'et' => 'event_time',
34+
];
35+
36+
/**
37+
* @var array<string, string>
38+
*/
39+
private const INNER_MAP = [
40+
'br' => 'bitrate',
41+
'h' => 'height',
42+
'w' => 'width',
43+
'cd' => 'codec',
44+
'host' => 'hostName',
45+
'txt' => 'text',
46+
'c' => 'code',
47+
'err' => 'error',
48+
't' => 'type',
49+
'u' => 'url',
50+
];
51+
52+
public function afterSuccess(AfterSuccessContext $context, ResponseInterface $response): ResponseInterface
53+
{
54+
if ($context->operationID !== self::OPERATION_ID) {
55+
return $response;
56+
}
57+
58+
$statusCode = $response->getStatusCode();
59+
if ($statusCode < 200 || $statusCode >= 300) {
60+
return $response;
61+
}
62+
63+
$contentType = $response->getHeaderLine('Content-Type');
64+
if (! str_contains(strtolower($contentType), 'application/json')) {
65+
return $response;
66+
}
67+
68+
$body = (string) $response->getBody();
69+
if ($body === '') {
70+
return $response;
71+
}
72+
73+
/** @var mixed $decoded */
74+
$decoded = json_decode($body, true);
75+
if (! is_array($decoded) || json_last_error() !== JSON_ERROR_NONE || self::isList($decoded)) {
76+
return $response;
77+
}
78+
79+
if (! isset($decoded['data']) || ! is_array($decoded['data']) || self::isList($decoded['data'])) {
80+
return $response;
81+
}
82+
83+
if (! isset($decoded['data']['events']) || ! is_array($decoded['data']['events']) || ! self::isList($decoded['data']['events'])) {
84+
return $response;
85+
}
86+
87+
$rebuiltEvents = [];
88+
foreach ($decoded['data']['events'] as $event) {
89+
if (! is_array($event) || self::isList($event)) {
90+
$rebuiltEvents[] = $event;
91+
92+
continue;
93+
}
94+
95+
$rebuiltEvent = [];
96+
foreach ($event as $key => $value) {
97+
$newKey = self::OUTER_MAP[$key] ?? $key;
98+
if ($newKey === 'event_details' && is_array($value) && ! self::isList($value)) {
99+
$rebuiltInner = [];
100+
foreach ($value as $innerKey => $innerValue) {
101+
$rebuiltInner[self::INNER_MAP[$innerKey] ?? $innerKey] = $innerValue;
102+
}
103+
$rebuiltEvent[$newKey] = $rebuiltInner;
104+
} else {
105+
$rebuiltEvent[$newKey] = $value;
106+
}
107+
}
108+
$rebuiltEvents[] = $rebuiltEvent;
109+
}
110+
111+
$decoded['data']['events'] = $rebuiltEvents;
112+
113+
$rewritten = json_encode($decoded, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
114+
if ($rewritten === false) {
115+
return $response;
116+
}
117+
118+
return $response->withBody(Utils::streamFor($rewritten));
119+
}
120+
121+
/**
122+
* @param array<int|string, mixed> $value
123+
*/
124+
private static function isList(array $value): bool
125+
{
126+
return $value === [] || array_is_list($value);
127+
}
128+
}

src/Hooks/HookRegistration.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@ class HookRegistration
1818
*/
1919
public static function initHooks(Hooks $hooks): void
2020
{
21-
// $myHook = new MyHook();
22-
23-
// $hooks->registerSDKInitHook($myHook);
24-
// $hooks->registerBeforeRequestHook($myHook);
25-
// $hooks->registerAfterSuccessHook($myHook);
26-
// $hooks->registerAfterErrorHook($myHook);
21+
$eventsFieldRemapHook = new EventsFieldRemapHook();
22+
$hooks->registerAfterSuccessHook($eventsFieldRemapHook);
2723
}
2824
}

src/SDKConfiguration.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ class SDKConfiguration
2626

2727
public string $openapiDocVersion = '1.0.0';
2828

29-
public string $sdkVersion = '1.0.1';
29+
public string $sdkVersion = '1.0.2';
3030

3131
public string $genVersion = '2.801.0';
3232

33-
public string $userAgent = 'fastpix-sdk/php 1.0.1 2.801.0 1.0.0 fastpix/sdk';
33+
public string $userAgent = 'fastpix-sdk/php 1.0.2 2.801.0 1.0.0 fastpix/sdk';
3434

3535
public ?RetryConfig $retryConfig = null;
3636

0 commit comments

Comments
 (0)