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

PHP 8.4 compatibility #17786

Merged
merged 2 commits into from
Nov 26, 2024
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
14 changes: 7 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
matrix:
include:
- {php-version: "8.2"} # Lint on lower PHP version to detected too early usage of new syntaxes
- {php-version: "8.3"} # Lint on higher PHP version to detected deprecated elements usage
- {php-version: "8.4"} # Lint on higher PHP version to detected deprecated elements usage
env:
COMPOSE_FILE: ".github/actions/docker-compose-app.yml"
APPLICATION_ROOT: "${{ github.workspace }}"
Expand Down Expand Up @@ -116,20 +116,20 @@ jobs:
MATRIX='
{
"include": [
{"php-version": "8.3", "db-image": "mariadb:11.4"},
{"php-version": "8.3", "db-image": "mysql:8.4"},
{"php-version": "8.4", "db-image": "mariadb:11.4"},
{"php-version": "8.4", "db-image": "mysql:8.4"},
{"php-version": "8.2", "db-image": "mariadb:11.4"},
{"php-version": "8.3", "db-image": "mariadb:10.5"},
{"php-version": "8.3", "db-image": "percona:8.0"}
{"php-version": "8.4", "db-image": "mariadb:10.5"},
{"php-version": "8.4", "db-image": "percona:8.0"}
]
}
'
else
MATRIX='
{
"include": [
{"php-version": "8.3", "db-image": "mariadb:11.4"},
{"php-version": "8.3", "db-image": "mysql:8.4"}
{"php-version": "8.4", "db-image": "mariadb:11.4"},
{"php-version": "8.4", "db-image": "mysql:8.4"}
]
}
'
Expand Down
18 changes: 10 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@
},
"require-dev": {
"ext-xml": "*",
"atoum/atoum": "^4.2",
"atoum/stubs": "^2.6",
"atoum/atoum": "dev-main#e43a6a84809635cf5dcdf80bf3c773e7cf1d5a04",
"atoum/stubs": "dev-master#fb8890f347a7ecf1e3cf2b5a139a8b038359a6ab",
"friendsoftwig/twigcs": "^6.4",
"glpi-project/tools": "^0.7",
"mikey179/vfsstream": "^1.6",
Expand Down Expand Up @@ -188,19 +188,21 @@
"post-install-cmd": [
"@php -r \"file_put_contents('.composer.hash', sha1_file('composer.lock'));\"",
"@php -f vendor/bin/build_hw_jsons",
"patch -f -p1 -d vendor/laminas/laminas-mail/ < tools/patches/laminas-mail-invalid-header-ignore.patch || true",
"patch -f -p1 -d vendor/laminas/laminas-mail/ < tools/patches/laminas-mail-address-no-length-check.patch || true",
"patch -f -p1 -d vendor/guzzlehttp/guzzle/ < tools/patches/guzzle-http-client-restrict-http-methods.patch || true"
"@patch"
],
"post-update-cmd": [
"@php -r \"file_put_contents('.composer.hash', sha1_file('composer.lock'));\"",
"@php -f vendor/bin/build_hw_jsons",
"patch -f -p1 -d vendor/laminas/laminas-mail/ < tools/patches/laminas-mail-invalid-header-ignore.patch || true",
"patch -f -p1 -d vendor/laminas/laminas-mail/ < tools/patches/laminas-mail-address-no-length-check.patch || true",
"patch -f -p1 -d vendor/guzzlehttp/guzzle/ < tools/patches/guzzle-http-client-restrict-http-methods.patch || true"
"@patch"
],
"build": [
"bin/console dependencies install"
],
"patch": [
"patch -f -p1 -d vendor/laminas/laminas-mail/ < tools/patches/laminas-mail-invalid-header-ignore.patch || true",
"patch -f -p1 -d vendor/laminas/laminas-mail/ < tools/patches/laminas-mail-address-no-length-check.patch || true",
"patch -f -p1 -d vendor/guzzlehttp/guzzle/ < tools/patches/guzzle-http-client-restrict-http-methods.patch || true",
"patch -f -p1 -d vendor/apereo/phpcas/ < tools/patches/apereo-phpcas-php84.patch || true"
]
}
}
31 changes: 18 additions & 13 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions phpunit/functional/TicketTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7579,7 +7579,10 @@ public function testDynamicProperties(): void
{
$ticket = new \Ticket();

$reporting_level = \error_reporting(E_ALL); // be sure to report deprecations
$ticket->plugin_xxx_data = 'test';
\error_reporting($reporting_level); // restore previous level

$this->hasPhpLogRecordThatContains(
'Creation of dynamic property Ticket::$plugin_xxx_data is deprecated',
LogLevel::INFO
Expand Down
12 changes: 12 additions & 0 deletions phpunit/functional/ToolboxTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,10 @@ public function testIsValidWebUrl(string $url, bool $result)

public function testDeprecated()
{
$reporting_level = \error_reporting(E_ALL); // be sure to report deprecations
\Toolbox::deprecated('Calling this function is deprecated');
\error_reporting($reporting_level); // restore previous level

$this->hasPhpLogRecordThatContains(
'Calling this function is deprecated',
LogLevel::INFO
Expand All @@ -1090,7 +1093,10 @@ public function testDeprecated()
public function testDeprecatedPast()
{
// Test planned deprecation in the past
$reporting_level = \error_reporting(E_ALL); // be sure to report deprecations
\Toolbox::deprecated('Calling this function is deprecated', true, '10.0');
\error_reporting($reporting_level); // restore previous level

$this->hasPhpLogRecordThatContains(
'Calling this function is deprecated',
LogLevel::INFO
Expand All @@ -1100,7 +1106,10 @@ public function testDeprecatedPast()
public function testDeprecatedCurrent()
{
// Test planned deprecation in current version
$reporting_level = \error_reporting(E_ALL); // be sure to report deprecations
\Toolbox::deprecated('Calling this function is deprecated', true, GLPI_VERSION);
\error_reporting($reporting_level); // restore previous level

$this->hasPhpLogRecordThatContains(
'Calling this function is deprecated',
LogLevel::INFO
Expand All @@ -1110,7 +1119,10 @@ public function testDeprecatedCurrent()
public function testFutureDeprecated()
{
// Test planned deprecation in the future does NOT throw an error
$reporting_level = \error_reporting(E_ALL); // be sure to report deprecations
\Toolbox::deprecated('Calling this function is deprecated', true, '99.0');
\error_reporting($reporting_level); // restore previous level

$this->assertTrue(true); //non empty test
}

Expand Down
4 changes: 2 additions & 2 deletions public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@

// Check PHP version not to have trouble
// Need to be the very fist step before any include
if (version_compare(PHP_VERSION, '8.2.0', '<') || version_compare(PHP_VERSION, '8.3.999', '>')) {
exit('PHP version must be between 8.2 and 8.3.');
if (version_compare(PHP_VERSION, '8.2.0', '<') || version_compare(PHP_VERSION, '8.4.999', '>')) {
exit('PHP version must be between 8.2 and 8.4.');
}

// Check the resources state before trying to instanciate the Kernel.
Expand Down
2 changes: 1 addition & 1 deletion src/Consumable.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public static function getMassiveActionsForItemtype(
array &$actions,
$itemtype,
$is_deleted = 0,
CommonDBTM $checkitem = null
?CommonDBTM $checkitem = null
) {
// Special actions only for self
if ($itemtype !== static::class) {
Expand Down
44 changes: 30 additions & 14 deletions src/Glpi/Application/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class ErrorHandler
E_USER_ERROR => LogLevel::ERROR,
E_USER_WARNING => LogLevel::WARNING,
E_USER_NOTICE => LogLevel::NOTICE,
E_STRICT => LogLevel::NOTICE,
2048 => LogLevel::NOTICE, // 2048 = deprecated E_STRICT
E_RECOVERABLE_ERROR => LogLevel::ERROR,
E_DEPRECATED => LogLevel::INFO,
E_USER_DEPRECATED => LogLevel::INFO,
Expand Down Expand Up @@ -227,9 +227,34 @@ public function register(): void
set_exception_handler([$this, 'handleException']);
}

// Force reporting of all errors, to ensure that all log levels that are supposed to be
// pushed in logs according to `GLPI_LOG_LVL`/`GLPI_ENVIRONMENT_TYPE` are actually reported.
error_reporting(E_ALL);
// Adjust reporting level to the environment, to ensure that all the errors supposed to be logged are
// actually reported, and to prevent reporting other errors.
$reporting_level = E_ALL;
foreach (self::ERROR_LEVEL_MAP as $value => $log_level) {
if (
$this->env !== GLPI::ENV_DEVELOPMENT
&& in_array($log_level, [LogLevel::DEBUG, LogLevel::INFO])
) {
// Do not report debug and info messages unless in development env.
// Suppressing the INFO level will prevent deprecations to be pushed in other environments logs.
//
// Suppressing the deprecations in the testing environment is mandatory to prevent deprecations
// triggered in vendor code to make our test suite fail.
// We may review this part once we will have migrate all our test suite on PHPUnit.
// For now, we rely on PHPStan to detect usages of deprecated code.
$reporting_level = $reporting_level & ~$value;
}

if (
!in_array($this->env, [GLPI::ENV_DEVELOPMENT, GLPI::ENV_TESTING], true)
&& $log_level === LogLevel::NOTICE
) {
// Do not report notice messages unless in development/testing env.
// Notices are errors with no functional impact, so we do not want people to report them as issues.
$reporting_level = $reporting_level & ~$value;
}
}
error_reporting($reporting_level);

// Disable native error displaying as it will be handled by `self::outputDebugMessage()`.
ini_set('display_errors', 'Off');
Expand Down Expand Up @@ -435,15 +460,6 @@ private function outputDebugMessage(string $error_type, string $message, string
return;
}

if (
in_array($this->env, [GLPI::ENV_STAGING, GLPI::ENV_PRODUCTION])
&& in_array($log_level, [LogLevel::DEBUG, LogLevel::INFO])
) {
// On staging/production environment, do not output debug/info messages.
// These messages are not supposed to be intended for end users, as they have no functional impact.
return;
}

$is_dev_env = $this->env === GLPI::ENV_DEVELOPMENT;
$is_debug_mode = isset($_SESSION['glpi_use_mode']) && $_SESSION['glpi_use_mode'] == \Session::DEBUG_MODE;
$is_console_context = $this->output_handler instanceof OutputInterface;
Expand Down Expand Up @@ -513,7 +529,7 @@ private function codeToString(int $error_code): string
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Runtime Notice',
2048 => 'Runtime Notice', // 2048 = deprecated E_STRICT
E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
E_DEPRECATED => 'Deprecated function',
E_USER_DEPRECATED => 'User deprecated function',
Expand Down
2 changes: 1 addition & 1 deletion src/Glpi/Asset/Asset_PeripheralAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ public static function getMassiveActionsForItemtype(
array &$actions,
$itemtype,
$is_deleted = false,
CommonDBTM $checkitem = null
?CommonDBTM $checkitem = null
) {
$action_prefix = __CLASS__ . MassiveAction::CLASS_ACTION_SEPARATOR;
$specificities = self::getRelationMassiveActionsSpecificities();
Expand Down
6 changes: 3 additions & 3 deletions src/Glpi/DBAL/QueryFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public static function ifnull(string|QueryExpression $expression, string|QueryEx
* @param string|null $alias Function result alias (will be automatically quoted)
* @return QueryExpression
*/
public static function groupConcat(string|QueryExpression $expression, ?string $separator = null, bool $distinct = false, array|string $order_by = null, ?string $alias = null): QueryExpression
public static function groupConcat(string|QueryExpression $expression, ?string $separator = null, bool $distinct = false, array|string|null $order_by = null, ?string $alias = null): QueryExpression
{
/** @var \DBmysql $DB */
global $DB;
Expand Down Expand Up @@ -309,7 +309,7 @@ public static function replace(string|QueryExpression $expression, string|QueryE
* @param string|null $alias Function result alias (will be automatically quoted)
* @return QueryExpression
*/
public static function fromUnixtime(string|QueryExpression $expression, string|QueryExpression $format = null, ?string $alias = null): QueryExpression
public static function fromUnixtime(string|QueryExpression $expression, string|QueryExpression|null $format = null, ?string $alias = null): QueryExpression
{
$params = [$expression];
if ($format !== null) {
Expand Down Expand Up @@ -433,7 +433,7 @@ public static function timediff(string|QueryExpression $expression1, string|Quer
* @param string|null $alias Function result alias (will be automatically quoted)
* @return QueryExpression
*/
public static function unixTimestamp(string|QueryExpression $expression = null, ?string $alias = null): QueryExpression
public static function unixTimestamp(string|QueryExpression|null $expression = null, ?string $alias = null): QueryExpression
{
$params = [];
if ($expression !== null) {
Expand Down
6 changes: 3 additions & 3 deletions src/Glpi/Dashboard/FakeProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private static function getItemCount(?string $itemtype = null)
return $values[$itemtype] ?? null;
}

public static function bigNumberItem(CommonDBTM $item = null, array $params = []): array
public static function bigNumberItem(?CommonDBTM $item = null, array $params = []): array
{
return [
'number' => self::getItemCount($item::class) ?? 1500,
Expand Down Expand Up @@ -278,7 +278,7 @@ public static function nbTicketsByAgreementStatusAndTechnicianGroup(array $param
];
}

public static function nbItemByFk(CommonDBTM $item = null, CommonDBTM $fk_item = null, array $params = []): array
public static function nbItemByFk(?CommonDBTM $item = null, ?CommonDBTM $fk_item = null, array $params = []): array
{
$item_counts = self::getItemCount();
$number_fk = $item_counts[$fk_item::class] ?? 20;
Expand Down Expand Up @@ -306,7 +306,7 @@ public static function nbItemByFk(CommonDBTM $item = null, CommonDBTM $fk_item =
];
}

public static function articleListItem(CommonDBTM $item = null, array $params = []): array
public static function articleListItem(?CommonDBTM $item = null, array $params = []): array
{
$data = [];
for ($i = 0; $i < 5; $i++) {
Expand Down
5 changes: 2 additions & 3 deletions src/Glpi/Features/State.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,11 @@ private function checkSetup(): void
global $CFG_GLPI;

if (!in_array(static::class, $CFG_GLPI['state_types'])) {
trigger_error(
throw new \LogicException(
sprintf(
'Class %s must be present in $CFG_GLPI[\'state_types\']',
static::class
),
E_USER_ERROR
)
);
}
}
Expand Down
Loading