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: 8 additions & 4 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ on:
pull_request: ~

env:
PHP_VERSION: 8.1
APPLICATION_NAME: antifraud
GCP_PROJECT_ID: liniopay-sandbox
GCP_REGION: us-east4
Expand All @@ -16,17 +15,21 @@ env:
NEW_RELIC_APP_NAME: ${{ secrets.NEW_RELIC_APP_NAME }}

jobs:
test-php-81:
name: Code quality PHP 8.1
test-php:
name: Code quality PHP ${{ matrix.php-version }}
runs-on: [ubuntu-latest]
strategy:
fail-fast: false
matrix:
php-version: ['8.2.35', '8.3.36', '8.4.27', '8.5.12']
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
php-version: ${{ matrix.php-version }}
coverage: xdebug

- name: Validate composer.json and composer.lock
Expand All @@ -36,6 +39,7 @@ jobs:
run: composer install --prefer-dist --no-progress

- name: Lint
if: matrix.php-version == '8.2.35'
run: composer lint:check

- name: PHP Static Analysis
Expand Down
4 changes: 2 additions & 2 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
$config
->setRules([
'@Symfony' => true,
'@PHP81Migration' => true,
'@PHPUnit60Migration:risky' => true,
'@PHP8x1Migration' => true,
'@PHPUnit6x0Migration:risky' => true,
'array_indentation' => true,
'array_syntax' => ['syntax' => 'short'],
'blank_line_after_opening_tag' => true,
Expand Down
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
language: php

php:
- 8.1
- '8.2.35'
- '8.3.36'
- '8.4.27'
- '8.5.12'

cache:
directories:
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,35 @@ a coherent base for Linio components:

## Install

### PHP requirements

Supported PHP branches and minimum patch versions are:

| PHP branch | Minimum version |
| --- | --- |
| 8.2 | 8.2.35 |
| 8.3 | 8.3.36 |
| 8.4 | 8.4.27 |
| 8.5 | 8.5.12 |

Later patch releases within these branches are supported and recommended. PHP 8.1
and older, earlier patches, and unlisted branches are not supported.

These minimum versions contain the fixes for CVE-2026-109618 and CVE-2026-109619
described in the [PHP security advisory of October 21, 2026](https://www.php.net/archive/2026.php#2026-10-21-5).
The vulnerabilities are in the PHP runtime, not in this library. Updating this
package alone does not patch PHP: update the interpreter used by every deployment,
including PHP-FPM, Apache, CGI, FrankenPHP, LiteSpeed, CLI and CI, and restart all
web workers after the update. Verify the PHP version used by the web server
separately from `php -v`, which only checks the CLI runtime.

Composer rejects versions outside the supported ranges, but it cannot update the
runtime or protect deployments that bypass platform checks. Do not use
`--ignore-platform-reqs` or a `config.platform.php` override to simulate a patched
runtime. Run `composer check-platform-reqs --no-dev` on the deployed environment
and verify the web runtime separately. Configuration workarounds are not a
complete fix and are not applied by this library.

The recommended way to install Linio Common is [through composer](http://getcomposer.org).

```
Expand All @@ -24,6 +53,15 @@ run PHPUnit.
$ composer install
$ vendor/bin/phpunit

Run code formatting on PHP 8.2, the lowest supported PHP branch, to avoid
introducing syntax unsupported by that branch:

$ composer lint
$ composer lint:check

CI checks formatting on PHP 8.2 and runs static analysis and unit tests on every
supported PHP branch.

## Collections

This component has a direct dependency on doctrine/collections. You are encouraged
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
"type": "library",
"license": "BSD-3-Clause",
"require": {
"php": "^8.1",
"php": "~8.2.35 || ~8.3.36 || ~8.4.27 || ~8.5.12",
"doctrine/collections": "^1.6"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.6",
"friendsofphp/php-cs-fixer": "^3.95.27",
"monolog/monolog": "^2.0",
"phpstan/phpstan": "^1.9",
"phpunit/phpunit": "^9.4"
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/ClientException.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function __construct(
int $statusCode = self::DEFAULT_STATUS_CODE,
string $message = ExceptionTokens::INVALID_REQUEST,
array $errors = [],
Throwable $previous = null
?Throwable $previous = null
) {
parent::__construct($token, $statusCode, $message, $errors, $previous);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/DomainException.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function __construct(
int $statusCode = self::DEFAULT_STATUS_CODE,
string $message = ExceptionTokens::AN_ERROR_HAS_OCCURRED,
array $errors = [],
Throwable $previous = null
?Throwable $previous = null
) {
if (!$this->isExceptionToken($token)) {
throw new InvalidArgumentException(ExceptionTokens::INVALID_EXCEPTION_TOKEN, 500);
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/EntityNotFoundException.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function __construct(
string $token = ExceptionTokens::ENTITY_NOT_FOUND,
int $statusCode = self::DEFAULT_STATUS_CODE,
array $errors = [],
Throwable $previous = null
?Throwable $previous = null
) {
$formattedIdentifier = $this->getIdentifier($identifier);
$message = sprintf('Could not find [%s] identified by %s!', $entity, $formattedIdentifier);
Expand Down
7 changes: 4 additions & 3 deletions src/Type/Collection/FixedTypedCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Linio\Common\Type\Collection;

use Closure;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor;
use InvalidArgumentException;
Expand Down Expand Up @@ -97,9 +98,9 @@ public function matching(Criteria $criteria)

if ($expr) {
$visitor = new ClosureExpressionVisitor();
$filtered = array_filter($filtered, function () use ($visitor, $expr) {
return $visitor->dispatch($expr);
});
/** @var Closure(mixed): bool $filter */
$filter = $visitor->dispatch($expr);
$filtered = array_filter($filtered, $filter);
}

if ($orderings = $criteria->getOrderings()) {
Expand Down
2 changes: 1 addition & 1 deletion src/Type/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class Date extends DateTime
{
public function __construct(string $time = 'now', DateTimeZone $timezone = null)
public function __construct(string $time = 'now', ?DateTimeZone $timezone = null)
{
parent::__construct($time, $timezone);
$this->setTime(0, 0, 0);
Expand Down
2 changes: 1 addition & 1 deletion src/Type/Money.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public function applyInterest(float $rate, int $duration): MoneyInterface

public function equals(object $other): bool
{
if (!($other instanceof static)) {
if (!$other instanceof static) {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Type/PreciseMoney.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public function applyInterest(float $rate, int $duration): MoneyInterface

public function equals(object $other): bool
{
if (!($other instanceof MoneyInterface)) {
if (!$other instanceof MoneyInterface) {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Type/Time.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class Time extends DateTime
{
public function __construct(string $time = 'now', DateTimeZone $timezone = null)
public function __construct(string $time = 'now', ?DateTimeZone $timezone = null)
{
parent::__construct($time, $timezone);
$this->setDate(1970, 1, 1);
Expand Down
26 changes: 17 additions & 9 deletions tests/Type/Collection/FixedTypedCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ class FixedTypedCollectionTest extends TestCase
{
public function testIsValidatingSizeOnConstructor(): void
{
$object1 = new class() {
$object1 = new class {
};
$object2 = new class() {
$object2 = new class {
};

$this->expectException(InvalidArgumentException::class);
Expand All @@ -41,13 +41,13 @@ public function isValidType($value): bool
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Index invalid or out of range');

$collection[] = new class() {
$collection[] = new class {
};
}

public function testIsValidatingSizeOnAdd(): void
{
$object1 = new class() {
$object1 = new class {
};

$collection = new class(0) extends FixedTypedCollection {
Expand All @@ -65,7 +65,7 @@ public function isValidType($value): bool

public function testIsGetting(): void
{
$object1 = new class() {
$object1 = new class {
};

$collection = new class(1, [$object1]) extends FixedTypedCollection {
Expand All @@ -80,7 +80,7 @@ public function isValidType($value): bool

public function testIsValidatingKeyOnGet(): void
{
$object1 = new class() {
$object1 = new class {
};

$collection = new class(1, [$object1]) extends FixedTypedCollection {
Expand All @@ -98,7 +98,7 @@ public function isValidType($value): bool

public function testIsValidatingKeyOnOffsetGet(): void
{
$object1 = new class() {
$object1 = new class {
public $test = 'foo';
};

Expand All @@ -117,11 +117,14 @@ public function isValidType($value): bool

public function testIsApplyingMatchingCriteria(): void
{
$object1 = new class() {
$object1 = new class {
public $test = 'foo';
};
$object2 = new class {
public $test = 'bar';
};

$collection = new class(1, [$object1]) extends FixedTypedCollection {
$collection = new class(2, [$object1, $object2]) extends FixedTypedCollection {
public function isValidType($value): bool
{
return true;
Expand All @@ -133,5 +136,10 @@ public function isValidType($value): bool
$actual = $collection->matching($criteria);

$this->assertSame([$object1], $actual->getValues());

$criteria = Criteria::create()->where((new ExpressionBuilder())->eq('test', 'missing'));

$this->assertSame([], $collection->matching($criteria)->getValues());
$this->assertSame([$object1, $object2], $collection->getValues());
}
}
Loading