Skip to content
Merged
28 changes: 18 additions & 10 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ jobs:

strategy:
matrix:
php: ['8.1', '8.2', '8.3']
symfony: ['6.4', '7.1']
php: [ '8.2', '8.3', '8.4', '8.5' ]
symfony: [ '7.4', '8.0', '8.1' ]
exclude:
- php: '8.1'
symfony: '7.1'
- php: '8.2'
symfony: '8.0'
- php: '8.2'
symfony: '8.1'
- php: '8.3'
symfony: '8.0'
- php: '8.3'
symfony: '8.1'

runs-on: ubuntu-latest

Expand All @@ -27,15 +33,17 @@ jobs:
steps:
# https://github.com/marketplace/actions/checkout
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6

# https://github.com/marketplace/actions/setup-php-action
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mbstring, intl
extensions: mbstring, intl, :redis, redis-6.3.0
ini-values: post_max_size=256M, max_execution_time=180
env:
fail-fast: true

- name: Check PHP version
run: php -v
Expand All @@ -48,10 +56,10 @@ jobs:

- name: Install Symfony ${{ matrix.symfony }} packages
run: |
composer update symfony/http-client:${{ matrix.symfony }}
composer update symfony/cache:${{ matrix.symfony }}
composer update symfony/stopwatch:${{ matrix.symfony }}
composer update symfony/property-access:${{ matrix.symfony }}
composer update symfony/http-client:^${{ matrix.symfony }}
composer update symfony/cache:^${{ matrix.symfony }}
composer update symfony/stopwatch:^${{ matrix.symfony }}
composer update symfony/property-access:^${{ matrix.symfony }}

- name: Lint PHP files
run: |
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,20 @@ See the [documentation](docs/README.md) for more.
You can use this with the [frontend](https://github.com/strata/frontend) package to help you build a frontend website.

## Status
Please note this software is in development, usage may change before the 1.0 release.
Please note this software is in development and usage may change before the 1.0 release.

## Requirements

* PHP 8.1+
* PHP 8.2+
* Supports Symfony 7.4+
* [Composer](https://getcomposer.org/)

## Installation

Install via Composer:

```
composer require strata/data:^0.9
composer require strata/data
```

## Thanks to
Expand Down
25 changes: 14 additions & 11 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@
}
],
"require": {
"php": "^8.1",
"php": "^8.2",
"erusev/parsedown-extra": "^0.8",
"laminas/laminas-feed": "^2.22",
"league/commonmark": "^2.4",
"spatie/yaml-front-matter": "^2.0",
"symfony/http-client": "^6.4|^7.1",
"symfony/cache": "^6.4|^7.1",
"symfony/stopwatch": "^6.4|^7.1",
"symfony/property-access": "^6.4|^7.1",
"symfony/monolog-bundle": "^3.7"
"symfony/event-dispatcher": "^7.4|^8.0",
"symfony/http-client": "^7.4|^8.0",
"symfony/http-foundation": "^7.4|^8.0",
"symfony/cache": "^7.4|^8.0",
"symfony/stopwatch": "^7.4|^8.0",
"symfony/property-access": "^7.4|^8.0"
},
"autoload": {
"psr-4": {
Expand All @@ -30,10 +31,12 @@
]
},
"require-dev": {
"phpunit/phpunit": "^10.5",
"squizlabs/php_codesniffer": "^3.10",
"phpstan/phpstan": "^1.11",
"roave/security-advisories": "dev-latest"
"phpunit/phpunit": "^11.5",
"squizlabs/php_codesniffer": "^4.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"roave/security-advisories": "dev-latest",
"rector/rector": "^2.4"
},
"scripts": {
"phpcs": [
Expand All @@ -59,7 +62,7 @@
"extra": {
"symfony": {
"allow-contrib": false,
"require": "7.2.*"
"require": "8.0.*"
}
}
}
25 changes: 9 additions & 16 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,14 @@

declare(strict_types=1);

use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/src',
//__DIR__ . '/tests',
]);

// register a single rule
$rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);

// define sets of rules
$rectorConfig->sets([
LevelSetList::UP_TO_PHP_81
use Rector\Php81\Rector\Property\ReadOnlyPropertyRector;

return RectorConfig::configure()
->withPaths([__DIR__ . '/src', __DIR__ . '/tests'])
->withPhpSets(php82: true)
->withPreparedSets(symfonyCodeQuality: true)
->withComposerBased(symfony: true)
->withSkip([
ReadOnlyPropertyRector::class
]);
};
6 changes: 2 additions & 4 deletions src/Cache/DataCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
*/
class DataCache implements CacheItemPoolInterface, TagAwareAdapterInterface, PruneableInterface
{
private CacheItemPoolInterface $cache;
protected array $tags = [];
protected int $lifetime;

Expand All @@ -35,12 +34,11 @@ class DataCache implements CacheItemPoolInterface, TagAwareAdapterInterface, Pru
* @param CacheItemPoolInterface $cache
* @param ?int $defaultLifetime Default cache lifetime for data cache, defaults to 1 hour if not set
*/
public function __construct(CacheItemPoolInterface $cache, ?int $defaultLifetime = null)
public function __construct(private CacheItemPoolInterface $cache, ?int $defaultLifetime = null)
{
if ($defaultLifetime === null) {
$defaultLifetime = CacheLifetime::HOUR;
}
$this->cache = $cache;
$this->setLifetime($defaultLifetime);
}

Expand Down Expand Up @@ -92,7 +90,7 @@ public function isPruneable(): bool
public function setTags(array $tags)
{
if (!$this->isTaggable()) {
throw new CacheException(sprintf('Tags are not supported by your cache adapter %s', get_class($this->cache)));
throw new CacheException(sprintf('Tags are not supported by your cache adapter %s', $this->cache::class));
}
$this->tags = $tags;
return $this;
Expand Down
25 changes: 8 additions & 17 deletions src/Cache/DataHistory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,17 @@
class DataHistory
{
const CACHE_KEY_PREFIX = 'history_';

private CacheItemPoolInterface $cache;
private int $cacheLifetime;
private int $maxHistoryDays = 30;
private array $historyItems = [];

/**
* Constructor
*
* @param CacheItemPoolInterface $cache PSR-6 cache
* @param int $lifetime Default cache lifetime for data cache, defaults to 2 months if not set
* @param int $cacheLifetime Default cache lifetime for data cache, defaults to 2 months if not set
*/
public function __construct(CacheItemPoolInterface $cache, int $lifetime = 2 * CacheLifetime::MONTH)
public function __construct(private CacheItemPoolInterface $cache, private int $cacheLifetime = 2 * CacheLifetime::MONTH)
{
$this->cache = $cache;
$this->cacheLifetime = $lifetime;
}

/**
Expand Down Expand Up @@ -120,16 +115,12 @@ public function getLastItem($key, string $field = null)
return $item;
}

switch ($field) {
case 'updated':
return $item['updated'];
case 'content_hash':
return $item['content_hash'];
case 'metadata':
return $item['metadata'];
default:
throw new CacheException(sprintf('Cannot return history field "%s" since not set', $field));
}
return match ($field) {
'updated' => $item['updated'],
'content_hash' => $item['content_hash'],
'metadata' => $item['metadata'],
default => throw new CacheException(sprintf('Cannot return history field "%s" since not set', $field)),
};
}

/**
Expand Down
15 changes: 5 additions & 10 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,33 +52,29 @@ public function getPagination(): Pagination
/**
* Whether a offset exists
* @link https://php.net/manual/en/arrayaccess.offsetexists.php
* @param mixed $offset
* @return bool true on success or false on failure.
*/
public function offsetExists($offset): bool
public function offsetExists(mixed $offset): bool
{
return isset($this->collection[$offset]);
}

/**
* Offset to retrieve
* @link https://php.net/manual/en/arrayaccess.offsetget.php
* @param mixed $offset
* @return mixed Can return all value types.
*/
public function offsetGet($offset): mixed
public function offsetGet(mixed $offset): mixed
{
return isset($this->collection[$offset]) ? $this->collection[$offset] : null;
return $this->collection[$offset] ?? null;
}

/**
* Offset to set
* @link https://php.net/manual/en/arrayaccess.offsetset.php
* @param mixed $offset
* @param mixed $value
* @return void
*/
public function offsetSet($offset, $value): void
public function offsetSet(mixed $offset, mixed $value): void
{
if (is_null($offset)) {
$this->collection[] = $value;
Expand All @@ -90,10 +86,9 @@ public function offsetSet($offset, $value): void
/**
* Offset to unset
* @link https://php.net/manual/en/arrayaccess.offsetunset.php
* @param mixed $offset
* @return void
*/
public function offsetUnset($offset): void
public function offsetUnset(mixed $offset): void
{
unset($this->collection[$offset]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/DataProviderCommonTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function setBaseUri(string $baseUri)
public function getBaseUri(): string
{
if (empty($this->baseUri)) {
throw new BaseUriException(sprintf('Base URI not set, please set via %s::setBaseUri()', get_class($this)));
throw new BaseUriException(sprintf('Base URI not set, please set via %s::setBaseUri()', $this::class));
}

return $this->baseUri;
Expand Down
3 changes: 1 addition & 2 deletions src/DataProviderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,10 @@ public function getDefaultDecoder(): ?DecoderInterface;
/**
* Decode response
*
* @param mixed $response
* @param DecoderInterface|null $decoder Optional decoder, if not set uses getDefaultDecoder()
* @return mixed
*/
public function decode($response, ?DecoderInterface $decoder = null);
public function decode(mixed $response, ?DecoderInterface $decoder = null);

/**
* Is the cache enabled?
Expand Down
5 changes: 2 additions & 3 deletions src/Decode/StringNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ class StringNormalizer
/**
* Take a string or object, and return a string representing the content
*
* @param mixed $data
* @return string
* @throws DecoderException
*/
public static function getString($data): string
public static function getString(mixed $data): string
{
if (is_string($data)) {
return $data;
Expand All @@ -30,7 +29,7 @@ public static function getString($data): string
if (method_exists($data, '__toString')) {
return $data->__toString();
}
throw new DecoderException(sprintf('Cannot convert object of type "%s" into a string', get_class($data)));
throw new DecoderException(sprintf('Cannot convert object of type "%s" into a string', $data::class));
}
throw new DecoderException(sprintf('Cannot convert %s into a string', gettype($data)));
}
Expand Down
5 changes: 1 addition & 4 deletions src/Event/DecodeEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ class DecodeEvent extends RequestEventAbstract
{
const NAME = 'data.request.decode';

private $decodedData;

public function __construct($decodedData, string $requestId, string $uri, array $context = [])
public function __construct(private $decodedData, string $requestId, string $uri, array $context = [])
{
$this->decodedData = $decodedData;
parent::__construct($requestId, $uri, $context);
}

Expand Down
5 changes: 1 addition & 4 deletions src/Event/FailureEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ class FailureEvent extends RequestEventAbstract
{
const NAME = 'data.request.failure';

private \Exception $exception;

public function __construct(\Exception $exception, string $requestId, string $uri, array $context = [])
public function __construct(private \Exception $exception, string $requestId, string $uri, array $context = [])
{
$this->exception = $exception;
parent::__construct($requestId, $uri, $context);
}

Expand Down
9 changes: 1 addition & 8 deletions src/Event/RequestEventAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,8 @@

abstract class RequestEventAbstract extends Event
{
private string $requestId;
private string $uri;
private array $context;

public function __construct(string $requestId, string $uri, array $context = [])
public function __construct(private string $requestId, private string $uri, private array $context = [])
{
$this->requestId = $requestId;
$this->uri = $uri;
$this->context = $context;
}

/**
Expand Down
5 changes: 1 addition & 4 deletions src/Event/Subscriber/LoggerSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@ class LoggerSubscriber implements EventSubscriberInterface
{
const PREFIX = '(Strata Data) ';

private LoggerInterface $logger;

public function __construct(LoggerInterface $logger)
public function __construct(private LoggerInterface $logger)
{
$this->logger = $logger;
}

public static function getSubscribedEvents(): array
Expand Down
Loading