Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bye bye PHP 8.1, long live PHP 8.2 #2060

Merged
merged 6 commits into from
Dec 21, 2023
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
18 changes: 9 additions & 9 deletions .github/workflows/CICD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ jobs:
access_token: ${{ github.token }}

php_syntax_errors:
name: 1️⃣ PHP 8.1 - Syntax errors
name: 1️⃣ PHP 8.2 - Syntax errors
runs-on: ubuntu-latest
needs:
- kill_previous
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
php-version: 8.2

- name: Checkout code
uses: actions/checkout@v3
Expand All @@ -50,15 +50,15 @@ jobs:
run: vendor/bin/parallel-lint --exclude .git --exclude vendor .

code_style_errors:
name: 2️⃣ PHP 8.1 - Code Style errors
name: 2️⃣ PHP 8.2 - Code Style errors
runs-on: ubuntu-latest
needs:
- php_syntax_errors
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
php-version: 8.2

- name: Checkout code
uses: actions/checkout@v3
Expand All @@ -70,7 +70,7 @@ jobs:
run: PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --verbose --diff --dry-run

phpstan:
name: 2️⃣ PHP 8.1 - PHPStan
name: 2️⃣ PHP 8.2 - PHPStan
runs-on: ubuntu-latest
needs:
- php_syntax_errors
Expand All @@ -81,7 +81,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
php-version: 8.2
coverage: none

- name: Install Composer dependencies
Expand All @@ -98,8 +98,8 @@ jobs:
strategy:
matrix:
php-version:
- 8.1
- 8.2
- 8.3
sql-versions:
- mariadb
- postgresql
Expand Down Expand Up @@ -181,7 +181,7 @@ jobs:
strategy:
matrix:
php-version:
- 8.1
- 8.2
sql-versions:
- mariadb
- postgresql
Expand Down Expand Up @@ -273,7 +273,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
php-version: 8.2
extensions: ${{ env.extensions }}
coverage: none

Expand Down
77 changes: 77 additions & 0 deletions .phpstorm.meta.php

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<p align="center"><a href="https://lycheeorg.github.io"><img src="https://raw.githubusercontent.com/LycheeOrg/Lychee/master/Banner.png" width="400px" alt="@LycheeOrg"></a></p>

[![GitHub Release][release-shield]](https://github.com/LycheeOrg/Lychee/releases)
[![PHP 8.1 & 8.2][php-shield]](https://lycheeorg.github.io/docs/#server-requirements)
[![PHP 8.2 & 8.3][php-shield]](https://lycheeorg.github.io/docs/#server-requirements)
[![MIT License][license-shield]](https://github.com/LycheeOrg/Lychee/blob/master/LICENSE)
[![Downloads][download-shield]](https://github.com/LycheeOrg/Lychee/releases)
<br>
Expand Down Expand Up @@ -32,7 +32,7 @@ Lychee is a free photo-management tool, which runs on your server or web-space.

## Installation

To run Lychee, everything you need is a web-server with PHP 8.1 or later and a database (MySQL/MariaDB, PostgreSQL or SQLite). Follow the instructions to install Lychee on your server. This version of Lychee is built on the Laravel framework. To install:
To run Lychee, everything you need is a web-server with PHP 8.2 or later and a database (MySQL/MariaDB, PostgreSQL or SQLite). Follow the instructions to install Lychee on your server. This version of Lychee is built on the Laravel framework. To install:

1. Clone this repo to your server and set the web root to `lychee/public`
2. Run `composer install --no-dev` to install dependencies
Expand Down Expand Up @@ -96,7 +96,7 @@ We would like to thank Jetbrains for supporting us with their [Open Source Devel
[build-status-shield]: https://img.shields.io/github/actions/workflow/status/LycheeOrg/Lychee/CICD.yml?branch=master
[codecov-shield]: https://codecov.io/gh/LycheeOrg/Lychee/branch/master/graph/badge.svg
[release-shield]: https://img.shields.io/github/release/LycheeOrg/Lychee.svg
[php-shield]: https://img.shields.io/badge/PHP-8.1%20|%208.2-blue
[php-shield]: https://img.shields.io/badge/PHP-8.2%20|%208.3-blue
[license-shield]: https://img.shields.io/github/license/LycheeOrg/Lychee.svg
[cii-shield]: https://img.shields.io/cii/summary/2855.svg
[sonar-shield]: https://sonarcloud.io/api/project_badges/measure?project=LycheeOrg_Lychee-Laravel&metric=alert_status
Expand Down
6 changes: 2 additions & 4 deletions app/Actions/Diagnostics/Pipes/Checks/ForeignKeyListInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ private function sqlite(array &$data): void
$fks = DB::select("SELECT m.name , p.* FROM sqlite_master m JOIN pragma_foreign_key_list(m.name) p ON m.name != p.\"table\" WHERE m.type = 'table' ORDER BY m.name;");

foreach ($fks as $fk) {
/** @phpstan-ignore-next-line */
$data[] = sprintf('Foreign key: %-30s → %-20s : %s', $fk->name . '.' . $fk->from, $fk->table . '.' . $fk->to, $fk->on_update);
$data[] = sprintf('Foreign key: %-30s → %-20s : %s', $fk->name . '.' . $fk->from, $fk->table . '.' . $fk->to, strval($fk->on_update));
}
}

Expand All @@ -51,11 +50,10 @@ private function mysql(array &$data): void
order by fks.constraint_schema, fks.table_name;
');
foreach ($fks as $fk) {
/** @phpstan-ignore-next-line */
$data[] = sprintf('Foreign key: %-30s → %-20s : %s',
$fk->TABLE_NAME . '.' . $fk->COLUMN_NAME,
$fk->REFERENCED_TABLE_NAME . '.' . $fk->REFERENCED_COLUMN_NAME,
$fk->UPDATE_RULE);
strval($fk->UPDATE_RULE));
}
}

Expand Down
6 changes: 3 additions & 3 deletions app/Actions/Diagnostics/Pipes/Checks/PHPVersionCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ class PHPVersionCheck implements DiagnosticPipe
{
// We only support the actively supported version of php.
// See here: https://www.php.net/supported-versions.php
public const PHP_ERROR = 8.0;
public const PHP_WARNING = 8.1;
public const PHP_LATEST = 8.2;
public const PHP_ERROR = 8.1;
public const PHP_WARNING = 8.2;
public const PHP_LATEST = 8.3;

/**
* {@inheritDoc}
Expand Down
6 changes: 1 addition & 5 deletions app/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,7 @@ protected function prepareResponse($request, \Throwable $e): RedirectResponse|Re
$e = new HttpException(500, $e->getMessage(), $e);
}

// `renderHttpException` expects `$e` to be an instance of
// `HttpExceptionInterface`.
// This is ensured by `isHttpException` above, but PHPStan does not
// understand that.
// @phpstan-ignore-next-line
/** @var HttpExceptionInterface $e */
return $this->toIlluminateResponse($this->renderHttpException($e), $e);
}

Expand Down
19 changes: 5 additions & 14 deletions app/Factories/AlbumFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,12 @@

class AlbumFactory
{
// PHP 8.2
// public const BUILTIN_SMARTS_CLASS = [
// SmartAlbumType::UNSORTED->value => UnsortedAlbum::class,
// SmartAlbumType::STARRED->value => StarredAlbum::class,
// SmartAlbumType::PUBLIC->value => PublicAlbum::class,
// SmartAlbumType::RECENT->value => RecentAlbum::class,
// SmartAlbumType::ON_THIS_DAY->value => OnThisDayAlbum::class,
// ];

public const BUILTIN_SMARTS_CLASS = [
'unsorted' => UnsortedAlbum::class,
'starred' => StarredAlbum::class,
'public' => PublicAlbum::class,
'recent' => RecentAlbum::class,
'on_this_day' => OnThisDayAlbum::class,
SmartAlbumType::UNSORTED->value => UnsortedAlbum::class,
SmartAlbumType::STARRED->value => StarredAlbum::class,
SmartAlbumType::PUBLIC->value => PublicAlbum::class,
SmartAlbumType::RECENT->value => RecentAlbum::class,
SmartAlbumType::ON_THIS_DAY->value => OnThisDayAlbum::class,
];

/**
Expand Down
12 changes: 6 additions & 6 deletions app/Http/Requests/Album/MergeAlbumsRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ public function rules(): array
*/
protected function processValidatedValues(array $values, array $files): void
{
$this->album = Album::query()->findOrFail($values[RequestAttribute::ALBUM_ID_ATTRIBUTE]);
// `findOrFail` returns a union type, but we know that it returns the
// correct collection in this case
// TODO: As part of our `FixedQueryBuilder` we should also consider adding a method `findManyOrFail` which does not return an union type, but only a `Collection`.
// This would avoid using phpstan-ignore-next-line here and in many similar cases.
/** @var string $id */
$id = $values[RequestAttribute::ALBUM_ID_ATTRIBUTE];
/** @var array<int,string> $ids */
$ids = $values[RequestAttribute::ALBUM_IDS_ATTRIBUTE];
$this->album = Album::query()->findOrFail($id);
// @phpstan-ignore-next-line
$this->albums = Album::query()
->with(['children'])
->findOrFail($values[RequestAttribute::ALBUM_IDS_ATTRIBUTE]);
->findOrFail($ids);
}
}
14 changes: 7 additions & 7 deletions app/Http/Requests/Album/MoveAlbumsRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ public function rules(): array
*/
protected function processValidatedValues(array $values, array $files): void
{
$targetAlbumID = $values[RequestAttribute::ALBUM_ID_ATTRIBUTE];
$this->album = $targetAlbumID === null ?
/** @var string|null $id */
$id = $values[RequestAttribute::ALBUM_ID_ATTRIBUTE];
/** @var array<int,string> $ids */
$ids = $values[RequestAttribute::ALBUM_IDS_ATTRIBUTE];
$this->album = $id === null ?
null :
Album::query()->findOrFail($targetAlbumID);
// `findOrFail` returns a union type, but we know that it returns the
// correct collection in this case
// @phpstan-ignore-next-line
$this->albums = Album::query()->findOrFail($values[RequestAttribute::ALBUM_IDS_ATTRIBUTE]);
Album::findOrFail($id);
$this->albums = Album::findOrFail($ids);
}
}
8 changes: 3 additions & 5 deletions app/Http/Requests/Album/SetAlbumTagsRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,9 @@ public function rules(): array
*/
protected function processValidatedValues(array $values, array $files): void
{
// `findOrFail` returns the union `TagAlbum|Collection<TagAlbum`
// which is not assignable to `TagAlbum`; but as we query for the ID
// we never get a collection
// @phpstan-ignore-next-line
$this->album = TagAlbum::query()->findOrFail($values[RequestAttribute::ALBUM_ID_ATTRIBUTE]);
/** @var string $id */
$id = $values[RequestAttribute::ALBUM_ID_ATTRIBUTE];
$this->album = TagAlbum::query()->findOrFail($id);
$this->tags = $values[RequestAttribute::SHOW_TAGS_ATTRIBUTE];
}
}
36 changes: 33 additions & 3 deletions app/Image/Handlers/GdHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
use function Safe\imagegif;
use function Safe\imagejpeg;
use function Safe\imagepng;
use function Safe\imagerotate;
use function Safe\imagesx;
use function Safe\imagesy;
use function Safe\imagewebp;
Expand Down Expand Up @@ -280,7 +279,7 @@ private function autoRotate(int $orientation): void
};

if ($angle !== 0) {
$this->gdImage = imagerotate($this->gdImage, $angle, 0);
$this->gdImage = $this->imagerotate($this->gdImage, $angle, 0);
}

if ($flip !== 0) {
Expand Down Expand Up @@ -374,7 +373,7 @@ public function cloneAndCrop(ImageDimension $dstDim): ImageHandlerInterface
public function rotate(int $angle): ImageDimension
{
try {
$this->gdImage = imagerotate($this->gdImage, -$angle, 0);
$this->gdImage = $this->imagerotate($this->gdImage, -$angle, 0);

return $this->getDimensions();
} catch (\ErrorException $e) {
Expand Down Expand Up @@ -455,4 +454,35 @@ public function isLoaded(): bool
{
return $this->gdImageType !== 0 && $this->gdImage !== null;
}

/**
* CORRECTED from Safe/imagerotate.
*
* Rotates the image image using the given
* angle in degrees.
*
* The center of rotation is the center of the image, and the rotated
* image may have different dimensions than the original image.
*
* @param \GdImage $image a GdImage object, returned by one of the image creation functions,
* such as imagecreatetruecolor
* @param float $angle Rotation angle, in degrees. The rotation angle is interpreted as the
* number of degrees to rotate the image anticlockwise.
* @param int $background_color Specifies the color of the uncovered zone after the rotation
*
* @return \GdImage returns an image object for the rotated image
*
* @throws ImageException
*/
private function imagerotate($image, float $angle, int $background_color)
{
error_clear_last();
// @phpstan-ignore-next-line
$safeResult = \imagerotate($image, $angle, $background_color);
if ($safeResult === false) {
throw ImageException::createFromPhpError();
}

return $safeResult;
}
}
15 changes: 10 additions & 5 deletions app/Models/Extensions/UTCBasedTimes.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Models\Extensions;

use App\Exceptions\Internal\LycheeLogicException;
use Carbon\CarbonInterface;
use Carbon\Exceptions\InvalidTimeZoneException;
use Illuminate\Support\Carbon;
Expand Down Expand Up @@ -81,10 +82,14 @@ public function fromDateTime($value): ?string
// If $value is already an instance of Carbon, the method returns a
// deep copy, hence it is safe to change the timezone below without
// altering the original object
if ($value === null || $value === '') {
return null;
}

$carbonTime = $this->asDateTime($value);
$carbonTime?->setTimezone(self::$DB_TIMEZONE_NAME);
$carbonTime->setTimezone(self::$DB_TIMEZONE_NAME);

return $carbonTime?->format(self::$DB_DATETIME_FORMAT);
return $carbonTime->format(self::$DB_DATETIME_FORMAT);
}

/**
Expand Down Expand Up @@ -123,14 +128,14 @@ public function fromDateTime($value): ?string
*
* @param mixed $value
*
* @return Carbon|null
* @return Carbon
*
* @throws InvalidTimeZoneException
*/
public function asDateTime($value): ?Carbon
public function asDateTime($value): Carbon
{
if ($value === null || $value === '') {
return null;
throw new LycheeLogicException('asDateTime called on null or empty string');
}

// If this value is already a Carbon instance, we shall just return it as is.
Expand Down
4 changes: 1 addition & 3 deletions app/SmartAlbums/OnThisDayAlbum.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
class OnThisDayAlbum extends BaseSmartAlbum
{
private static ?self $instance = null;
// PHP 8.2
// public const ID = SmartAlbumType::ON_THIS_DAY->value;
public const ID = 'on_this_day';
public const ID = SmartAlbumType::ON_THIS_DAY->value;

/**
* @throws InvalidFormatException
Expand Down
4 changes: 1 addition & 3 deletions app/SmartAlbums/PublicAlbum.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
class PublicAlbum extends BaseSmartAlbum
{
private static ?self $instance = null;
// PHP 8.2
// public const ID = SmartAlbumType::PUBLIC->value;
public const ID = 'public';
public const ID = SmartAlbumType::PUBLIC->value;

/**
* Constructor.
Expand Down
4 changes: 1 addition & 3 deletions app/SmartAlbums/RecentAlbum.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
class RecentAlbum extends BaseSmartAlbum
{
private static ?self $instance = null;
// PHP 8.2
// public const ID = SmartAlbumType::RECENT->value;
public const ID = 'recent';
public const ID = SmartAlbumType::RECENT->value;

/**
* @throws InvalidFormatException
Expand Down
4 changes: 1 addition & 3 deletions app/SmartAlbums/StarredAlbum.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
class StarredAlbum extends BaseSmartAlbum
{
private static ?self $instance = null;
// PHP 8.2
// public const ID = SmartAlbumType::STARRED->value;
public const ID = 'starred';
public const ID = SmartAlbumType::STARRED->value;

/**
* @throws ConfigurationKeyMissingException
Expand Down
Loading