Compare commits

...

24 commits

Author SHA1 Message Date
rxu
f99776d198
Merge 67afc0a1e2 into b7db1b0844 2025-05-03 11:41:25 +07:00
Marc Alexander
b7db1b0844
Merge pull request #6803 from rxu/ticket/17496
[ticket/17496] Fix Implicitly marking parameters as nullable PHP deprecations
2025-05-02 20:20:57 +02:00
rxu
0066d53c08
[ticket/17496] Fix recently added changes
PHPBB-17496
2025-05-02 22:48:59 +07:00
rxu
1b08a74508
[ticket/17496] Sniffer to support question mark nullable type syntax
PHPBB-17496
2025-05-02 22:48:59 +07:00
rxu
a5113d7cd3
[ticket/17496] Correctly restore willReturn()
PHPBB-17496
2025-05-02 22:48:59 +07:00
rxu
0f94e1cb13
[ticket/17496] Fix tests
PHPBB-17496
2025-05-02 22:48:58 +07:00
rxu
c6dcf474d3
[ticket/17496] Upgrade to the most recent GuzzleHTTP 7.9
PHPBB-17496
2025-05-02 22:48:58 +07:00
rxu
d0cb7d6389
[ticket/17496] Fix tests
PHPUnit will automatically create a test double
of required return type to be returned

PHPBB-17496
2025-05-02 22:48:57 +07:00
rxu
118ab73c37
[ticket/17496] Upgrade to GuzzleHTTP 7.8 as PHP 8.4-compatible
PHPBB-17496
2025-05-02 22:48:57 +07:00
rxu
91aaadbc6d
[ticket/17496] Unused use statements sniffer to check union types
PHPBB-17496
2025-05-02 22:48:57 +07:00
rxu
7d1ae5bf19
[ticket/17496] Fix Implicitly marking parameters as nullable PHP deprecations
Also use union types consistently instead of question marks.
Fixed with php-cs-fixer.

PHPBB-17496
2025-05-02 22:48:46 +07:00
rxu
67afc0a1e2
[ticket/15214] Fix rebasing and some other issues
PHPBB3-15214
2025-01-10 22:01:51 +07:00
rxu
0a31489ed2
[ticket/15214] Fix Windows tests
PHPBB3-15214
2025-01-10 16:09:00 +07:00
toxyy
cb5b9823f9
[ticket/15214] Fix tests again
Adding per rxu's recommendation

PHPBB3-15214
2025-01-10 16:09:00 +07:00
rxu
059ad4a9b7
[ticket/15214] Fix Windows tests
Purge Twig compiled cache in Windows.
Set appropriate folder access control options to do that.

PHPBB3-15214
2025-01-10 16:08:59 +07:00
rxu
74f1f01a91
[ticket/15214] Fix test foo/foo extension listener
PHPBB3-15214
2025-01-10 16:08:58 +07:00
rxu
7330b0c792
[ticket/15214] Optimize event node code and add template event order tests
PHPBB3-15214
2025-01-10 16:08:56 +07:00
toxyy
127b775317
[ticket/15214] Update block, restart tests
Make docblock look a bit cleaner and restart the tests

PHPBB3-15214
2025-01-10 16:08:56 +07:00
toxyy
5b16729934
[ticket/15214] Provide usage example within event docblock
Adds similar usage examples like the event core.permissions has

PHPBB3-15214
2025-01-10 16:08:55 +07:00
toxyy
7345106f11
[ticket/15214] Replace arrow functions with anonymous functions
Arrow functions aren't added until PHP 7.4, so we can't use them yet.
Anonymous functions have been added since PHP 5.3

PHPBB3-15214
2025-01-10 16:08:54 +07:00
toxyy
b6265792d1
[ticket/15214] Add fixes for various other tests
Add new dispatch parameter to the template\twig\extension calls

PHPBB3-15214
2025-01-10 16:08:53 +07:00
toxyy
e34da0b33d
[ticket/15214] Test fix for test_bbcode_firstpass
Add new dispatch parameter to the template\twig\extension call

PHPBB3-15214
2025-01-10 16:08:53 +07:00
toxyy
5608f00f62
[ticket/15214] Test fix for test_helper_url_no_rewrite
Add new dispatch parameter to the template\twig\extension call

PHPBB3-15214
2025-01-10 16:08:52 +07:00
toxyy
827f744ca4
[ticket/15214] Add event & functionality for assigning template event priority
Event added to allow template events to be assigned priority per extension,
event location chosen so that it only fires once.
Twig node event class refactored to allow template event priority assignment,
compile calls are deferred until all locations are processed
per extension namespace.
Priority precedence mirrors Symfony priority, with higher numbers
being placed at the beginning of the array.
Duplicate priority assignment will currently have the later events
compiled before the others.

PHPBB3-15214
2025-01-10 16:08:37 +07:00
100 changed files with 581 additions and 228 deletions

View file

@ -49,9 +49,20 @@ class phpbb_Sniffs_Namespaces_UnusedUseSniff implements Sniff
$phpcsFile->addError($error, $stack_pointer, 'FullName');
}
if ($found_name === $short_name)
/*
* Check for possible union types (like string|MyType|null)
* and question mark nullable type syntax (like ?MyType)
*/
$types = explode('|', $found_name);
foreach ($types as $type)
{
return true;
// Nullable type syntax
$type = (strpos($type, '?') === 0) ? substr($type, 1) : $type;
if ($short_name === $type)
{
return true;
}
}
return false;

View file

@ -39,7 +39,7 @@
"composer/package-versions-deprecated": "^1.11",
"doctrine/dbal": "~3.3.6",
"google/recaptcha": "~1.1",
"guzzlehttp/guzzle": "~6.3",
"guzzlehttp/guzzle": " ^7.0",
"marc1706/fast-image-size": "^1.1",
"minishlink/web-push": "^8.0",
"s9e/text-formatter": "^2.0",

124
phpBB/composer.lock generated
View file

@ -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": "96d8bdaa91db532b0a0bf5e1b6c0ec31",
"content-hash": "5ed4369e5ba29297443f428dd3001fae",
"packages": [
{
"name": "bantu/ini-get-wrapper",
@ -1700,37 +1700,47 @@
},
{
"name": "guzzlehttp/guzzle",
"version": "6.5.8",
"version": "7.9.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "a52f0440530b54fa079ce76e8c5d196a42cad981"
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/a52f0440530b54fa079ce76e8c5d196a42cad981",
"reference": "a52f0440530b54fa079ce76e8c5d196a42cad981",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.0",
"guzzlehttp/psr7": "^1.9",
"php": ">=5.5",
"symfony/polyfill-intl-idn": "^1.17"
"guzzlehttp/promises": "^1.5.3 || ^2.0.3",
"guzzlehttp/psr7": "^2.7.0",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
},
"provide": {
"psr/http-client-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"ext-curl": "*",
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
"psr/log": "^1.1"
"guzzle/client-integration-tests": "3.0.2",
"php-http/message-factory": "^1.1",
"phpunit/phpunit": "^8.5.39 || ^9.6.20",
"psr/log": "^1.1 || ^2.0 || ^3.0"
},
"suggest": {
"ext-curl": "Required for CURL handler support",
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
"psr/log": "Required for using the Log middleware"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.5-dev"
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
@ -1783,19 +1793,20 @@
}
],
"description": "Guzzle is a PHP HTTP client library",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"psr-18",
"psr-7",
"rest",
"web service"
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/6.5.8"
"source": "https://github.com/guzzle/guzzle/tree/7.9.3"
},
"funding": [
{
@ -1811,33 +1822,37 @@
"type": "tidelift"
}
],
"time": "2022-06-20T22:16:07+00:00"
"time": "2025-03-27T13:37:11+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "1.5.3",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e"
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e",
"reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e",
"url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c",
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c",
"shasum": ""
},
"require": {
"php": ">=5.5"
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^4.4 || ^5.1"
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
}
@ -1874,7 +1889,7 @@
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/1.5.3"
"source": "https://github.com/guzzle/promises/tree/2.2.0"
},
"funding": [
{
@ -1890,42 +1905,48 @@
"type": "tidelift"
}
],
"time": "2023-05-21T12:31:43+00:00"
"time": "2025-03-27T13:27:01+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "1.9.1",
"version": "2.7.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b"
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/e4490cabc77465aaee90b20cfc9a770f8c04be6b",
"reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16",
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0",
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
"php": "^7.2.5 || ^8.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.1 || ^2.0",
"ralouphie/getallheaders": "^3.0"
},
"provide": {
"psr/http-factory-implementation": "1.0",
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"ext-zlib": "*",
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
"bamarni/composer-bin-plugin": "^1.8.2",
"http-interop/http-factory-tests": "0.9.0",
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
}
@ -1964,6 +1985,11 @@
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://sagikazarmark.hu"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
@ -1979,7 +2005,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/1.9.1"
"source": "https://github.com/guzzle/psr7/tree/2.7.1"
},
"funding": [
{
@ -1995,7 +2021,7 @@
"type": "tidelift"
}
],
"time": "2023-04-17T16:00:37+00:00"
"time": "2025-03-27T12:30:47+00:00"
},
{
"name": "justinrainbow/json-schema",
@ -2802,16 +2828,16 @@
},
{
"name": "psr/http-message",
"version": "1.1",
"version": "2.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba"
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"shasum": ""
},
"require": {
@ -2820,7 +2846,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
"dev-master": "2.0.x-dev"
}
},
"autoload": {
@ -2835,7 +2861,7 @@
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
@ -2849,9 +2875,9 @@
"response"
],
"support": {
"source": "https://github.com/php-fig/http-message/tree/1.1"
"source": "https://github.com/php-fig/http-message/tree/2.0"
},
"time": "2023-04-04T09:50:52+00:00"
"time": "2023-04-04T09:54:51+00:00"
},
{
"name": "psr/log",

View file

@ -40,6 +40,7 @@ services:
- '@template_context'
- '@template.twig.environment'
- '@language'
- '@dispatcher'
tags:
- { name: twig.extension }

View file

@ -130,7 +130,7 @@ function phpbb_gmgetdate($time = false)
*
* @return array|string data array if $string_only is false
*/
function get_formatted_filesize($value, bool $string_only = true, array $allowed_units = null)
function get_formatted_filesize($value, bool $string_only = true, array|null $allowed_units = null)
{
global $user;
@ -253,7 +253,7 @@ function still_on_time($extra_time = 15)
* @return mixed Boolean (true, false) if comparison operator is specified.
* Integer (-1, 0, 1) otherwise.
*/
function phpbb_version_compare(string $version1, string $version2, string $operator = null)
function phpbb_version_compare(string $version1, string $version2, string|null $operator = null)
{
$version1 = strtolower($version1);
$version2 = strtolower($version2);

View file

@ -215,7 +215,7 @@ function adm_back_link($u_action)
*
* @return array
*/
function build_select(array $options_ary, int|string|bool $option_default = false): array
function build_select(array $options_ary, bool|int|string $option_default = false): array
{
global $language;

View file

@ -82,7 +82,7 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface
* @param \phpbb\path_helper $path_helper phpBB path helper
* @param \phpbb\cache\driver\driver_interface|null $cache Cache driver
*/
public function __construct(\phpbb\config\config $config, \FastImageSize\FastImageSize $imagesize, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface $cache = null)
public function __construct(\phpbb\config\config $config, \FastImageSize\FastImageSize $imagesize, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface|null $cache = null)
{
$this->config = $config;
$this->imagesize = $imagesize;

View file

@ -28,7 +28,7 @@ class email extends base
/**
* {@inheritDoc}
*/
public function get_user_column(): ?string
public function get_user_column(): string|null
{
return 'user_email';
}

View file

@ -31,7 +31,7 @@ class ip extends base
/**
* @inheritDoc
*/
public function get_user_column(): ?string
public function get_user_column(): string|null
{
return null;
}

View file

@ -33,7 +33,7 @@ interface type_interface
*
* @return string|null
*/
public function get_user_column(): ?string;
public function get_user_column(): string|null;
/**
* Sets a user object to the ban type to have it excluded

View file

@ -48,7 +48,7 @@ class class_loader
* @param string $php_ext The file extension for PHP files
* @param \phpbb\cache\driver\driver_interface|null $cache An implementation of the phpBB cache interface.
*/
public function __construct($namespace, $path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null)
public function __construct($namespace, $path, $php_ext = 'php', \phpbb\cache\driver\driver_interface|null $cache = null)
{
if ($namespace[0] !== '\\')
{
@ -69,7 +69,7 @@ class class_loader
*
* @param \phpbb\cache\driver\driver_interface|null $cache An implementation of the phpBB cache interface.
*/
public function set_cache(\phpbb\cache\driver\driver_interface $cache = null)
public function set_cache(\phpbb\cache\driver\driver_interface|null $cache = null)
{
if ($cache)
{

View file

@ -29,7 +29,7 @@ class runtime_exception extends base
* @param \Exception|null $previous The previous runtime_exception used for the runtime_exception chaining.
* @param integer $code The Exception code.
*/
public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0)
public function __construct($prefix, $message = '', array $parameters = [], \Exception|null $previous = null, $code = 0)
{
parent::__construct($prefix . $message, $parameters, $previous, $code);
}

View file

@ -68,7 +68,7 @@ class extension_manager extends manager
* @param string $root_path phpBB root path
* @param config|null $config Config object
*/
public function __construct(installer $installer, driver_interface $cache, ext_manager $extension_manager, filesystem $filesystem, $package_type, $exception_prefix, $root_path, config $config = null)
public function __construct(installer $installer, driver_interface $cache, ext_manager $extension_manager, filesystem $filesystem, $package_type, $exception_prefix, $root_path, config|null $config = null)
{
$this->extension_manager = $extension_manager;
$this->filesystem = $filesystem;
@ -86,7 +86,7 @@ class extension_manager extends manager
/**
* {@inheritdoc}
*/
public function pre_install(array $packages, IOInterface $io = null)
public function pre_install(array $packages, IOInterface|null $io = null)
{
$installed_manually = array_intersect(array_keys($this->extension_manager->all_available()), array_keys($packages));
if (count($installed_manually) !== 0)
@ -98,7 +98,7 @@ class extension_manager extends manager
/**
* {@inheritdoc}
*/
public function post_install(array $packages, IOInterface $io = null)
public function post_install(array $packages, IOInterface|null $io = null)
{
if ($this->enable_on_install)
{
@ -127,7 +127,7 @@ class extension_manager extends manager
/**
* {@inheritdoc}
*/
protected function pre_update(array $packages, IOInterface $io = null)
protected function pre_update(array $packages, IOInterface|null $io = null)
{
/** @psalm-suppress InvalidArgument */
$io->writeError([['DISABLING_EXTENSIONS', [], 1]]);
@ -158,7 +158,7 @@ class extension_manager extends manager
/**
* {@inheritdoc}
*/
protected function post_update(array $packages, IOInterface $io = null)
protected function post_update(array $packages, IOInterface|null $io = null)
{
/** @psalm-suppress InvalidArgument */
$io->writeError([['ENABLING_EXTENSIONS', [], 1]]);
@ -184,7 +184,7 @@ class extension_manager extends manager
/**
* {@inheritdoc}
*/
public function remove(array $packages, IOInterface $io = null)
public function remove(array $packages, IOInterface|null $io = null)
{
$packages = $this->normalize_version($packages);
@ -200,7 +200,7 @@ class extension_manager extends manager
/**
* {@inheritdoc}
*/
public function pre_remove(array $packages, IOInterface $io = null)
public function pre_remove(array $packages, IOInterface|null $io = null)
{
if ($this->purge_on_remove)
{

View file

@ -101,7 +101,7 @@ class installer
* @param request $request phpBB request object
* @param config|null $config Config object
*/
public function __construct($root_path, filesystem $filesystem, request $request, config $config = null)
public function __construct($root_path, filesystem $filesystem, request $request, config|null $config = null)
{
if ($config)
{
@ -135,7 +135,7 @@ class installer
*
* @throws runtime_exception
*/
public function install(array $packages, $whitelist, IOInterface $io = null)
public function install(array $packages, $whitelist, IOInterface|null $io = null)
{
$this->wrap(function() use ($packages, $whitelist, $io) {
$this->do_install($packages, $whitelist, $io);
@ -155,7 +155,7 @@ class installer
* @throws runtime_exception
* @throws JsonValidationException
*/
protected function do_install(array $packages, $whitelist, io\io_interface $io = null)
protected function do_install(array $packages, $whitelist, io\io_interface|null $io = null)
{
if (!$io)
{
@ -232,7 +232,7 @@ class installer
* @return Composer|PartialComposer
* @throws JsonValidationException
*/
protected function get_composer(?string $config_file): PartialComposer
protected function get_composer(string|null $config_file): PartialComposer
{
static $composer_factory;
if (!$composer_factory)

View file

@ -46,7 +46,7 @@ class html_output_formatter extends \Composer\Console\HtmlOutputFormatter
/**
* {@inheritdoc}
*/
public function format(?string $message): ?string
public function format(string|null $message): string|null
{
$formatted = parent::format($message);

View file

@ -28,7 +28,7 @@ class web_io extends BufferIO implements io_interface
* @param int $verbosity Verbosity level
* @param OutputFormatterInterface|null $formatter Output formatter
*/
public function __construct(language $language, $input = '', $verbosity = StreamOutput::VERBOSITY_NORMAL, OutputFormatterInterface $formatter = null)
public function __construct(language $language, $input = '', $verbosity = StreamOutput::VERBOSITY_NORMAL, OutputFormatterInterface|null $formatter = null)
{
$this->language = $language;

View file

@ -74,7 +74,7 @@ class manager implements manager_interface
/**
* {@inheritdoc}
*/
public function install(array $packages, IOInterface $io = null)
public function install(array $packages, IOInterface|null $io = null)
{
$packages = $this->normalize_version($packages);
@ -103,7 +103,7 @@ class manager implements manager_interface
* Each entry may be a name or an array associating a version constraint to a name
* @param IOInterface|null $io IO object used for the output
*/
protected function pre_install(array $packages, IOInterface $io = null)
protected function pre_install(array $packages, IOInterface|null $io = null)
{
}
@ -114,14 +114,14 @@ class manager implements manager_interface
* Each entry may be a name or an array associating a version constraint to a name
* @param IOInterface|null $io IO object used for the output
*/
protected function post_install(array $packages, IOInterface $io = null)
protected function post_install(array $packages, IOInterface|null $io = null)
{
}
/**
* {@inheritdoc}
*/
public function update(array $packages, IOInterface $io = null)
public function update(array $packages, IOInterface|null $io = null)
{
$packages = $this->normalize_version($packages);
@ -148,7 +148,7 @@ class manager implements manager_interface
* Each entry may be a name or an array associating a version constraint to a name
* @param IOInterface|null $io IO object used for the output
*/
protected function pre_update(array $packages, IOInterface $io = null)
protected function pre_update(array $packages, IOInterface|null $io = null)
{
}
@ -159,14 +159,14 @@ class manager implements manager_interface
* Each entry may be a name or an array associating a version constraint to a name
* @param IOInterface|null $io IO object used for the output
*/
protected function post_update(array $packages, IOInterface $io = null)
protected function post_update(array $packages, IOInterface|null $io = null)
{
}
/**
* {@inheritdoc}
*/
public function remove(array $packages, IOInterface $io = null)
public function remove(array $packages, IOInterface|null $io = null)
{
$packages = $this->normalize_version($packages);
@ -195,7 +195,7 @@ class manager implements manager_interface
* Each entry may be a name or an array associating a version constraint to a name
* @param IOInterface|null $io IO object used for the output
*/
protected function pre_remove(array $packages, IOInterface $io = null)
protected function pre_remove(array $packages, IOInterface|null $io = null)
{
}
@ -206,7 +206,7 @@ class manager implements manager_interface
* Each entry may be a name or an array associating a version constraint to a name
* @param IOInterface|null $io IO object used for the output
*/
protected function post_remove(array $packages, IOInterface $io = null)
protected function post_remove(array $packages, IOInterface|null $io = null)
{
}

View file

@ -30,7 +30,7 @@ interface manager_interface
*
* @throws runtime_exception
*/
public function install(array $packages, IOInterface $io = null);
public function install(array $packages, IOInterface|null $io = null);
/**
* Updates or installs a set of packages
@ -41,7 +41,7 @@ interface manager_interface
*
* @throws runtime_exception
*/
public function update(array $packages, IOInterface $io = null);
public function update(array $packages, IOInterface|null $io = null);
/**
* Removes a set of packages
@ -52,7 +52,7 @@ interface manager_interface
*
* @throws runtime_exception
*/
public function remove(array $packages, IOInterface $io = null);
public function remove(array $packages, IOInterface|null $io = null);
/**
* Tells whether or not a package is managed by Composer.

View file

@ -53,7 +53,7 @@ class resolver implements ControllerResolverInterface
* @param string $phpbb_root_path Relative path to phpBB root
* @param \phpbb\template\template|null $template
*/
public function __construct(ContainerInterface $container, $phpbb_root_path, \phpbb\template\template $template = null)
public function __construct(ContainerInterface $container, $phpbb_root_path, \phpbb\template\template|null $template = null)
{
$this->container = $container;
$this->template = $template;

View file

@ -42,7 +42,7 @@ class datetime extends \DateTime
* @param string $time String in a format accepted by strtotime().
* @param \DateTimeZone|null $timezone Time zone of the time.
*/
public function __construct($user, $time = 'now', \DateTimeZone $timezone = null)
public function __construct($user, $time = 'now', \DateTimeZone|null $timezone = null)
{
$this->user = $user;
$timezone = $timezone ?: $this->user->timezone;

View file

@ -73,10 +73,10 @@ class connection_factory
public static function get_connection_from_params(
string $driver,
string $host,
?string $user = null,
?string $password = null,
?string $name = null,
?string $port = null): Connection
string|null $user = null,
string|null $password = null,
string|null $name = null,
string|null $port = null): Connection
{
$available_drivers = DriverManager::getAvailableDrivers();
if (!in_array($driver, $available_drivers))

View file

@ -37,11 +37,11 @@ class connection_parameter_factory
*/
public static function get_configuration(
string $driver,
?string $host = null,
?string $user = null,
?string $password = null,
?string $name = null,
?string $port = null) : array
string|null $host = null,
string|null $user = null,
string|null $password = null,
string|null $name = null,
string|null $port = null) : array
{
$params = [
'driver' => $driver,
@ -73,11 +73,11 @@ class connection_parameter_factory
*/
private static function build_connection_parameters(
array $params,
?string $host = null,
?string $user = null,
?string $password = null,
?string $name = null,
?string $port = null) : array
string|null $host = null,
string|null $user = null,
string|null $password = null,
string|null $name = null,
string|null $port = null) : array
{
if ($params['driver'] === 'pdo_sqlite')
{
@ -120,7 +120,7 @@ class connection_parameter_factory
*
* @return array Doctrine's DBAL configuration for SQLite.
*/
private static function build_sqlite_parameters(array $params, string $path, ?string $user, ?string $password) : array
private static function build_sqlite_parameters(array $params, string $path, string|null $user, string|null $password) : array
{
$params['path'] = $path;

View file

@ -29,7 +29,7 @@ abstract class container_aware_migration extends migration implements ContainerA
/**
* {@inheritdoc}
*/
public function setContainer(ContainerInterface $container = null)
public function setContainer(ContainerInterface|null $container = null)
{
$this->container = $container;
}

View file

@ -101,7 +101,7 @@ class remove_jabber extends migration
];
}
public function move_jabber_to_email_notifications(?int $start)
public function move_jabber_to_email_notifications(int|null $start)
{
$limit = 1000;

View file

@ -240,7 +240,7 @@ class schema_generator
* @param mixed $data Array of values to be set.
* @param callable|null $value_transform Callback to transform the value being set.
*/
private static function set_all(&$schema, $data, ?callable $value_transform = null)
private static function set_all(&$schema, $data, callable|null $value_transform = null)
{
$data = (!is_array($data)) ? [$data] : $data;
foreach ($data as $key => $change)
@ -317,7 +317,7 @@ class schema_generator
*
* @return Closure|null The value transformation callback or null if it is not needed.
*/
private static function get_value_transform(string $change_type, string $schema_type) : ?Closure
private static function get_value_transform(string $change_type, string $schema_type) : Closure|null
{
if ($change_type !== 'add')
{

View file

@ -24,7 +24,7 @@ class error_handler extends ErrorHandler
/**
* @psalm-suppress MethodSignatureMismatch
*/
public function __construct(BufferingLogger $bootstrappingLogger = null, private readonly bool $debug = false) // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod.Found
public function __construct(BufferingLogger|null $bootstrappingLogger = null, private readonly bool $debug = false) // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod.Found
{
parent::__construct($bootstrappingLogger, $debug);
}

View file

@ -52,7 +52,7 @@ class dispatcher extends EventDispatcher implements dispatcher_interface
/**
* {@inheritdoc}
*/
public function dispatch(object $event, string $eventName = null) : object
public function dispatch(object $event, string|null $eventName = null) : object
{
if ($this->disabled)
{

View file

@ -39,7 +39,7 @@ class recursive_event_filter_iterator extends \RecursiveFilterIterator
*
* @return recursive_event_filter_iterator
*/
public function getChildren(): ?\RecursiveFilterIterator
public function getChildren(): \RecursiveFilterIterator|null
{
$inner_iterator = $this->getInnerIterator();
assert($inner_iterator instanceof \RecursiveIterator);

View file

@ -44,7 +44,7 @@ class http_exception extends runtime_exception implements HttpExceptionInterface
* @param array $headers Additional headers to set in the response.
* @param integer $code The Exception code.
*/
public function __construct($status_code, $message = "", array $parameters = array(), \Exception $previous = null, array $headers = array(), $code = 0)
public function __construct($status_code, $message = "", array $parameters = array(), \Exception|null $previous = null, array $headers = array(), $code = 0)
{
$this->status_code = $status_code;
$this->headers = $headers;

View file

@ -35,7 +35,7 @@ class runtime_exception extends \RuntimeException implements exception_interface
* @param \Exception|null $previous The previous runtime_exception used for the runtime_exception chaining.
* @param integer $code The Exception code.
*/
public function __construct($message = "", array $parameters = array(), \Exception $previous = null, $code = 0)
public function __construct($message = "", array $parameters = array(), \Exception|null $previous = null, $code = 0)
{
$this->parameters = $parameters;

View file

@ -47,7 +47,7 @@ class manager
* @param \phpbb\cache\service|null $cache A cache instance or null
* @param string $cache_name The name of the cache variable, defaults to _ext
*/
public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, finder_factory $finder_factory, $extension_table, $phpbb_root_path, \phpbb\cache\service $cache = null, $cache_name = '_ext')
public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, finder_factory $finder_factory, $extension_table, $phpbb_root_path, \phpbb\cache\service|null $cache = null, $cache_name = '_ext')
{
$this->cache = $cache;
$this->cache_name = $cache_name;

View file

@ -15,7 +15,7 @@ namespace phpbb\feed\exception;
class no_feed_exception extends feed_unavailable_exception
{
public function __construct(\Exception $previous = null, $code = 0)
public function __construct(\Exception|null $previous = null, $code = 0)
{
parent::__construct('NO_FEED', array(), $previous, $code);
}

View file

@ -15,7 +15,7 @@ namespace phpbb\feed\exception;
class no_forum_exception extends feed_unavailable_exception
{
public function __construct($forum_id, \Exception $previous = null, $code = 0)
public function __construct($forum_id, \Exception|null $previous = null, $code = 0)
{
parent::__construct('NO_FORUM', array($forum_id), $previous, $code);
}

View file

@ -15,7 +15,7 @@ namespace phpbb\feed\exception;
class no_topic_exception extends feed_unavailable_exception
{
public function __construct($topic_id, \Exception $previous = null, $code = 0)
public function __construct($topic_id, \Exception|null $previous = null, $code = 0)
{
parent::__construct('NO_TOPIC', array($topic_id), $previous, $code);
}

View file

@ -15,7 +15,7 @@ namespace phpbb\feed\exception;
class unauthorized_forum_exception extends unauthorized_exception
{
public function __construct($forum_id, \Exception $previous = null, $code = 0)
public function __construct($forum_id, \Exception|null $previous = null, $code = 0)
{
parent::__construct('SORRY_AUTH_READ', array($forum_id), $previous, $code);
}

View file

@ -15,7 +15,7 @@ namespace phpbb\feed\exception;
class unauthorized_topic_exception extends unauthorized_exception
{
public function __construct($topic_id, \Exception $previous = null, $code = 0)
public function __construct($topic_id, \Exception|null $previous = null, $code = 0)
{
parent::__construct('SORRY_AUTH_READ_TOPIC', array($topic_id), $previous, $code);
}

View file

@ -103,7 +103,7 @@ class filespec
* @param \phpbb\mimetype\guesser|null $mimetype_guesser Mime type guesser
* @param \phpbb\plupload\plupload|null $plupload Plupload
*/
public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, \FastImageSize\FastImageSize $imagesize, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null)
public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, \FastImageSize\FastImageSize $imagesize, $phpbb_root_path, \phpbb\mimetype\guesser|null $mimetype_guesser = null, \phpbb\plupload\plupload|null $plupload = null)
{
$this->filesystem = $phpbb_filesystem;
$this->language = $language;

View file

@ -86,7 +86,7 @@ class filespec_storage
* @param \phpbb\mimetype\guesser|null $mimetype_guesser Mime type guesser
* @param \phpbb\plupload\plupload|null $plupload Plupload
*/
public function __construct(language $language, \FastImageSize\FastImageSize $imagesize, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null)
public function __construct(language $language, \FastImageSize\FastImageSize $imagesize, \phpbb\mimetype\guesser|null $mimetype_guesser = null, \phpbb\plupload\plupload|null $plupload = null)
{
$this->language = $language;
$this->imagesize = $imagesize;

View file

@ -26,7 +26,7 @@ class filesystem_exception extends runtime_exception
* @param \Exception|null $previous The previous runtime_exception used for the runtime_exception chaining.
* @param integer $code The Exception code.
*/
public function __construct($message = '', $filename = '', $parameters = array(), \Exception $previous = null, $code = 0)
public function __construct($message = '', $filename = '', $parameters = array(), \Exception|null $previous = null, $code = 0)
{
parent::__construct($message, array_merge(array('filename' => $filename), $parameters), $previous, $code);
}

View file

@ -293,7 +293,7 @@ class filesystem implements filesystem_interface
/**
* {@inheritdoc}
*/
public function mirror($origin_dir, $target_dir, \Traversable $iterator = null, $options = array())
public function mirror($origin_dir, $target_dir, \Traversable|null $iterator = null, $options = array())
{
try
{

View file

@ -190,7 +190,7 @@ interface filesystem_interface
* The filename which triggered the error can be
* retrieved by filesystem_exception::get_filename()
*/
public function mirror($origin_dir, $target_dir, \Traversable $iterator = null, $options = array());
public function mirror($origin_dir, $target_dir, \Traversable|null $iterator = null, $options = array());
/**
* Creates a directory recursively.

View file

@ -33,7 +33,7 @@ class factory
* @param string $phpbb_root_path Path to the phpbb root directory
* @param string $php_ext php file extension
*/
public function __construct(?service $cache, bool $use_cache, string $phpbb_root_path, string $php_ext)
public function __construct(service|null $cache, bool $use_cache, string $phpbb_root_path, string $php_ext)
{
$this->cache = $cache;
$this->use_cache = $use_cache;

View file

@ -58,7 +58,7 @@ class finder
* @param string $cache_name The name of the cache variable, defaults to
* _ext_finder
*/
public function __construct(?service $cache, bool $use_cache, string $phpbb_root_path, string $php_ext, string $cache_name = '_ext_finder')
public function __construct(service|null $cache, bool $use_cache, string $phpbb_root_path, string $php_ext, string $cache_name = '_ext_finder')
{
$this->phpbb_root_path = $phpbb_root_path;
$this->cache = $cache;

View file

@ -52,7 +52,7 @@ class form_helper
*
* @return array Array containing form_token and creation_time of form token
*/
public function get_form_tokens(string $form_name, ?int &$now = 0, ?string &$token_sid = '', ?string &$token = ''): array
public function get_form_tokens(string $form_name, int|null &$now = 0, string|null &$token_sid = '', string|null &$token = ''): array
{
$now = time();
$token_sid = ($this->user->data['user_id'] == ANONYMOUS && !empty($this->config['form_token_sid_guests'])) ? $this->user->session_id : '';
@ -71,7 +71,7 @@ class form_helper
* @param int|null $timespan Lifetime of token or null if default value should be used
* @return bool True if form token is valid, false if not
*/
public function check_form_tokens(string $form_name, ?int $timespan = null): bool
public function check_form_tokens(string $form_name, int|null $timespan = null): bool
{
if ($timespan === null)
{

View file

@ -74,7 +74,7 @@ abstract class database_task extends task_base
*
* @return Result|null Result of the query.
*/
protected function query(string $sql) : ?Result
protected function query(string $sql) : Result|null
{
try
{
@ -95,7 +95,7 @@ abstract class database_task extends task_base
*
* @return Statement|null The prepared statement object or null if preparing failed
*/
protected function create_prepared_stmt(string $sql): ?Statement
protected function create_prepared_stmt(string $sql): Statement|null
{
try
{
@ -155,7 +155,7 @@ abstract class database_task extends task_base
*
* @return int|null The last insert ID.
*/
protected function get_last_insert_id() : ?int
protected function get_last_insert_id() : int|null
{
try
{

View file

@ -38,7 +38,7 @@ trait sequential_task
*
* @throws resource_limit_reached_exception When resources are exhausted.
*/
protected function execute(config $config, array $data, ?string $counter_name = null) : void
protected function execute(config $config, array $data, string|null $counter_name = null) : void
{
if ($counter_name === null)
{

View file

@ -119,8 +119,8 @@ abstract class base implements messenger_interface
user $user,
string $phpbb_root_path,
string $template_cache_path,
?manager $ext_manager = null,
?log_interface $log = null
manager|null $ext_manager = null,
log_interface|null $log = null
)
{
$this->assets_bag = $assets_bag;
@ -469,7 +469,7 @@ abstract class base implements messenger_interface
*
* @return void
*/
protected function set_template_paths(string|array $path_name, string|array $paths): void
protected function set_template_paths(array|string $path_name, array|string $paths): void
{
$this->setup_template();
$this->template->set_custom_style($path_name, $paths);

View file

@ -91,7 +91,7 @@ class email extends messenger_base
* method additionally checks if the type provides an email template.
* @return bool
*/
public function is_available(type_interface $notification_type = null)
public function is_available(type_interface|null $notification_type = null)
{
return parent::is_available($notification_type) && $this->config['email_enable'] && !empty($this->user->data['user_email']);
}

View file

@ -59,7 +59,7 @@ abstract class messenger_base extends \phpbb\notification\method\base
* only if the type is provided and if it doesn't provide an email template.
* @return bool
*/
public function is_available(type_interface $notification_type = null)
public function is_available(type_interface|null $notification_type = null)
{
return $notification_type === null || $notification_type->get_email_template() !== false;
}

View file

@ -101,7 +101,7 @@ class webpush extends base implements extended_method_interface
/**
* {@inheritDoc}
*/
public function is_available(type_interface $notification_type = null): bool
public function is_available(type_interface|null $notification_type = null): bool
{
return $this->config['webpush_enable']
&& $this->config['webpush_vapid_public']

View file

@ -57,7 +57,7 @@ class request implements request_interface
* Initialises the request class, that means it stores all input data in {@link $input input}
* and then calls {@link \phpbb\request\deactivated_super_global \phpbb\request\deactivated_super_global}
*/
public function __construct(\phpbb\request\type_cast_helper_interface $type_cast_helper = null, $disable_super_globals = true)
public function __construct(\phpbb\request\type_cast_helper_interface|null $type_cast_helper = null, $disable_super_globals = true)
{
if ($type_cast_helper)
{

View file

@ -48,7 +48,7 @@ class default_resources_locator implements resources_locator_interface
* @param string $environment Name of the current environment
* @param manager|null $extension_manager Extension manager
*/
public function __construct($phpbb_root_path, $environment, manager $extension_manager = null)
public function __construct($phpbb_root_path, $environment, manager|null $extension_manager = null)
{
$this->phpbb_root_path = $phpbb_root_path;
$this->environment = $environment;

View file

@ -316,7 +316,7 @@ abstract class base implements search_backend_interface
/**
* {@inheritdoc}
*/
public function create_index(int &$post_counter = 0): ?array
public function create_index(int &$post_counter = 0): array|null
{
$max_post_id = $this->get_max_post_id();
$forums_indexing_enabled = $this->forum_ids_with_indexing_enabled();
@ -377,7 +377,7 @@ abstract class base implements search_backend_interface
/**
* {@inheritdoc}
*/
public function delete_index(int &$post_counter = null): ?array
public function delete_index(int|null &$post_counter = null): array|null
{
$max_post_id = $this->get_max_post_id();

View file

@ -912,7 +912,7 @@ class fulltext_mysql extends base implements search_backend_interface
/**
* {@inheritdoc}
*/
public function create_index(int &$post_counter = 0): ?array
public function create_index(int &$post_counter = 0): array|null
{
// Make sure we can actually use MySQL with fulltext indexes
if ($error = $this->init())
@ -984,7 +984,7 @@ class fulltext_mysql extends base implements search_backend_interface
/**
* {@inheritdoc}
*/
public function delete_index(int &$post_counter = null): ?array
public function delete_index(int|null &$post_counter = null): array|null
{
// Make sure we can actually use MySQL with fulltext indexes
if ($error = $this->init())

View file

@ -1621,7 +1621,7 @@ class fulltext_native extends base implements search_backend_interface
/**
* {@inheritdoc}
*/
public function delete_index(int &$post_counter = null): ?array
public function delete_index(int|null &$post_counter = null): array|null
{
$truncate_tables = [
$this->search_wordlist_table,

View file

@ -867,7 +867,7 @@ class fulltext_postgres extends base implements search_backend_interface
/**
* {@inheritdoc}
*/
public function create_index(int &$post_counter = 0): ?array
public function create_index(int &$post_counter = 0): array|null
{
// Make sure we can actually use PostgreSQL with fulltext indexes
if ($error = $this->init())
@ -926,7 +926,7 @@ class fulltext_postgres extends base implements search_backend_interface
/**
* {@inheritdoc}
*/
public function delete_index(int &$post_counter = null): ?array
public function delete_index(int|null &$post_counter = null): array|null
{
// Make sure we can actually use PostgreSQL with fulltext indexes
if ($error = $this->init())

View file

@ -629,7 +629,7 @@ class fulltext_sphinx implements search_backend_interface
/**
* {@inheritdoc}
*/
public function create_index(int &$post_counter = 0): ?array
public function create_index(int &$post_counter = 0): array|null
{
if (!$this->index_created())
{
@ -656,7 +656,7 @@ class fulltext_sphinx implements search_backend_interface
/**
* {@inheritdoc}
*/
public function delete_index(int &$post_counter = null): ?array
public function delete_index(int|null &$post_counter = null): array|null
{
if ($this->index_created())
{

View file

@ -163,7 +163,7 @@ interface search_backend_interface
* @param int $post_counter
* @return array|null array with current status or null if finished
*/
public function create_index(int &$post_counter = 0): ?array;
public function create_index(int &$post_counter = 0): array|null;
/**
* Drop fulltext index
@ -171,7 +171,7 @@ interface search_backend_interface
* @param int $post_counter
* @return array|null array with current status or null if finished
*/
public function delete_index(int &$post_counter = 0): ?array;
public function delete_index(int &$post_counter = 0): array|null;
/**
* Returns true if both FULLTEXT indexes exist

View file

@ -28,7 +28,7 @@ class config
* @param string $name The name of the section that shall be returned
* @return config_section|null The section object or null if none was found
*/
public function get_section_by_name(string $name): ?config_section
public function get_section_by_name(string $name): config_section|null
{
for ($i = 0, $size = count($this->sections); $i < $size; $i++)
{

View file

@ -60,7 +60,7 @@ class config_section extends config_item
* @return config_variable|null The first variable object from this section with the
* given name or null if none was found
*/
public function get_variable_by_name(string $name): ?config_variable
public function get_variable_by_name(string $name): config_variable|null
{
for ($i = 0, $size = count($this->variables); $i < $size; $i++)
{

View file

@ -26,7 +26,7 @@ class storage_exception extends runtime_exception
* @param \Exception|null $previous The previous runtime_exception used for the runtime_exception chaining
* @param integer $code The Exception code
*/
public function __construct($message = '', $filename = '', $parameters = [], \Exception $previous = null, $code = 0)
public function __construct($message = '', $filename = '', $parameters = [], \Exception|null $previous = null, $code = 0)
{
parent::__construct($message, array_merge(array('filename' => $filename), $parameters), $previous, $code);
}

View file

@ -66,7 +66,7 @@ class environment extends \Twig\Environment
* @param dispatcher_interface|null $phpbb_dispatcher Event dispatcher object
* @param array $options Array of options to pass to Twig
*/
public function __construct(assets_bag $assets_bag, config $phpbb_config, filesystem $filesystem, path_helper $path_helper, $cache_path, manager $extension_manager = null, LoaderInterface $loader = null, dispatcher_interface $phpbb_dispatcher = null, $options = array())
public function __construct(assets_bag $assets_bag, config $phpbb_config, filesystem $filesystem, path_helper $path_helper, $cache_path, manager|null $extension_manager = null, LoaderInterface|null $loader = null, dispatcher_interface|null $phpbb_dispatcher = null, $options = array())
{
$this->phpbb_config = $phpbb_config;
@ -271,7 +271,7 @@ class environment extends \Twig\Environment
* @return \Twig\Template A template instance representing the given template name
* @throws \Twig\Error\LoaderError
*/
public function loadTemplate(string $cls, string $name, int $index = null) : \Twig\Template
public function loadTemplate(string $cls, string $name, int|null $index = null) : \Twig\Template
{
if (strpos($name, '@') === false)
{

View file

@ -28,18 +28,23 @@ class extension extends \Twig\Extension\AbstractExtension
/** @var \phpbb\language\language */
protected $language;
/** @var \phpbb\event\dispatcher_interface */
protected $phpbb_dispatcher;
/**
* Constructor
*
* @param \phpbb\template\context $context
* @param \phpbb\template\twig\environment $environment
* @param \phpbb\language\language $language
* @param \phpbb\event\dispatcher_interface $phpbb_dispatcher
*/
public function __construct(\phpbb\template\context $context, \phpbb\template\twig\environment $environment, $language)
public function __construct(\phpbb\template\context $context, \phpbb\template\twig\environment $environment, $language, \phpbb\event\dispatcher_interface $phpbb_dispatcher)
{
$this->context = $context;
$this->environment = $environment;
$this->language = $language;
$this->phpbb_dispatcher = $phpbb_dispatcher;
}
/**
@ -64,7 +69,7 @@ class extension extends \Twig\Extension\AbstractExtension
new \phpbb\template\twig\tokenparser\includeparser,
new \phpbb\template\twig\tokenparser\includejs,
new \phpbb\template\twig\tokenparser\includecss,
new \phpbb\template\twig\tokenparser\event($this->environment),
new \phpbb\template\twig\tokenparser\event($this->environment, $this->phpbb_dispatcher),
);
}

View file

@ -70,7 +70,7 @@ class avatar extends AbstractExtension
*
* @return string The avatar HTML for the specified mode
*/
public function get_avatar(environment $environment, string $mode, array $row, ?string $alt, ?bool $ignore_config, ?bool $lazy): string
public function get_avatar(environment $environment, string $mode, array $row, string|null $alt, bool|null $ignore_config, bool|null $lazy): string
{
$alt = $alt ?? false;
$ignore_config = $ignore_config ?? false;

View file

@ -24,9 +24,13 @@ class event extends \Twig\Node\Node
/** @var \phpbb\template\twig\environment */
protected $environment;
public function __construct(\Twig\Node\Expression\AbstractExpression $expr, \phpbb\template\twig\environment $environment, $lineno, $tag = null)
/** @var array */
protected $template_event_priority_array;
public function __construct(\Twig\Node\Expression\AbstractExpression $expr, \phpbb\template\twig\environment $environment, $lineno, $tag = null, $template_event_priority_array = [])
{
$this->environment = $environment;
$this->template_event_priority_array = $template_event_priority_array;
parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
}
@ -42,40 +46,49 @@ class event extends \Twig\Node\Node
$location = $this->listener_directory . $this->getNode('expr')->getAttribute('name');
$template_events = [];
// Group and sort extension template events in according to their priority (0 by default if not set)
foreach ($this->environment->get_phpbb_extensions() as $ext_namespace => $ext_path)
{
$ext_namespace = str_replace('/', '_', $ext_namespace);
if ($this->environment->isDebug())
{
// If debug mode is enabled, lets check for new/removed EVENT
// templates on page load rather than at compile. This is
// slower, but makes developing extensions easier (no need to
// purge the cache when a new event template file is added)
$compiler
->write("if (\$this->env->getLoader()->exists('@{$ext_namespace}/{$location}.html')) {\n")
->indent()
;
}
if ($this->environment->isDebug() || $this->environment->getLoader()->exists('@' . $ext_namespace . '/' . $location . '.html'))
{
$priority_key = $this->template_event_priority_array[$ext_namespace][$location] ?? 0;
$template_events[$priority_key][] = $ext_namespace;
}
}
krsort($template_events);
foreach ($template_events as $events)
{
foreach ($events as $ext_namespace)
{
if ($this->environment->isDebug())
{
// If debug mode is enabled, lets check for new/removed EVENT
// templates on page load rather than at compile. This is
// slower, but makes developing extensions easier (no need to
// purge the cache when a new event template file is added)
$compiler
->write("if (\$this->env->getLoader()->exists('@{$ext_namespace}/{$location}.html')) {\n")
->indent();
}
$compiler
->write("\$previous_look_up_order = \$this->env->getNamespaceLookUpOrder();\n")
// We set the namespace lookup order to be this extension first, then the main path
->write("\$this->env->setNamespaceLookUpOrder(array('{$ext_namespace}', '__main__'));\n")
->write("\$this->env->loadTemplate(\$this->env->getTemplateClass('@{$ext_namespace}/{$location}.html'), '@{$ext_namespace}/{$location}.html')->display(\$context);\n")
->write("\$this->env->setNamespaceLookUpOrder(\$previous_look_up_order);\n")
;
}
->write("\$this->env->setNamespaceLookUpOrder(\$previous_look_up_order);\n");
if ($this->environment->isDebug())
{
$compiler
->outdent()
->write("}\n\n")
;
if ($this->environment->isDebug())
{
$compiler
->outdent()
->write("}\n\n");
}
}
}
}

View file

@ -18,14 +18,53 @@ class event extends \Twig\TokenParser\AbstractTokenParser
/** @var \phpbb\template\twig\environment */
protected $environment;
/** @var \phpbb\event\dispatcher_interface */
protected $phpbb_dispatcher;
/** @var array */
protected $template_event_priority_array;
/**
* Constructor
*
* @param \phpbb\template\twig\environment $environment
*/
public function __construct(\phpbb\template\twig\environment $environment)
public function __construct(\phpbb\template\twig\environment $environment, \phpbb\event\dispatcher_interface $phpbb_dispatcher = null)
{
$this->environment = $environment;
$this->phpbb_dispatcher = $phpbb_dispatcher;
$template_event_priority_array = [];
/**
* Allow assigning priority to template events
*
* The higher number - the higher tempate event listener priority value is.
* In case of equal priority values, corresponding template event listeners will be handled in default compilation order.
* If not set, template event listener priority will be assigned to the value of 0.
*
* @event core.twig_tokenparser_constructor
* @var array template_event_priority_array Array with template event priority assignments per extension namespace
* Usage:
* '<author>_<extension_name>' => [
* 'event/<template_event_name>' => priority_number,
* ],
*
* Example:
* 'phpbb_viglink' => [
* 'event/acp_help_phpbb_stats_after' => 80,
* 'event/overall_footer_after' => 100,
* ],
*
* @since 4.0.0-a1
*/
if ($this->phpbb_dispatcher)
{
$vars = ['template_event_priority_array'];
extract($this->phpbb_dispatcher->trigger_event('core.twig_tokenparser_constructor', compact($vars)));
}
$this->template_event_priority_array = $template_event_priority_array;
unset($template_event_priority_array);
}
/**
@ -42,7 +81,7 @@ class event extends \Twig\TokenParser\AbstractTokenParser
$stream = $this->parser->getStream();
$stream->expect(\Twig\Token::BLOCK_END_TYPE);
return new \phpbb\template\twig\node\event($expr, $this->environment, $token->getLine(), $this->getTag());
return new \phpbb\template\twig\node\event($expr, $this->environment, $token->getLine(), $this->getTag(), $this->template_event_priority_array);
}
/**

View file

@ -70,9 +70,9 @@ class twig extends \phpbb\template\base
\phpbb\template\context $context,
environment $twig_environment,
$cache_path,
\phpbb\user $user = null,
\phpbb\user|null $user = null,
$extensions = [],
\phpbb\extension\manager $extension_manager = null
\phpbb\extension\manager|null $extension_manager = null
)
{
$this->path_helper = $path_helper;

View file

@ -709,7 +709,7 @@ class user extends \phpbb\session
* @param ?\DateTimeZone $timezone Time zone of the time.
* @return \phpbb\datetime Date time object linked to the current users locale
*/
public function create_datetime(string $time = 'now', ?\DateTimeZone $timezone = null)
public function create_datetime(string $time = 'now', \DateTimeZone|null $timezone = null)
{
$timezone = $timezone ?: $this->create_timezone();
return new $this->datetime($this, $time, $timezone);
@ -723,7 +723,7 @@ class user extends \phpbb\session
* @param ?\DateTimeZone $timezone Timezone of the date/time, falls back to timezone of current user
* @return string|false Returns the unix timestamp or false if date is invalid
*/
public function get_timestamp_from_format($format, $time, ?\DateTimeZone $timezone = null)
public function get_timestamp_from_format($format, $time, \DateTimeZone|null $timezone = null)
{
$timezone = $timezone ?: $this->create_timezone();
$date = \DateTime::createFromFormat($format, $time, $timezone);

View file

@ -24,6 +24,7 @@ use phpbb\template\template;
use phpbb\user;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\Utils;
require_once __DIR__ . '/../../phpBB/includes/functions_acp.php';
@ -266,7 +267,7 @@ class phpbb_captcha_turnstile_test extends \phpbb_database_test_case
$response_mock = $this->createMock(Response::class);
$client_mock->method('request')->willReturn($response_mock);
$response_mock->method('getBody')->willReturn(json_encode(['success' => true]));
$response_mock->method('getBody')->willReturn(Utils::streamFor(json_encode(['success' => true])));
// Mock config values for secret
$this->config->method('offsetGet')->willReturn('secret_value');
@ -354,7 +355,7 @@ class phpbb_captcha_turnstile_test extends \phpbb_database_test_case
$response_mock = $this->createMock(Response::class);
$client_mock->method('request')->willReturn($response_mock);
$response_mock->method('getBody')->willReturn(json_encode(['success' => false]));
$response_mock->method('getBody')->willReturn(Utils::streamFor(json_encode(['success' => false])));
// Mock config values for secret
$this->config->method('offsetGet')->willReturn('secret_value');

View file

@ -190,7 +190,7 @@ abstract class phpbb_console_user_base extends phpbb_database_test_case
'autoescape' => false,
]
);
$twig_extension = new \phpbb\template\twig\extension($context, $twig, $this->language);
$twig_extension = new \phpbb\template\twig\extension($context, $twig, $this->language, $phpbb_dispatcher);
$phpbb_container->set('template.twig.extensions.phpbb', $twig_extension);
$twig_extensions_collection = new \phpbb\di\service_collection($phpbb_container);

View file

@ -119,6 +119,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_database_test_
$assets_bag = new \phpbb\template\assets_bag();
$context = new \phpbb\template\context();
$loader = new \phpbb\template\twig\loader('');
$this->dispatcher = new \phpbb\event\dispatcher();
$twig = new \phpbb\template\twig\environment(
$assets_bag,
$this->config,
@ -127,7 +128,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_database_test_
$cache_path,
null,
$loader,
new \phpbb\event\dispatcher(),
$this->dispatcher,
array(
'cache' => false,
'debug' => false,
@ -135,7 +136,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_database_test_
'autoescape' => false,
)
);
$this->template = new phpbb\template\twig\twig($this->phpbb_path_helper, $this->config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user)));
$this->template = new phpbb\template\twig\twig($this->phpbb_path_helper, $this->config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user, $this->dispatcher)));
$twig->setLexer(new \phpbb\template\twig\lexer($twig));
$this->extension_manager = new phpbb_mock_extension_manager(

View file

@ -87,7 +87,7 @@ class phpbb_email_parsing_test extends phpbb_test_case
'autoescape' => false,
)
);
$twig_extension = new \phpbb\template\twig\extension($context, $twig, $lang);
$twig_extension = new \phpbb\template\twig\extension($context, $twig, $lang, $dispatcher);
$phpbb_container->set('template.twig.extensions.phpbb', $twig_extension);
$twig_extensions_collection = new \phpbb\di\service_collection($phpbb_container);

View file

@ -117,7 +117,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case
$lang = new \phpbb\language\language($lang_loader);
$this->user = new \phpbb\user($lang, '\phpbb\datetime');
$this->template = new phpbb\template\twig\twig($phpbb_path_helper, $this->config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user)));
$this->template = new phpbb\template\twig\twig($phpbb_path_helper, $this->config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user, $phpbb_dispatcher)));
$twig->setLexer(new \phpbb\template\twig\lexer($twig));
}

View file

@ -16,8 +16,6 @@
*/
class phpbb_functional_extension_controller_test extends phpbb_functional_test_case
{
protected $phpbb_extension_manager;
private static $helper;
protected static $fixtures = array(

View file

@ -16,8 +16,6 @@
*/
class phpbb_functional_extension_global_lang_test extends phpbb_functional_test_case
{
protected $phpbb_extension_manager;
private static $helper;
protected static $fixtures = array(

View file

@ -17,8 +17,6 @@ require_once __DIR__ . '/../../phpBB/includes/acp/acp_modules.php';
*/
class phpbb_functional_extension_module_test extends phpbb_functional_test_case
{
protected $phpbb_extension_manager;
private static $helper;
protected static $fixtures = array(

View file

@ -16,8 +16,6 @@
*/
class phpbb_functional_extension_permission_lang_test extends phpbb_functional_test_case
{
protected $phpbb_extension_manager;
private static $helper;
protected static $fixtures = array(

View file

@ -0,0 +1,91 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
/**
* @group functional
*/
class phpbb_functional_extension_template_event_order_test extends phpbb_functional_test_case
{
static private $helper;
static protected $fixtures = [
'./',
];
static public function setUpBeforeClass(): void
{
parent::setUpBeforeClass();
self::$helper = new phpbb_test_case_helpers(__CLASS__);
self::$helper->copy_ext_fixtures(__DIR__ . '/fixtures/ext/', self::$fixtures);
}
static public function tearDownAfterClass(): void
{
parent::tearDownAfterClass();
self::$helper->restore_original_ext_dir();
}
protected function setUp(): void
{
parent::setUp();
$this->purge_cache();
}
protected function tearDown(): void
{
$this->uninstall_ext('foo/bar');
$this->uninstall_ext('foo/foo');
parent::tearDown();
}
protected static function setup_extensions()
{
return ['foo/bar', 'foo/foo'];
}
/**
* Check a controller for extension foo/bar.
*/
public function test_template_event_order()
{
global $phpbb_root_path;
$crawler = self::request('GET', 'index.php');
$quick_links_menu = $crawler->filter('ul[role="menu"]')->eq(0);
$quick_links_menu_nodes_count = (int) $quick_links_menu->filter('li')->count();
// Ensure foo/foo template event goes before foo/bar one
$this->assertStringContainsString('FOO_FOO_QUICK_LINK', $quick_links_menu->filter('li')->eq($quick_links_menu_nodes_count - 4)->filter('span')->text());
$this->assertStringContainsString('FOO_BAR_QUICK_LINK', $quick_links_menu->filter('li')->eq($quick_links_menu_nodes_count - 3)->filter('span')->text());
// Change template events order to default, put foo/bar event before foo/foo one
$this->disable_ext('foo/bar');
$this->disable_ext('foo/foo');
$this->assertTrue(copy(__DIR__ . '/fixtures/ext/foo/bar/event/template_event_order_higher.php', $phpbb_root_path . 'ext/foo/bar/event/template_event_order.php'));
$this->assertTrue(copy(__DIR__ . '/fixtures/ext/foo/foo/event/template_event_order_lower.php', $phpbb_root_path . 'ext/foo/foo/event/template_event_order.php'));
$this->install_ext('foo/bar');
$this->install_ext('foo/foo');
$crawler = self::request('GET', 'index.php');
$quick_links_menu = $crawler->filter('ul[role="menu"]')->eq(0);
$quick_links_menu_nodes_count = (int) $quick_links_menu->filter('li')->count();
// Ensure foo/foo template event goes before foo/bar one
$this->assertStringContainsString('FOO_BAR_QUICK_LINK', $quick_links_menu->filter('li')->eq($quick_links_menu_nodes_count - 4)->filter('span')->text());
$this->assertStringContainsString('FOO_FOO_QUICK_LINK', $quick_links_menu->filter('li')->eq($quick_links_menu_nodes_count - 3)->filter('span')->text());
}
}

View file

@ -14,7 +14,13 @@ services:
class: foo\bar\event\permission
tags:
- { name: event.listener }
foo_bar.listener.user_setup:
class: foo\bar\event\user_setup
tags:
- { name: event.listener }
foo_bar.listener.template_event_order:
class: foo\bar\event\template_event_order
tags:
- { name: event.listener }

View file

@ -0,0 +1,38 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace foo\bar\event;
/**
* Event listener
*/
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class template_event_order implements EventSubscriberInterface
{
static public function getSubscribedEvents()
{
return array(
'core.twig_tokenparser_constructor' => 'set_template_event_priority',
);
}
public function set_template_event_priority($event)
{
$template_event_priority_array = $event['template_event_priority_array'];
$template_event_priority_array['foo_bar'] = [
'event/navbar_header_quick_links_after' => -1,
];
$event['template_event_priority_array'] = $template_event_priority_array;
}
}

View file

@ -0,0 +1,38 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace foo\bar\event;
/**
* Event listener
*/
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class template_event_order implements EventSubscriberInterface
{
static public function getSubscribedEvents()
{
return array(
'core.twig_tokenparser_constructor' => 'set_template_event_priority',
);
}
public function set_template_event_priority($event)
{
$template_event_priority_array = $event['template_event_priority_array'];
$template_event_priority_array['foo_bar'] = [
'event/navbar_header_quick_links_after' => 1,
];
$event['template_event_priority_array'] = $template_event_priority_array;
}
}

View file

@ -0,0 +1 @@
<li><span>{{ lang('FOO_BAR_QUICK_LINK') }}</span></li>

View file

@ -1,3 +1,8 @@
services:
foo_foo.controller:
class: foo\foo\controller\controller
foo_foo.listener.template_event_order:
class: foo\foo\event\template_event_order
tags:
- { name: event.listener }

View file

@ -0,0 +1,38 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace foo\foo\event;
/**
* Event listener
*/
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class template_event_order implements EventSubscriberInterface
{
static public function getSubscribedEvents()
{
return array(
'core.twig_tokenparser_constructor' => 'set_template_event_priority',
);
}
public function set_template_event_priority($event)
{
$template_event_priority_array = $event['template_event_priority_array'];
$template_event_priority_array['foo_foo'] = [
'event/navbar_header_quick_links_after' => 1,
];
$event['template_event_priority_array'] = $template_event_priority_array;
}
}

View file

@ -0,0 +1,38 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace foo\foo\event;
/**
* Event listener
*/
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class template_event_order implements EventSubscriberInterface
{
static public function getSubscribedEvents()
{
return array(
'core.twig_tokenparser_constructor' => 'set_template_event_priority',
);
}
public function set_template_event_priority($event)
{
$template_event_priority_array = $event['template_event_priority_array'];
$template_event_priority_array['foo_foo'] = [
'event/navbar_header_quick_links_after' => -1,
];
$event['template_event_priority_array'] = $template_event_priority_array;
}
}

View file

@ -0,0 +1 @@
<li><span>{{ lang('FOO_FOO_QUICK_LINK') }}</span></li>

View file

@ -16,8 +16,6 @@
*/
class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case
{
protected $phpbb_extension_manager;
private static $helper;
protected static $fixtures = array(

View file

@ -56,7 +56,7 @@ class phpbb_mock_container_builder implements ContainerInterface
*
* @api
*/
public function get(string $id, int $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE): ?object
public function get(string $id, int $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE): object|null
{
if ($this->has($id))
{

View file

@ -82,13 +82,13 @@ class search_backend_mock implements search_backend_interface
// Nothing
}
public function create_index(int &$post_counter = 0): ?array
public function create_index(int &$post_counter = 0): array|null
{
$this->index_created = true;
return null;
}
public function delete_index(int &$post_counter = 0): ?array
public function delete_index(int &$post_counter = 0): array|null
{
$this->index_created = true;
return null;

View file

@ -221,7 +221,7 @@ class phpbb_profilefield_type_date_test extends phpbb_test_case
return implode('-', func_get_args());
}
public function create_datetime_callback($time = 'now', \DateTimeZone $timezone = null)
public function create_datetime_callback($time = 'now', \DateTimeZone|null $timezone = null)
{
$timezone = $timezone ?: $this->user->timezone;
return new \phpbb\datetime($this->user, $time, $timezone);

View file

@ -102,6 +102,7 @@ class phpbb_template_extension_test extends phpbb_template_template_test_case
$loader = new \phpbb\template\twig\loader([]);
$log = new \phpbb\log\dummy();
$assets_bag = new \phpbb\template\assets_bag();
$dispatcher = new \phpbb\event\dispatcher();
$twig = new \phpbb\template\twig\environment(
$assets_bag,
$config,
@ -110,7 +111,7 @@ class phpbb_template_extension_test extends phpbb_template_template_test_case
$cache_path,
null,
$loader,
new \phpbb\event\dispatcher(),
$dispatcher,
[
'cache' => false,
'debug' => false,
@ -126,7 +127,7 @@ class phpbb_template_extension_test extends phpbb_template_template_test_case
$cache_path,
$this->user,
[
new \phpbb\template\twig\extension($context, $twig, $this->lang),
new \phpbb\template\twig\extension($context, $twig, $this->lang, $dispatcher),
new \phpbb\template\twig\extension\avatar($avatar_helper),
new \phpbb\template\twig\extension\config($config),
new \phpbb\template\twig\extension\icon($this->user),

View file

@ -60,6 +60,7 @@ class phpbb_template_allfolder_test extends phpbb_template_template_test_case
$loader = new \phpbb\template\twig\loader('');
$log = new \phpbb\log\dummy();
$assets_bag = new \phpbb\template\assets_bag();
$dispatcher = new \phpbb\event\dispatcher();
$twig = new \phpbb\template\twig\environment(
$assets_bag,
$config,
@ -68,7 +69,7 @@ class phpbb_template_allfolder_test extends phpbb_template_template_test_case
$cache_path,
$this->extension_manager,
$loader,
new \phpbb\event\dispatcher(),
$dispatcher,
array(
'cache' => false,
'debug' => false,
@ -76,7 +77,7 @@ class phpbb_template_allfolder_test extends phpbb_template_template_test_case
'autoescape' => false,
)
);
$this->template = new \phpbb\template\twig\twig($path_helper, $config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user)), $this->extension_manager);
$this->template = new \phpbb\template\twig\twig($path_helper, $config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user, $dispatcher)), $this->extension_manager);
$twig->setLexer(new \phpbb\template\twig\lexer($twig));
$this->template_path = $this->test_path . '/templates';

View file

@ -154,6 +154,7 @@ Zeta test event in all',
$loader = new \phpbb\template\twig\loader('');
$log = new \phpbb\log\dummy();
$assets_bag = new \phpbb\template\assets_bag();
$dispatcher = new \phpbb\event\dispatcher();
$twig = new \phpbb\template\twig\environment(
$assets_bag,
$config,
@ -162,7 +163,7 @@ Zeta test event in all',
$cache_path,
$this->extension_manager,
$loader,
new \phpbb\event\dispatcher(),
$dispatcher,
array(
'cache' => false,
'debug' => false,
@ -170,7 +171,7 @@ Zeta test event in all',
'autoescape' => false,
)
);
$this->template = new \phpbb\template\twig\twig($path_helper, $config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user)), $this->extension_manager);
$this->template = new \phpbb\template\twig\twig($path_helper, $config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user, $dispatcher)), $this->extension_manager);
$twig->setLexer(new \phpbb\template\twig\lexer($twig));
$this->template->set_custom_style(((!empty($style_names)) ? $style_names : 'silver'), array($this->template_path));

View file

@ -46,6 +46,7 @@ class phpbb_template_template_includecss_test extends phpbb_template_template_te
$loader = new \phpbb\template\twig\loader('');
$log = new \phpbb\log\dummy();
$assets_bag = new \phpbb\template\assets_bag();
$dispatcher = new \phpbb\event\dispatcher();
$twig = new \phpbb\template\twig\environment(
$assets_bag,
$config,
@ -54,7 +55,7 @@ class phpbb_template_template_includecss_test extends phpbb_template_template_te
$cache_path,
null,
$loader,
new \phpbb\event\dispatcher(),
$dispatcher,
array(
'cache' => false,
'debug' => false,
@ -69,7 +70,7 @@ class phpbb_template_template_includecss_test extends phpbb_template_template_te
$twig,
$cache_path,
$this->user,
array(new \phpbb\template\twig\extension($context, $twig, $this->user)),
array(new \phpbb\template\twig\extension($context, $twig, $this->user, $dispatcher)),
new phpbb_mock_extension_manager(
__DIR__ . '/',
array(

View file

@ -97,6 +97,7 @@ class phpbb_template_template_test_case extends phpbb_test_case
$loader = new \phpbb\template\twig\loader('');
$log = new \phpbb\log\dummy();
$assets_bag = new \phpbb\template\assets_bag();
$dispatcher = new \phpbb\event\dispatcher();
$twig = new \phpbb\template\twig\environment(
$assets_bag,
$config,
@ -105,7 +106,7 @@ class phpbb_template_template_test_case extends phpbb_test_case
$cache_path,
null,
$loader,
new \phpbb\event\dispatcher(),
$dispatcher,
array(
'cache' => false,
'debug' => false,
@ -113,7 +114,8 @@ class phpbb_template_template_test_case extends phpbb_test_case
'autoescape' => false,
)
);
$this->template = new phpbb\template\twig\twig($path_helper, $config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $lang)));
$this->template = new phpbb\template\twig\twig($path_helper, $config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $lang, $dispatcher)));
$twig->setLexer(new \phpbb\template\twig\lexer($twig));
$this->template->set_custom_style('tests', $this->template_path);
}

View file

@ -47,6 +47,7 @@ class phpbb_template_template_test_case_with_tree extends phpbb_template_templat
$loader = new \phpbb\template\twig\loader('');
$log = new \phpbb\log\dummy();
$assets_bag = new \phpbb\template\assets_bag();
$dispatcher = new \phpbb\event\dispatcher();
$twig = new \phpbb\template\twig\environment(
$assets_bag,
$config,
@ -55,7 +56,7 @@ class phpbb_template_template_test_case_with_tree extends phpbb_template_templat
$cache_path,
null,
$loader,
new \phpbb\event\dispatcher(),
$dispatcher,
array(
'cache' => false,
'debug' => false,
@ -63,7 +64,7 @@ class phpbb_template_template_test_case_with_tree extends phpbb_template_templat
'autoescape' => false,
)
);
$this->template = new phpbb\template\twig\twig($this->phpbb_path_helper, $config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user)));
$this->template = new phpbb\template\twig\twig($this->phpbb_path_helper, $config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user, $dispatcher)));
$twig->setLexer(new \phpbb\template\twig\lexer($twig));
$this->template->set_custom_style('tests', array($this->template_path, $this->parent_template_path));
}

View file

@ -65,6 +65,7 @@ class twig_test extends \phpbb_test_case
$loader = new \phpbb\template\twig\loader('');
$log = new \phpbb\log\dummy();
$assets_bag = new \phpbb\template\assets_bag();
$dispatcher = new \phpbb\event\dispatcher();
$twig = new \phpbb\template\twig\environment(
$assets_bag,
$config,
@ -73,7 +74,7 @@ class twig_test extends \phpbb_test_case
$cache_path,
null,
$loader,
new \phpbb\event\dispatcher(),
$dispatcher,
[
'cache' => false,
'debug' => false,
@ -81,7 +82,7 @@ class twig_test extends \phpbb_test_case
'autoescape' => false,
]
);
$this->template = new \phpbb\template\twig\twig($path_helper, $config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user)));
$this->template = new \phpbb\template\twig\twig($path_helper, $config, $context, $twig, $cache_path, $this->user, array(new \phpbb\template\twig\extension($context, $twig, $this->user, $dispatcher)));
$twig->setLexer(new \phpbb\template\twig\lexer($twig));
}

View file

@ -407,7 +407,7 @@ class phpbb_functional_test_case extends phpbb_test_case
'autoescape' => false,
]
);
$twig_extension = new \phpbb\template\twig\extension($context, $twig, $lang);
$twig_extension = new \phpbb\template\twig\extension($context, $twig, $lang, $phpbb_dispatcher);
$container->set('template.twig.extensions.phpbb', $twig_extension);
$twig_extensions_collection = new \phpbb\di\service_collection($container);
@ -644,7 +644,7 @@ class phpbb_functional_test_case extends phpbb_test_case
$meta_refresh = $crawler->filter('meta[http-equiv="refresh"]');
// Wait for extension to be fully enabled
// Wait for extension to be fully disabled
while (count($meta_refresh))
{
preg_match('#url=.+/(adm+.+)#', $meta_refresh->attr('content'), $match);

View file

@ -346,7 +346,7 @@ class phpbb_test_case_helpers
* @param string $styles_path Path to the styles dir
* @return ContainerInterface
*/
public function set_s9e_services(ContainerInterface $container = null, $fixture = null, $styles_path = null)
public function set_s9e_services(ContainerInterface|null $container = null, $fixture = null, $styles_path = null)
{
static $first_run;
global $config, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx, $request, $user;

View file

@ -13,6 +13,7 @@
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Psr7\Response;
use phpbb\filesystem\exception\filesystem_exception;
use phpbb\filesystem\filesystem_interface;
use phpbb\update\get_updates;
@ -63,13 +64,14 @@ class phpbb_update_get_updates_test extends phpbb_test_case
public function test_download_success()
{
$response_mock = $this->createMock(Response::class);
$this->http_client->expects($this->once())
->method('request')
->with('GET', 'http://example.com/update.zip', [
'sink' => '/path/to/storage',
'allow_redirects' => false
])
->willReturn(true);
->willReturn($response_mock);
$client_reflection = new \ReflectionProperty($this->update, 'http_client');
$client_reflection->setValue($this->update, $this->http_client);
@ -84,7 +86,7 @@ class phpbb_update_get_updates_test extends phpbb_test_case
->method('request')
->willReturnCallback(function ($method, $url, $options)
{
throw new ClientException('bad client', new \GuzzleHttp\Psr7\Request($method, $url));
throw new ClientException('bad client', new \GuzzleHttp\Psr7\Request($method, $url), new \GuzzleHttp\Psr7\Response());
});
$client_reflection = new \ReflectionProperty($this->update, 'http_client');
$client_reflection->setValue($this->update, $this->http_client);