Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ jobs:
fail-fast: false
matrix:
include:
- php: '8.2'
laravel: '10.x'
testbench: '^8.0'
pest: '^2.0'
phpstan: '^1.12'
larastan: '^2.0'
- php: '8.2'
laravel: '11.x'
testbench: '^9.0'
Expand All @@ -40,6 +34,12 @@ jobs:
pest: '^4.0'
phpstan: '^2.1'
larastan: '^3.0'
- php: '8.5'
laravel: '13.x'
testbench: '^11.0'
pest: '^4.0'
phpstan: '^2.1'
larastan: '^3.0'

steps:
- name: Checkout
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@ All notable changes to `laravel-ares` will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.1.0]

### Added
- `cache.enabled` config option (`ARES_CACHE_ENABLED`) to disable caching entirely.
- `cache.store` (`ARES_CACHE_STORE`) to select a specific cache store, and
`cache.prefix` (`ARES_CACHE_PREFIX`) to customize cache key prefixes.
- CI coverage for PHP 8.5.

### Changed
- **Breaking:** the `cache_ttl` config key moved under a `cache` array as
`cache.ttl`. Republish the config or rename the key when upgrading.
- Configuration is now read through Laravel's built-in typed config accessors.

### Removed
- **Breaking:** dropped support for Laravel 10; Laravel 11+ is now required.

## [1.0.0]

Initial public release.
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
## Requirements

- PHP 8.2+
- Laravel 10, 11, 12, or 13
- Laravel 11, 12, or 13

## Installation

Expand All @@ -38,7 +38,10 @@ php artisan vendor:publish --tag=laravel-ares::config
| Key | Default | Description |
| --- | --- | --- |
| `api_url` | `https://ares.gov.cz/ekonomicke-subjekty-v-be/rest` | Base URL for the ARES REST API |
| `cache_ttl` | `86400` | Cache lifetime for successful lookups in seconds |
| `cache.enabled` | `true` | Enable response caching; set to `false` to disable caching entirely |
| `cache.ttl` | `86400` | Cache lifetime for successful lookups in seconds |
| `cache.store` | `null` | Cache store to use (`null` = default store) |
| `cache.prefix` | `ares:v1:company:` | Prefix for ARES cache keys |
| `log_channel` | `stack` | Laravel log channel used for client errors |
| `http_options.timeout` | `5.0` | Request timeout in seconds |
| `http_options.connect_timeout` | `3.0` | Connection timeout in seconds |
Expand All @@ -49,7 +52,10 @@ php artisan vendor:publish --tag=laravel-ares::config
Environment overrides:

- `ARES_API_URL`
- `ARES_CACHE_ENABLED`
- `ARES_CACHE_TTL`
- `ARES_CACHE_STORE`
- `ARES_CACHE_PREFIX`
- `ARES_LOG_CHANNEL`
- `ARES_HTTP_TIMEOUT`
- `ARES_HTTP_CONNECT_TIMEOUT`
Expand Down
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@
],
"require": {
"php": "^8.2",
"illuminate/contracts": "^10.0|^11.0|^12.0|^13.0",
"illuminate/http": "^10.0|^11.0|^12.0|^13.0",
"illuminate/support": "^10.0|^11.0|^12.0|^13.0",
"illuminate/contracts": "^11.0|^12.0|^13.0",
"illuminate/http": "^11.0|^12.0|^13.0",
"illuminate/support": "^11.0|^12.0|^13.0",
"guzzlehttp/guzzle": "^7.0",
"nyoncode/laravel-package-toolkit": "^2.0"
},
"require-dev": {
"larastan/larastan": "^2.9|^3.0",
"laravel/pint": "^1.13",
"orchestra/testbench": "^8.0|^9.0|^10.0|^11.0",
"orchestra/testbench": "^9.0|^10.0|^11.0",
"pestphp/pest": "^2.0|^3.0|^4.0",
"phpstan/phpstan": "^1.12|^2.1"
},
Expand Down
28 changes: 19 additions & 9 deletions config/ares.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,40 @@
| ARES API URL
|--------------------------------------------------------------------------
*/
'api_url' => env('ARES_API_URL', 'https://ares.gov.cz/ekonomicke-subjekty-v-be/rest'),
'api_url' => (string) env('ARES_API_URL', 'https://ares.gov.cz/ekonomicke-subjekty-v-be/rest'),

/*
|--------------------------------------------------------------------------
| Cache TTL (seconds)
| Cache
|--------------------------------------------------------------------------
|
| Successful lookups are cached to reduce load on the ARES API. Set
| "enabled" to false (or ARES_CACHE_ENABLED=false) to turn caching off
| completely — every lookup will then hit the ARES API directly.
|
*/
'cache_ttl' => env('ARES_CACHE_TTL', 86400),
'cache' => [
'enabled' => (bool) env('ARES_CACHE_ENABLED', true),
'ttl' => (int) env('ARES_CACHE_TTL', 86400),
'store' => env('ARES_CACHE_STORE'),
'prefix' => (string) env('ARES_CACHE_PREFIX', 'ares:v1:company:'),
],

/*
|--------------------------------------------------------------------------
| Logging channel
|--------------------------------------------------------------------------
*/
'log_channel' => env('ARES_LOG_CHANNEL', 'stack'),
'log_channel' => (string) env('ARES_LOG_CHANNEL', 'stack'),

/*
|--------------------------------------------------------------------------
| Guzzle HTTP options
|--------------------------------------------------------------------------
*/
'http_options' => [
'timeout' => env('ARES_HTTP_TIMEOUT', 5.0),
'connect_timeout' => env('ARES_HTTP_CONNECT_TIMEOUT', 3.0),
'timeout' => (float) env('ARES_HTTP_TIMEOUT', 5.0),
'connect_timeout' => (float) env('ARES_HTTP_CONNECT_TIMEOUT', 3.0),
],

/*
Expand All @@ -38,9 +48,9 @@
|--------------------------------------------------------------------------
*/
'indexing' => [
'enabled' => env('ARES_INDEXING_ENABLED', true),
'auto_index' => env('ARES_AUTO_INDEX', true),
'stale_days' => env('ARES_STALE_DAYS', 30),
'enabled' => (bool) env('ARES_INDEXING_ENABLED', true),
'auto_index' => (bool) env('ARES_AUTO_INDEX', true),
'stale_days' => (int) env('ARES_STALE_DAYS', 30),
'queue' => env('ARES_INDEX_QUEUE'),
'connection' => env('ARES_INDEX_CONNECTION'),
],
Expand Down
75 changes: 14 additions & 61 deletions src/Providers/AresServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,27 @@ public function configure(Packager $packager): void
TestAresCommand::class,
IndexAresCommand::class,
])
->hasAbout()
->hasTranslations('resources/lang')
->registeredPackage(function ($packager) {
$this->app->singleton(SubjectSearchService::class, fn () => new SubjectSearchService);

$this->app->bind(AresClientInterface::class, function (Application $app): AresClient {
$indexingEnabled = $this->configBool('ares.indexing.enabled');
$config = $app->make('config');
$indexingEnabled = $config->boolean('ares.indexing.enabled');
$cacheEnabled = $config->boolean('ares.cache.enabled');
$cacheStore = $config->get('ares.cache.store');

return new AresClient(
baseUrl: $this->configString('ares.api_url'),
cacheTtl: $this->configInt('ares.cache_ttl'),
logger: $app->make(LogManager::class)->channel($this->configString('ares.log_channel')),
cache: $app->make(CacheFactory::class)->store(),
httpTimeout: $this->configFloat('ares.http_options.timeout'),
httpConnectTimeout: $this->configFloat('ares.http_options.connect_timeout'),
autoIndex: $indexingEnabled && $this->configBool('ares.indexing.auto_index'),
baseUrl: $config->string('ares.api_url'),
cacheTtl: $cacheEnabled ? $config->integer('ares.cache.ttl') : 0,
logger: $app->make(LogManager::class)->channel($config->string('ares.log_channel')),
cache: $app->make(CacheFactory::class)->store(is_string($cacheStore) && $cacheStore !== '' ? $cacheStore : null),
httpTimeout: $config->float('ares.http_options.timeout'),
httpConnectTimeout: $config->float('ares.http_options.connect_timeout'),
autoIndex: $indexingEnabled && $config->boolean('ares.indexing.auto_index'),
searchService: $indexingEnabled ? $app->make(SubjectSearchService::class) : null,
cachePrefix: $config->string('ares.cache.prefix'),
);
});

Expand All @@ -73,59 +78,7 @@ public function aboutData(): array
'Author' => 'Ondřej Nyklíček',
'Client contract' => AresClientInterface::class,
'Facade alias' => 'Ares',
'Cache support' => 'enabled',
'Cache support' => $this->app->make('config')->boolean('ares.cache.enabled') ? 'enabled' : 'disabled',
];
}

/**
* Get a string value from configuration.
*
* @param string $key The configuration key
* @return string The configuration value or empty string if not found
*/
private function configString(string $key): string
{
$value = config($key);

return is_string($value) ? $value : '';
}

/**
* Get an integer value from configuration.
*
* @param string $key The configuration key
* @return int The configuration value or 0 if not found/invalid
*/
private function configInt(string $key): int
{
$value = config($key);

return is_int($value) ? $value : (is_numeric($value) ? (int) $value : 0);
}

/**
* Get a boolean value from configuration.
*
* @param string $key The configuration key
* @return bool The configuration value
*/
private function configBool(string $key): bool
{
$value = config($key);

return filter_var($value, FILTER_VALIDATE_BOOLEAN);
}

/**
* Get a float value from configuration.
*
* @param string $key The configuration key
* @return float The configuration value or 0.0 if not found/invalid
*/
private function configFloat(string $key): float
{
$value = config($key);

return is_float($value) || is_int($value) ? (float) $value : (is_numeric($value) ? (float) $value : 0.0);
}
}
6 changes: 4 additions & 2 deletions src/Services/AresClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ final class AresClient implements AresClientInterface
* Create a new ARES client instance.
*
* @param string $baseUrl The base URL for the ARES API
* @param int $cacheTtl The cache time-to-live in seconds
* @param int $cacheTtl The cache time-to-live in seconds; 0 disables caching
* @param LoggerInterface $logger The logger instance
* @param Cache $cache The cache repository
* @param float $httpTimeout The HTTP request timeout in seconds
* @param float $httpConnectTimeout The HTTP connection timeout in seconds
* @param string $cachePrefix The prefix used for cache keys
*/
public function __construct(
private readonly string $baseUrl,
Expand All @@ -49,6 +50,7 @@ public function __construct(
private readonly float $httpConnectTimeout = self::DEFAULT_HTTP_CONNECT_TIMEOUT,
private readonly bool $autoIndex = false,
private readonly ?SubjectSearchService $searchService = null,
private readonly string $cachePrefix = self::CACHE_PREFIX,
) {
$this->processedBaseUrl = rtrim($this->baseUrl, '/');
}
Expand Down Expand Up @@ -210,7 +212,7 @@ public function normalizeIc(string $ic): string

private function cacheKey(string $ic): string
{
return self::CACHE_PREFIX.$ic;
return $this->cachePrefix.$ic;
}

/**
Expand Down
5 changes: 4 additions & 1 deletion tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ protected function defineEnvironment($app): void
$app['config']->set('app.fallback_locale', 'en');
$app['config']->set('cache.default', 'array');
$app['config']->set('ares.api_url', 'https://ares.gov.cz/ekonomicke-subjekty-v-be/rest');
$app['config']->set('ares.cache_ttl', 3600);
$app['config']->set('ares.cache.enabled', true);
$app['config']->set('ares.cache.ttl', 3600);
$app['config']->set('ares.cache.store', null);
$app['config']->set('ares.cache.prefix', 'ares:v1:company:');
$app['config']->set('ares.log_channel', 'stack');
$app['config']->set('ares.http_options.timeout', 5.0);
$app['config']->set('ares.http_options.connect_timeout', 3.0);
Expand Down