Compare commits

..

1 commit

Author SHA1 Message Date
Matt Friedman
990425b00f
Merge 6b6b5ffc28 into 2fce8aeb3e 2025-05-30 01:52:31 -05:00
9 changed files with 70 additions and 189 deletions

View file

@ -33,6 +33,7 @@
"ext-sodium": "*", "ext-sodium": "*",
"bantu/ini-get-wrapper": "~1.0", "bantu/ini-get-wrapper": "~1.0",
"carlos-mg89/oauth": "^0.8.15", "carlos-mg89/oauth": "^0.8.15",
"chita/topological_sort": "^3.0",
"composer/composer": "^2.0", "composer/composer": "^2.0",
"composer/installers": "^1.9", "composer/installers": "^1.9",
"composer/package-versions-deprecated": "^1.11", "composer/package-versions-deprecated": "^1.11",

43
phpBB/composer.lock generated
View file

@ -171,6 +171,49 @@
}, },
"time": "2025-02-08T12:14:07+00:00" "time": "2025-02-08T12:14:07+00:00"
}, },
{
"name": "chita/topological_sort",
"version": "v3.0.1",
"source": {
"type": "git",
"url": "https://github.com/CHItA/TopologicalSort.git",
"reference": "9e0401c712d0c7cf012f264cc105669844d2479e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/CHItA/TopologicalSort/zipball/9e0401c712d0c7cf012f264cc105669844d2479e",
"reference": "9e0401c712d0c7cf012f264cc105669844d2479e",
"shasum": ""
},
"require": {
"php": ">=7.1.0"
},
"require-dev": {
"phpunit/phpunit": "^7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"CHItA\\TopologicalSort\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Máté Bartus",
"email": "mate.bartus@gmail.com"
}
],
"description": "Topological sort function",
"support": {
"issues": "https://github.com/CHItA/TopologicalSort/issues",
"source": "https://github.com/CHItA/TopologicalSort/tree/v3.0.1"
},
"time": "2021-01-04T21:31:59+00:00"
},
{ {
"name": "composer/ca-bundle", "name": "composer/ca-bundle",
"version": "1.5.6", "version": "1.5.6",

View file

@ -14,17 +14,21 @@
namespace phpbb\db\migration; namespace phpbb\db\migration;
use Closure; use Closure;
use LogicException;
use phpbb\config\config; use phpbb\config\config;
use phpbb\db\driver\driver_interface; use phpbb\db\driver\driver_interface;
use phpbb\db\migrator; use phpbb\db\migrator;
use phpbb\db\tools\tools_interface; use phpbb\db\tools\tools_interface;
use UnexpectedValueException; use UnexpectedValueException;
use CHItA\TopologicalSort\TopologicalSort;
/** /**
* The schema generator generates the schema based on the existing migrations * The schema generator generates the schema based on the existing migrations
*/ */
class schema_generator class schema_generator
{ {
use TopologicalSort;
/** @var config */ /** @var config */
protected $config; protected $config;
@ -99,56 +103,24 @@ class schema_generator
return $this->tables; return $this->tables;
} }
$dependency_counts = []; $migrations = $this->class_names;
$dependencies = []; $filter = function($class_name) {
$applicable_migrations = []; return !migrator::is_migration($class_name);
$migration_count = 0; };
foreach ($this->class_names as $class_name)
$edges = function($class_name) {
return $class_name::depends_on();
};
$apply_for_each = function($class_name) {
$this->apply_migration_to_schema($class_name);
};
try
{ {
if (!migrator::is_migration($class_name)) $this->topologicalSort($migrations, $edges, true, $apply_for_each, $filter);
{
continue;
}
$migration_count++;
$migration_dependencies = $class_name::depends_on();
if (empty($migration_dependencies))
{
$applicable_migrations[] = $class_name;
continue;
}
$dependency_counts[$class_name] = count($migration_dependencies);
foreach ($migration_dependencies as $migration_dependency)
{
$dependencies[$migration_dependency][] = $class_name;
}
} }
catch (LogicException $e)
$applied_migrations = 0;
while (!empty($applicable_migrations))
{
$migration = array_pop($applicable_migrations);
$this->apply_migration_to_schema($migration);
++$applied_migrations;
if (!array_key_exists($migration, $dependencies))
{
continue;
}
$dependents = $dependencies[$migration];
foreach ($dependents as $dependent)
{
$dependency_counts[$dependent]--;
if ($dependency_counts[$dependent] === 0)
{
$applicable_migrations[] = $dependent;
}
}
}
if ($migration_count !== $applied_migrations)
{ {
throw new UnexpectedValueException( throw new UnexpectedValueException(
"Migrations either have circular dependencies or unsatisfiable dependencies." "Migrations either have circular dependencies or unsatisfiable dependencies."

View file

@ -4,4 +4,4 @@
to hide visually and `aria-hidden="true"` to hide from screen-readers; using to hide visually and `aria-hidden="true"` to hide from screen-readers; using
`hidden` or `display: none` would prevent the task from running. `hidden` or `display: none` would prevent the task from running.
#} #}
<img class="sr-only" aria-hidden="true" src="{{ CRON_TASK_URL|e('url') }}" width="1" height="1" alt=""> <img class="sr-only" aria-hidden="true" src="{{ CRON_TASK_URL|e('html_attr') }}" width="1" height="1" alt="">

View file

@ -1,131 +0,0 @@
<?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.
*
*/
require_once __DIR__ . '/../template/template_test_case.php';
class phpbb_cron_wrapper_test extends phpbb_template_template_test_case
{
private $task;
private $routing_helper;
private $wrapper;
protected function setUp(): void
{
global $phpbb_root_path;
$this->setup_engine([], $phpbb_root_path . 'styles/all/template');
global $phpbb_filesystem;
$phpbb_filesystem = new \phpbb\filesystem\filesystem();
$this->task = $this->createMock(\phpbb\cron\task\task::class);
$this->routing_helper = $this->createMock(\phpbb\routing\helper::class);
$this->wrapper = new \phpbb\cron\task\wrapper(
$this->task,
$this->routing_helper,
$this->template
);
}
public function test_generate_template_pagination()
{
$this->task = $this->createMock(\phpbb\cron\task\parametrized::class);
$this->task->expects($this->any())
->method('get_parameters')
->willReturn(['f' => '5']);
$this->task->expects($this->any())
->method('get_name')
->willReturn('test_task');
$this->routing_helper = $this->createMock(\phpbb\routing\helper::class);
$this->routing_helper->expects($this->any())
->method('route')
->with('phpbb_cron_run', ['cron_type' => 'test_task', 'f' => '5'])
->willReturn('app.php/cron/foo?f=5');
$this->wrapper = new \phpbb\cron\task\wrapper(
$this->task,
$this->routing_helper,
$this->template
);
$this->assertEquals('<img class="sr-only" aria-hidden="true" src="app.php%2Fcron%2Ffoo%3Ff%3D5" width="1" height="1" alt="">', str_replace(["\n", "\t"], '', $this->wrapper->get_html_tag()));
}
public function test_is_parametrized_false()
{
$this->assertFalse($this->wrapper->is_parametrized());
}
public function test_is_ready()
{
$this->task->method('is_runnable')->willReturn(true);
$this->task->method('should_run')->willReturn(true);
$this->assertTrue($this->wrapper->is_ready());
}
public function test_get_url_non_parametrized()
{
$this->task->method('get_name')->willReturn('test_task');
$this->routing_helper->expects($this->once())
->method('route')
->with('phpbb_cron_run', ['cron_type' => 'test_task'])
->willReturn('/cron/url');
$this->assertEquals('/cron/url', $this->wrapper->get_url());
}
public function test_get_html_tag()
{
$this->template = $this->createMock(\phpbb\template\template::class);
$this->wrapper = new \phpbb\cron\task\wrapper(
$this->task,
$this->routing_helper,
$this->template
);
$this->template->expects($this->once())
->method('set_filenames');
$this->template->expects($this->once())
->method('assign_var');
$this->template->expects($this->once())
->method('assign_display')
->willReturn('<img src="cron">');
$this->assertEquals('<img src="cron">', $this->wrapper->get_html_tag());
}
public function test_call_forwards_to_task()
{
$this->task = $this->getMockBuilder(\phpbb\cron\task\task::class)
->disableOriginalConstructor()
->setMethods(['get_name', 'run', 'is_runnable', 'should_run', 'some_method'])
->getMock();
$this->routing_helper = $this->createMock(\phpbb\routing\helper::class);
$this->wrapper = new \phpbb\cron\task\wrapper(
$this->task,
$this->routing_helper,
$this->template
);
$this->task->expects($this->once())
->method('some_method')
->with('arg1', 'arg2')
->willReturn('result');
$result = $this->wrapper->some_method('arg1', 'arg2');
$this->assertEquals('result', $result);
}
}

View file

@ -15,7 +15,7 @@ require_once __DIR__ . '/template_test_case.php';
class phpbb_template_extension_test extends phpbb_template_template_test_case class phpbb_template_extension_test extends phpbb_template_template_test_case
{ {
protected function setup_engine(array $new_config = [], string $template_path = '') protected function setup_engine(array $new_config = [])
{ {
global $config, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx; global $config, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx;

View file

@ -21,7 +21,7 @@ class phpbb_template_template_includecss_test extends phpbb_template_template_te
/** @var string */ /** @var string */
protected $parent_template_path; protected $parent_template_path;
protected function setup_engine(array $new_config = array(), string $template_path = '') protected function setup_engine(array $new_config = array())
{ {
global $phpbb_root_path, $phpEx, $user; global $phpbb_root_path, $phpEx, $user;

View file

@ -1,7 +1,4 @@
<?php <?php
use phpbb\template\twig\twig;
/** /**
* *
* This file is part of the phpBB Forum Software package. * This file is part of the phpBB Forum Software package.
@ -17,7 +14,6 @@ use phpbb\template\twig\twig;
class phpbb_template_template_test_case extends phpbb_test_case class phpbb_template_template_test_case extends phpbb_test_case
{ {
protected $lang; protected $lang;
/** @var twig */
protected $template; protected $template;
protected $template_path; protected $template_path;
protected $user; protected $user;
@ -72,7 +68,7 @@ class phpbb_template_template_test_case extends phpbb_test_case
return $defaults; return $defaults;
} }
protected function setup_engine(array $new_config = array(), string $template_path = '') protected function setup_engine(array $new_config = array())
{ {
global $phpbb_root_path, $phpEx; global $phpbb_root_path, $phpEx;
@ -94,7 +90,7 @@ class phpbb_template_template_test_case extends phpbb_test_case
$phpEx $phpEx
); );
$this->template_path = $template_path ?: $this->test_path . '/templates'; $this->template_path = $this->test_path . '/templates';
$cache_path = $phpbb_root_path . 'cache/twig'; $cache_path = $phpbb_root_path . 'cache/twig';
$context = new \phpbb\template\context(); $context = new \phpbb\template\context();

View file

@ -21,7 +21,7 @@ class phpbb_template_template_test_case_with_tree extends phpbb_template_templat
/** @var string */ /** @var string */
protected $parent_template_path; protected $parent_template_path;
protected function setup_engine(array $new_config = [], string $template_path = '') protected function setup_engine(array $new_config = array())
{ {
global $phpbb_root_path, $phpEx, $user; global $phpbb_root_path, $phpEx, $user;