diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e8f27d3267..4c3ee2342fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 }}" @@ -116,11 +116,11 @@ 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"} ] } ' @@ -128,8 +128,8 @@ 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"} ] } ' diff --git a/composer.json b/composer.json index 4abf6cdba5c..53d9cc87528 100644 --- a/composer.json +++ b/composer.json @@ -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", @@ -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" ] } } diff --git a/composer.lock b/composer.lock index d40b9cab3f1..70515fb32a8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f7fbe4971a89637e80066017f3eeef72", + "content-hash": "093f173c565f7d2b5be80c807843fc1a", "packages": [ { "name": "apereo/phpcas", @@ -8986,16 +8986,16 @@ "packages-dev": [ { "name": "atoum/atoum", - "version": "4.2.0", + "version": "dev-main", "source": { "type": "git", "url": "https://github.com/atoum/atoum.git", - "reference": "fd9a339de252ea774ab755b3fd25dd19be2dbefb" + "reference": "e43a6a84809635cf5dcdf80bf3c773e7cf1d5a04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/atoum/atoum/zipball/fd9a339de252ea774ab755b3fd25dd19be2dbefb", - "reference": "fd9a339de252ea774ab755b3fd25dd19be2dbefb", + "url": "https://api.github.com/repos/atoum/atoum/zipball/e43a6a84809635cf5dcdf80bf3c773e7cf1d5a04", + "reference": "e43a6a84809635cf5dcdf80bf3c773e7cf1d5a04", "shasum": "" }, "require": { @@ -9016,6 +9016,7 @@ "ext-mbstring": "Provides support for UTF-8 strings", "ext-xdebug": "Provides code coverage report (>= 2.3)" }, + "default-branch": true, "bin": [ "bin/atoum" ], @@ -9067,27 +9068,28 @@ ], "support": { "issues": "https://github.com/atoum/atoum/issues", - "source": "https://github.com/atoum/atoum/tree/4.2.0" + "source": "https://github.com/atoum/atoum/tree/main" }, - "time": "2023-07-30T12:52:23+00:00" + "time": "2024-07-31T12:02:10+00:00" }, { "name": "atoum/stubs", - "version": "2.6.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/atoum/stubs.git", - "reference": "df8b73b0358de7283ecba91d8f4a9683f583993d" + "reference": "fb8890f347a7ecf1e3cf2b5a139a8b038359a6ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/atoum/stubs/zipball/df8b73b0358de7283ecba91d8f4a9683f583993d", - "reference": "df8b73b0358de7283ecba91d8f4a9683f583993d", + "url": "https://api.github.com/repos/atoum/stubs/zipball/fb8890f347a7ecf1e3cf2b5a139a8b038359a6ab", + "reference": "fb8890f347a7ecf1e3cf2b5a139a8b038359a6ab", "shasum": "" }, "suggest": { "atoum/atoum": "Include atoum in your projet dependencies" }, + "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -9120,7 +9122,7 @@ "issues": "https://github.com/atoum/stubs/issues", "source": "https://github.com/atoum/stubs/tree/master" }, - "time": "2018-01-29T22:41:37+00:00" + "time": "2024-07-30T18:02:37+00:00" }, { "name": "friendsoftwig/twigcs", @@ -11723,7 +11725,10 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "atoum/atoum": 20, + "atoum/stubs": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/public/index.php b/public/index.php index e0f2b05cc1a..c5fe79be48a 100755 --- a/public/index.php +++ b/public/index.php @@ -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. diff --git a/src/Consumable.php b/src/Consumable.php index 54d83e93e2f..2e04a699499 100644 --- a/src/Consumable.php +++ b/src/Consumable.php @@ -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) { diff --git a/src/Glpi/Asset/Asset_PeripheralAsset.php b/src/Glpi/Asset/Asset_PeripheralAsset.php index 50a907a8431..50f8f30ad23 100644 --- a/src/Glpi/Asset/Asset_PeripheralAsset.php +++ b/src/Glpi/Asset/Asset_PeripheralAsset.php @@ -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(); diff --git a/src/Glpi/DBAL/QueryFunction.php b/src/Glpi/DBAL/QueryFunction.php index 0e0ddf61ccf..6703e4bbbbc 100644 --- a/src/Glpi/DBAL/QueryFunction.php +++ b/src/Glpi/DBAL/QueryFunction.php @@ -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; @@ -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) { @@ -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) { diff --git a/src/Glpi/Dashboard/FakeProvider.php b/src/Glpi/Dashboard/FakeProvider.php index 398787c9180..c70a5ddb971 100644 --- a/src/Glpi/Dashboard/FakeProvider.php +++ b/src/Glpi/Dashboard/FakeProvider.php @@ -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, @@ -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; @@ -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++) { diff --git a/src/Glpi/Features/State.php b/src/Glpi/Features/State.php index ede86e18a26..88776e4fb09 100644 --- a/src/Glpi/Features/State.php +++ b/src/Glpi/Features/State.php @@ -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 + ) ); } } diff --git a/src/Glpi/Form/ServiceCatalog/ServiceCatalogManager.php b/src/Glpi/Form/ServiceCatalog/ServiceCatalogManager.php index 9b6f33da582..a88453c0976 100644 --- a/src/Glpi/Form/ServiceCatalog/ServiceCatalogManager.php +++ b/src/Glpi/Form/ServiceCatalog/ServiceCatalogManager.php @@ -161,7 +161,7 @@ function (ServiceCatalogItemInterface $item) use ($item_request) { private function hasChildren( ItemRequest $item_request, - ServiceCatalogCompositeInterface $composite = null, + ?ServiceCatalogCompositeInterface $composite = null, ): bool { $leaf_providers = array_filter( $this->providers, diff --git a/src/Glpi/Marketplace/Controller.php b/src/Glpi/Marketplace/Controller.php index ccae020c033..a4e9b532fec 100644 --- a/src/Glpi/Marketplace/Controller.php +++ b/src/Glpi/Marketplace/Controller.php @@ -159,7 +159,7 @@ private static function getPluginVersionInfo(array $plugin, string $version): ?a * @param ?string $version Download a specific version of the plugin * @return bool */ - public function downloadPlugin($auto_install = true, string $version = null): bool + public function downloadPlugin($auto_install = true, ?string $version = null): bool { if (!self::hasWriteAccess()) { return false; @@ -464,7 +464,7 @@ public function getRequiredOffers(): array * * @return bool */ - public function canBeDownloaded(string $version = null) + public function canBeDownloaded(?string $version = null) { $api = self::getAPI(); $api_plugin = $api->getPlugin($this->plugin_key); diff --git a/src/Glpi/System/Log/LogParser.php b/src/Glpi/System/Log/LogParser.php index afb3fc4af5b..fff81594eb9 100644 --- a/src/Glpi/System/Log/LogParser.php +++ b/src/Glpi/System/Log/LogParser.php @@ -124,7 +124,7 @@ public function getLogFileInfo(string $filepath): ?array * * @return array|null */ - public function parseLogFile(string $filepath, int $max_nb_lines = null): ?array + public function parseLogFile(string $filepath, ?int $max_nb_lines = null): ?array { /** @var array $CFG_GLPI */ global $CFG_GLPI; diff --git a/src/IPAddress.php b/src/IPAddress.php index a02d3af9b5f..9439743ff25 100644 --- a/src/IPAddress.php +++ b/src/IPAddress.php @@ -1276,9 +1276,9 @@ private static function getCriteriaLinkedToNetwork(IPNetwork $network): array * @param array $options **/ public static function getHTMLTableCellsForItem( - HTMLTableRow $row = null, - CommonDBTM $item = null, - HTMLTableCell $father = null, + ?HTMLTableRow $row = null, + ?CommonDBTM $item = null, + ?HTMLTableCell $father = null, array $options = [] ) { /** @var \DBmysql $DB */ diff --git a/src/Line.php b/src/Line.php index 0915e05bbcd..ebf085e5df7 100644 --- a/src/Line.php +++ b/src/Line.php @@ -246,7 +246,7 @@ public static function getIcon() return "ti ti-phone-calling"; } - public static function getMassiveActionsForItemtype(array &$actions, $itemtype, $is_deleted = 0, CommonDBTM $checkitem = null) + public static function getMassiveActionsForItemtype(array &$actions, $itemtype, $is_deleted = 0, ?CommonDBTM $checkitem = null) { /** @var array $CFG_GLPI */ global $CFG_GLPI; diff --git a/src/QueuedWebhook.php b/src/QueuedWebhook.php index 466c20e9250..91e1bcfa481 100644 --- a/src/QueuedWebhook.php +++ b/src/QueuedWebhook.php @@ -563,7 +563,7 @@ public static function getPendings($send_time = null, $limit = 20, $extra_where * * @return integer either 0 or 1 **/ - public static function cronQueuedWebhook(CronTask $task = null) + public static function cronQueuedWebhook(?CronTask $task = null) { $cron_status = 0; @@ -589,7 +589,7 @@ public static function cronQueuedWebhook(CronTask $task = null) * * @return integer either 0 or 1 **/ - public static function cronQueuedWebhookClean(CronTask $task = null) + public static function cronQueuedWebhookClean(?CronTask $task = null) { /** @var \DBmysql $DB */ global $DB; diff --git a/src/Reservation.php b/src/Reservation.php index be3fcccef7d..6642529d841 100644 --- a/src/Reservation.php +++ b/src/Reservation.php @@ -1153,7 +1153,7 @@ public static function getIcon() return "ti ti-calendar-event"; } - public static function getMassiveActionsForItemtype(array &$actions, $itemtype, $is_deleted = 0, CommonDBTM $checkitem = null) + public static function getMassiveActionsForItemtype(array &$actions, $itemtype, $is_deleted = 0, ?CommonDBTM $checkitem = null) { /** @var array $CFG_GLPI */ global $CFG_GLPI; diff --git a/src/Toolbox.php b/src/Toolbox.php index 9b2c57bcbcf..24abda6985f 100644 --- a/src/Toolbox.php +++ b/src/Toolbox.php @@ -262,7 +262,7 @@ public static function decodeFromUtf8($string, $to_charset = "ISO-8859-1") * * @return void **/ - private static function log(LoggerInterface $logger = null, $level = LogLevel::WARNING, $args = null) + private static function log(?LoggerInterface $logger = null, $level = LogLevel::WARNING, $args = null) { static $tps = 0; diff --git a/src/autoload/constants.php b/src/autoload/constants.php index e8ec0791909..d737740f34e 100644 --- a/src/autoload/constants.php +++ b/src/autoload/constants.php @@ -45,7 +45,7 @@ ); define('GLPI_MIN_PHP', '8.2'); // Must also be changed in top of public/index.php -define('GLPI_MAX_PHP', '8.3'); // Must also be changed in top of public/index.php +define('GLPI_MAX_PHP', '8.4'); // Must also be changed in top of public/index.php define('GLPI_YEAR', '2024'); //Define a global recipient address for email notifications diff --git a/tests/src/FormTesterTrait.php b/tests/src/FormTesterTrait.php index 053a8110366..00ee9a0c36d 100644 --- a/tests/src/FormTesterTrait.php +++ b/tests/src/FormTesterTrait.php @@ -161,7 +161,7 @@ protected function createForm(FormBuilder $builder): Form protected function getQuestionId( Form $form, string $question_name, - string $section_name = null, + ?string $section_name = null, ): int { // Make sure form is up to date $form->getFromDB($form->getID()); @@ -239,7 +239,7 @@ protected function getSectionId( protected function getCommentId( Form $form, string $comment_name, - string $section_name = null, + ?string $section_name = null, ): int { // Make sure form is up to date $form->getFromDB($form->getID()); diff --git a/tools/patches/apereo-phpcas-php84.patch b/tools/patches/apereo-phpcas-php84.patch new file mode 100644 index 00000000000..6df6e7d594c --- /dev/null +++ b/tools/patches/apereo-phpcas-php84.patch @@ -0,0 +1,35 @@ +diff --git a/source/CAS.php b/source/CAS.php +index df6bc82..da145bc 100644 +--- a/source/CAS.php ++++ b/source/CAS.php +@@ -347,7 +347,7 @@ class phpCAS + */ + public static function client($server_version, $server_hostname, + $server_port, $server_uri, $service_base_url, +- $changeSessionID = true, \SessionHandlerInterface $sessionHandler = null ++ $changeSessionID = true, ?\SessionHandlerInterface $sessionHandler = null + ) { + phpCAS :: traceBegin(); + if (is_object(self::$_PHPCAS_CLIENT)) { +@@ -402,7 +402,7 @@ class phpCAS + */ + public static function proxy($server_version, $server_hostname, + $server_port, $server_uri, $service_base_url, +- $changeSessionID = true, \SessionHandlerInterface $sessionHandler = null ++ $changeSessionID = true, ?\SessionHandlerInterface $sessionHandler = null + ) { + phpCAS :: traceBegin(); + if (is_object(self::$_PHPCAS_CLIENT)) { +diff --git a/source/CAS/Client.php b/source/CAS/Client.php +index 8ca9711..42709e9 100644 +--- a/source/CAS/Client.php ++++ b/source/CAS/Client.php +@@ -938,7 +938,7 @@ class CAS_Client + $server_uri, + $service_base_url, + $changeSessionID = true, +- \SessionHandlerInterface $sessionHandler = null ++ ?\SessionHandlerInterface $sessionHandler = null + ) { + // Argument validation + if (gettype($server_version) != 'string')