oleksyuk / apaleo-php
Framework-agnostic PHP SDK for the Apaleo hotel PMS API
Requires
- php: ^8.4
- php-http/discovery: ^1.20
- psr/clock: ^1.0
- psr/http-client: ^1.0
- psr/http-factory: ^1.1
- psr/http-message: ^2.0
- psr/simple-cache: ^3.0
- symfony/http-client-contracts: ^3.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.95.27
- nyholm/psr7: ^1.8.2
- php-http/mock-client: ^1.6.1
- phpstan/phpstan: ^2.2.14
- phpunit/phpunit: ^13.3.4
- rector/rector: ^2.6.7
- symfony/clock: ^8.0
- symfony/http-client: ^8.0
Suggests
- symfony/http-client: Lets RequestPipeline::sendMany() dispatch requests concurrently instead of one by one.
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-24 12:49:10 UTC
README
apaleo-php
Framework-agnostic PHP SDK for the Apaleo hotel PMS API.
Installation
composer require oleksyuk/apaleo-php
Requires an actual PSR-18 HTTP client (e.g. symfony/http-client, guzzlehttp/guzzle) to be installed — php-http/discovery picks it up automatically, it doesn't invent one.
Usage
use Oleksyuk\Apaleo\ApaleoClient; $apaleo = ApaleoClient::create( clientId: 'your-client-id', clientSecret: 'your-client-secret', ); $properties = $apaleo->inventory()->properties()->list(); foreach ($properties as $property) { echo $property->id, ' — ', implode(', ', $property->name), "\n"; }
ApaleoClient::create() auto-discovers a PSR-18 client and PSR-17 factories for you. To wire your own instead (e.g. inside a DI container), use the constructor directly:
use Oleksyuk\Apaleo\ApaleoClient; use Oleksyuk\Apaleo\Auth\ClientCredentialsTokenProvider; $tokenProvider = new ClientCredentialsTokenProvider( $httpClient, $requestFactory, $streamFactory, clientId: 'your-client-id', clientSecret: 'your-client-secret', ); $apaleo = new ApaleoClient($httpClient, $requestFactory, $streamFactory, $tokenProvider);
Timeouts and retries
The SDK doesn't retry on its own: that's the HTTP client's job. With symfony/http-client, this matches what apaleo-bundle sets up: a 10 s timeout, 429 retried for every method (honoring Retry-After), and 5xx/transport errors retried only for GET/HEAD, because a 502 after a POST may still have been applied.
use Oleksyuk\Apaleo\ApaleoClient; use Oleksyuk\Apaleo\Auth\ClientCredentialsTokenProvider; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpClient\Psr18Client; use Symfony\Component\HttpClient\Retry\GenericRetryStrategy; use Symfony\Component\HttpClient\RetryableHttpClient; $safe = ['GET', 'HEAD']; $http = new RetryableHttpClient( HttpClient::create(['timeout' => 10]), new GenericRetryStrategy([0 => $safe, 429, 500 => $safe, 502 => $safe, 503 => $safe, 504 => $safe]), maxRetries: 2, ); $psr18 = new Psr18Client($http); // also serves as the PSR-17 request/stream factory $tokenProvider = new ClientCredentialsTokenProvider($psr18, $psr18, $psr18, 'your-client-id', 'your-client-secret'); $apaleo = new ApaleoClient($psr18, $psr18, $psr18, $tokenProvider, asyncHttpClient: $http);
Passing asyncHttpClient also lets sendMany() run its requests concurrently. With Guzzle, use its Middleware::retry() with the same rules.
See apaleo-bundle for a ready-made Symfony integration (autowired service, cached token, HTTP client with this timeout and retry policy).
Development
task lint # PHPStan (max level), PHP CS Fixer, Rector, composer validate task test # PHPUnit task fix # auto-fix CS Fixer / Rector issues