mirror of
https://github.com/phpbb/phpbb.git
synced 2025-07-26 20:08:55 +00:00
Compare commits
12 commits
990425b00f
...
491af32565
Author | SHA1 | Date | |
---|---|---|---|
|
491af32565 | ||
|
083ae1102b | ||
|
c726382d84 | ||
|
db19a4a578 | ||
|
0b3897b8c3 | ||
|
b2d48b679f | ||
|
5deeea025f | ||
|
d3bb7e5bd3 | ||
|
6947dc8c92 | ||
|
b9df5bbbf0 | ||
|
6b6b5ffc28 | ||
|
4f66ec8758 |
10 changed files with 222 additions and 96 deletions
|
@ -33,7 +33,6 @@
|
||||||
"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
43
phpBB/composer.lock
generated
|
@ -171,49 +171,6 @@
|
||||||
},
|
},
|
||||||
"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",
|
||||||
|
|
|
@ -14,21 +14,17 @@
|
||||||
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;
|
||||||
|
|
||||||
|
@ -103,24 +99,56 @@ class schema_generator
|
||||||
return $this->tables;
|
return $this->tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
$migrations = $this->class_names;
|
$dependency_counts = [];
|
||||||
$filter = function($class_name) {
|
$dependencies = [];
|
||||||
return !migrator::is_migration($class_name);
|
$applicable_migrations = [];
|
||||||
};
|
$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
|
|
||||||
{
|
{
|
||||||
$this->topologicalSort($migrations, $edges, true, $apply_for_each, $filter);
|
if (!migrator::is_migration($class_name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
catch (LogicException $e)
|
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$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."
|
||||||
|
|
|
@ -34,16 +34,17 @@ self.addEventListener('push', event => {
|
||||||
notificationVersion = parseInt(notificationData.version, 10);
|
notificationVersion = parseInt(notificationData.version, 10);
|
||||||
pushToken = notificationData.token;
|
pushToken = notificationData.token;
|
||||||
} catch {
|
} catch {
|
||||||
self.registration.showNotification(event.data.text());
|
event.waitUntil(self.registration.showNotification(event.data.text()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.waitUntil((async() => {
|
||||||
const getNotificationUrl = '{{ U_WEBPUSH_GET_NOTIFICATION }}';
|
const getNotificationUrl = '{{ U_WEBPUSH_GET_NOTIFICATION }}';
|
||||||
const assetsVersion = parseInt('{{ ASSETS_VERSION }}', 10);
|
const assetsVersion = parseInt('{{ ASSETS_VERSION }}', 10);
|
||||||
|
|
||||||
// Force update if versions differ
|
// Force update if versions differ
|
||||||
if (assetsVersion !== notificationVersion) {
|
if (assetsVersion !== notificationVersion) {
|
||||||
self.registration.update();
|
await self.registration.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
@ -52,23 +53,29 @@ self.addEventListener('push', event => {
|
||||||
formData.append('user_id', userId.toString(10));
|
formData.append('user_id', userId.toString(10));
|
||||||
formData.append('token', pushToken);
|
formData.append('token', pushToken);
|
||||||
|
|
||||||
fetch(getNotificationUrl, {
|
try {
|
||||||
|
const response = await fetch(getNotificationUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
},
|
},
|
||||||
body: formData,
|
body: formData,
|
||||||
})
|
});
|
||||||
.then(response => response.json())
|
|
||||||
.then(response => {
|
const responseData = await response.json();
|
||||||
const responseBody = response.title + '\n' + response.text;
|
|
||||||
|
const responseBody = responseData.title + '\n' + responseData.text;
|
||||||
const options = {
|
const options = {
|
||||||
body: responseBody,
|
body: responseBody,
|
||||||
data: response,
|
data: responseData,
|
||||||
icon: response.avatar.src,
|
icon: responseData.avatar.src,
|
||||||
};
|
};
|
||||||
self.registration.showNotification(response.heading, options);
|
|
||||||
});
|
await self.registration.showNotification(responseData.heading, options);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Push error:', e);
|
||||||
|
}
|
||||||
|
})());
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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('html_attr') }}" width="1" height="1" alt="">
|
<img class="sr-only" aria-hidden="true" src="{{ CRON_TASK_URL|e('url') }}" width="1" height="1" alt="">
|
||||||
|
|
131
tests/cron/wrapper_test.php
Normal file
131
tests/cron/wrapper_test.php
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
<?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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 = [])
|
protected function setup_engine(array $new_config = [], string $template_path = '')
|
||||||
{
|
{
|
||||||
global $config, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx;
|
global $config, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx;
|
||||||
|
|
||||||
|
|
|
@ -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())
|
protected function setup_engine(array $new_config = array(), string $template_path = '')
|
||||||
{
|
{
|
||||||
global $phpbb_root_path, $phpEx, $user;
|
global $phpbb_root_path, $phpEx, $user;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?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.
|
||||||
|
@ -14,6 +17,7 @@
|
||||||
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;
|
||||||
|
@ -68,7 +72,7 @@ class phpbb_template_template_test_case extends phpbb_test_case
|
||||||
return $defaults;
|
return $defaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function setup_engine(array $new_config = array())
|
protected function setup_engine(array $new_config = array(), string $template_path = '')
|
||||||
{
|
{
|
||||||
global $phpbb_root_path, $phpEx;
|
global $phpbb_root_path, $phpEx;
|
||||||
|
|
||||||
|
@ -90,7 +94,7 @@ class phpbb_template_template_test_case extends phpbb_test_case
|
||||||
$phpEx
|
$phpEx
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->template_path = $this->test_path . '/templates';
|
$this->template_path = $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();
|
||||||
|
|
|
@ -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 = array())
|
protected function setup_engine(array $new_config = [], string $template_path = '')
|
||||||
{
|
{
|
||||||
global $phpbb_root_path, $phpEx, $user;
|
global $phpbb_root_path, $phpEx, $user;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue