-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Using v12.0.0 of this package, when you create/update/get a tracking object and deserialize that data using the response object's toArray() method, the "tag" field is improperly deserialized into an array instead of a string.
$client = new \Tracking\Client([
'apiKey' => 'API KEY',
'authenticationType' => \Tracking\Config::AUTHENTICATION_TYPE_API_KEY,
]);
$trackingInfo = $client->tracking->getTrackingById('TRACKING ID');
var_dump($trackingInfo->toArray());This will print something like:
array(75) {
["id"]=>
string(32) "[obfuscated]"
["legacy_id"]=>
string(24) "[obfuscated]"
["created_at"]=>
string(25) "2025-08-01T16:51:26+00:00"
["updated_at"]=>
string(25) "2025-08-01T16:51:29+00:00"
["tracking_number"]=>
string(22) "[obfuscated]"
["slug"]=>
string(4) "usps"
["active"]=>
bool(false)
...
["source"]=>
string(3) "api"
["tag"]=>
array(0) {
}
["subtag"]=>
string(13) "Delivered_001"
Notice how "tag" is an array rather than a string.
It has to do with this line:
/**
* @var string|null|\Tracking\Model\Tag Current status of tracking. (
*/
public $tag;
Since $tag is type-hinted as an object, Symfony will deserialize it into an array. \Tracking\Model\Tag is a class with only constants, and no properties or methods, so it can never represent a track's string tag and should not be included in the type hint.
Furthermore, since Symfony's serializer is used to hydrate the response object, there's no way to pull "tag" from the response.
$client = new \Tracking\Client([
'apiKey' => 'API KEY',
'authenticationType' => \Tracking\Config::AUTHENTICATION_TYPE_API_KEY,
]);
$trackingInfo = $client->tracking->getTrackingById('TRACKING ID');
var_dump($trackingInfo->tag);This yields an empty Tag object with no reference to the actual tag.
object(Tracking\Model\Tag)#3132 (0) {
}
Every response object that type-hints its $tag property needs to be updated as well.
\Tracking\Model\Tag would be more useful if converted to a string-backed enum, in which case it would be properly deserialized:
enum Tag: string
{
case Pending = 'Pending';
case InfoReceived = 'InfoReceived';
case InTransit = 'InTransit';
case OutForDelivery = 'OutForDelivery';
case AttemptFail = 'AttemptFail';
case Delivered = 'Delivered';
case AvailableForPickup = 'AvailableForPickup';
case Exception = 'Exception';
case Expired = 'Expired';
}