znojil / nette-heureka
🧩 Nette DI extension for the Heureka API library.
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/znojil/nette-heureka
Requires
- php: ^8.2
- nette/di: ^3.1
- znojil/heureka: ^1.0
Requires (Dev)
- nette/tester: ^2.5
- phpstan/phpstan: ^2.1
README
A simple Nette DI extension for the znojil/heureka PHP client, allowing for easy integration and configuration of one or more API clients.
🚀 Installation
Install via Composer:
composer require znojil/nette-heureka
⚙️ Configuration
First, register the extension in your config.neon:
extensions: heureka: Znojil\Nette\Heureka\DI\HeurekaExtension
Single Client Setup
If you only need to communicate with one Heureka region, you can configure a single client. This client service (Znojil\Heureka\Client) will be registered and autowired by the Nette DI container.
heureka: region: cz key: 'your-secret-api-key'
Configuration options:
region: (required) The Heureka region to use. The value must be one of the cases inZnojil\Heureka\Enum\Region.key: (optional) Your API key for authenticated requests.httpClient: (optional) A custom HTTP client implementingZnojil\Heureka\Http\Client(e.g.,@myCustomHttpClient).
Multiple Clients Setup
If you need to work with multiple regions or API keys, you can configure multiple named clients.
heureka: cz_shop: region: cz key: 'your-main-cz-api-key' sk_shop: region: sk key: 'your-sk-subsidiary-api-key' cz_shop_no_key: region: cz
In this setup, a single Znojil\Nette\Heureka\ClientProvider service is registered. Individual clients are not autowired.
🛠️ Advanced Configuration
Custom HTTP Client
You can provide a custom HTTP client that implements the Znojil\Heureka\Http\Client interface. This interface requires PSR-7 compatibility (Psr\Http\Message\ResponseInterface and UriInterface) but is not PSR-18.
The interface signature:
interface Client{ function send( string $method, Message\UriInterface $uri, array $headers = [], mixed $data = null, array $options = [] ): Message\ResponseInterface; }
This is useful for adding custom headers, timeouts, proxy settings, or other HTTP-specific configuration.
Using an Existing Service
Reference an existing service by name using the @ prefix:
services: myCustomHttpClient: Your\Custom\HttpClient heureka: region: cz key: 'your-api-key' httpClient: @myCustomHttpClient
Using a Class Name (Auto-instantiated)
Provide a fully qualified class name as a string:
heureka: region: cz key: 'your-api-key' httpClient: Your\Custom\HttpClient
Configuring HTTP Client with Inline Service Definitions
You can configure any HTTP client directly in your NEON configuration using Nette DI's inline service definitions. This example demonstrates the approach using the default implementation (Znojil\Heureka\Http\ZnojilClient), but the same technique works with any custom client.
Example: Custom User-Agent and Timeouts
parameters: curlOptMap: userAgent: ::CURLOPT_USERAGENT timeout: ::CURLOPT_TIMEOUT connectTimeout: ::CURLOPT_CONNECTTIMEOUT services: myCustomHttpClient: Znojil\Heureka\Http\ZnojilClient( Znojil\Http\Client( defaultCurlOptions: [ %curlOptMap.userAgent%: 'MyApp/1.0 (Heureka Integration)' %curlOptMap.timeout%: 30 %curlOptMap.connectTimeout%: 10 ] ) ) heureka: region: cz key: 'your-api-key' httpClient: @myCustomHttpClient
Why use parameter mapping?
The parameters.curlOptMap approach is necessary because NEON's ::CONSTANT_NAME syntax works only for values, not for array keys. Since cURL options require constants as keys (e.g., CURLOPT_USERAGENT => 'value'), we use parameter mapping to work around this limitation.
How it works:
- Define constants in
parameterssection:userAgent: ::CURLOPT_USERAGENT(value position - works!) - Reference them as keys using
%curlOptMap.userAgent%(expands to the constant value)
This keeps your configuration readable and type-safe while leveraging cURL's native options without resorting to magic numbers.
📖 Usage
Single Client
When using the single client setup, you can inject the Znojil\Heureka\Client directly into your services.
<?php declare(strict_types=1); use Znojil\Heureka\Client; final class SomeService{ public function __construct( private readonly Client $heurekaClient ){} public function doSomething(): void{ // Use the client to send a request // $this->heurekaClient->send(...); } }
Multiple Clients
When using the multiple clients setup, inject the Znojil\Nette\Heureka\ClientProvider and use it to get the client you need by its name.
<?php declare(strict_types=1); use Znojil\Nette\Heureka\ClientProvider; final class AnotherService{ public function __construct( private readonly ClientProvider $clientProvider ){} public function doSomethingWithMultipleClients(): void{ $czClient = $this->clientProvider->getClient('cz_shop'); // $czClient->send(...); $skClient = $this->clientProvider->getClient('sk_shop'); // $skClient->send(...); } }
The ClientProvider has the following public methods:
getClient(string $name): Client: Returns the client by name. ThrowsZnojil\Nette\Heureka\Exception\ClientNotFoundExceptionif the name is invalid.hasClient(string $name): bool: Checks if a client with the given name is configured.getNames(): array: Returns an array of all configured client names.
📄 License
This library is open-source software licensed under the MIT license.