Installation:
composer require answear/gls-bundle
The bundle auto-registers in config/bundles.php via Symfony Flex.
Configure:
Add your supported countries (e.g., HU, SK) in config/packages/answear_gls.yaml:
answear_gls:
countryCode: HU|SK
logger: app.logger # Optional: Custom PSR-3 logger
First Use Case: Fetch parcel shops via the service container:
$parcelShops = $this->get('Answear\GlsBundle\Service\ParcelShopsService')
->getParcelShopCollection();
Returns an array of \Answear\GlsBundle\Response\DTO\ParcelShop objects.
Fetching Parcel Shops:
ParcelShopsService for real-time data:
$service = $container->get(ParcelShopsService::class);
$shops = $service->getParcelShopCollection();
$cacheKey = 'gls_shops_' . implode('_', $service->getCountryCodes());
$shops = $cache->get($cacheKey, function() use ($service) {
return $service->getParcelShopCollection();
});
Filtering Shops:
FeatureEnum::PACKAGES):
$filtered = array_filter($shops, fn(ParcelShop $shop) =>
$shop->getFeatures()->contains(FeatureEnum::PACKAGES)
);
$monday = $shops[0]->getOpenings()->getMonday();
if ($monday->isOpen()) {
// Logic for open shops
}
Error Handling:
try {
$shops = $service->getParcelShopCollection();
} catch (ServiceUnavailableException $e) {
$this->logger->error('GLS API unavailable', ['exception' => $e]);
// Fallback: Return cached data or empty array
}
ParcelShop DTOs to form fields for user selection:
$builder->add('parcelShop', EntityType::class, [
'class' => ParcelShop::class,
'choice_label' => 'name',
'choice_value' => 'id',
]);
$client = new Client([
'handler' => HandlerStack::create([
new RetryMiddleware([
'max_retries' => 3,
'delay' => 100,
]),
]),
]);
ParcelShopsService in unit tests:
$this->mockBuilder()
->getMockBuilder(ParcelShopsService::class)
->disableOriginalConstructor()
->onlyMethods(['getParcelShopCollection'])
->getMock();
Country Code Validation:
countryCode in config. Invalid codes (e.g., US) will cause silent failures. Validate manually:
$validCountries = ['HU', 'SK', 'CZ', 'RO', 'SI', 'HR'];
if (!preg_match('/^('.implode('|', $validCountries).')(\|'.implode('|', $validCountries).')*$/', $config['countryCode'])) {
throw new \InvalidArgumentException('Invalid country codes');
}
API Endpoint Changes:
// Test for endpoint changes
$this->assertStringContainsString('new-endpoint', $service->getClient()->getConfig('base_uri'));
Feature Enum Deprecation:
MabeEnum was replaced with PHP’s native Enum in 3.0.0. Update type hints:
// Old (pre-3.0.0)
$features = $shop->getFeatures(); // Returns MabeEnum
// New (3.0.0+)
$features = $shop->getFeatures(); // Returns FeatureEnum
Null Handling:
iscodhandler may be null. Use null-safe operators:
$codHandler = $shop->getIsCodHandler() ?? false;
Enable Logging: Configure a custom logger to debug API responses:
answear_gls:
logger: app.debug_logger # Monolog channel
Log the raw response in a custom ParcelShopsService decorator.
Guzzle Debugging: Add Guzzle’s debug handler to inspect HTTP traffic:
$stack = HandlerStack::create();
$stack->push(Middleware::tap(function (RequestInterface $request) use ($logger) {
$logger->debug('GLS Request', ['url' => $request->getUri(), 'method' => $request->getMethod()]);
}));
Custom DTOs:
Extend ParcelShop to add business logic:
class ExtendedParcelShop extends ParcelShop {
public function isOpenNow(): bool {
$now = new \DateTime();
$today = $this->getOpenings()->getDay($now->format('N'));
return $today->isOpen() && $today->isOpenAt($now);
}
}
Override API Client:
Replace the default Guzzle client in services.yaml:
services:
Answear\GlsBundle\Service\ParcelShopsService:
arguments:
$client: '@custom_gls_client' # Your Guzzle client
Add New Features:
Extend FeatureEnum for custom GLS features:
enum FeatureEnum {
case PACKAGES;
case PARCELS;
case // Your custom feature
case CUSTOM_FEATURE;
}
Update the ParcelShop DTO to include the new feature.
$batchSize = 100;
foreach (array_chunk($shops, $batchSize) as $batch) {
// Process batch
}
function getParcelShopsGenerator(ParcelShopsService $service): Generator {
foreach ($service->getParcelShopCollection() as $shop) {
yield $shop;
}
}
How can I help you explore Laravel packages today?