Skip to content

Commit 985ec1a

Browse files
committed
Create text reparser task dynamically
test
1 parent 9f3e1b7 commit 985ec1a

3 files changed

Lines changed: 205 additions & 8 deletions

File tree

config/services.yml

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,13 @@ services:
8181
tags:
8282
- { name: text_reparser.plugin }
8383

84+
phpbb.pages.cron.task.text_reparser.factory:
85+
class: phpbb\pages\textreparser\cron_text_reparser_factory
86+
8487
phpbb.pages.cron.task.text_reparser:
8588
class: phpbb\cron\task\text_reparser\reparser
89+
factory: ['@phpbb.pages.cron.task.text_reparser.factory', 'create']
8690
arguments:
87-
- '@config'
88-
- '@config_text'
89-
- '@text_reparser.lock'
90-
- '@text_reparser.manager'
91-
- '@text_reparser_collection'
92-
calls:
93-
- [set_name, [cron.task.text_reparser.phpbb_pages]]
94-
- [set_reparser, [phpbb.pages.text_reparser.page_text]]
91+
- '@service_container'
9592
tags:
9693
- { name: cron.task }
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
/**
3+
*
4+
* Pages extension for the phpBB Forum Software package.
5+
*
6+
* @copyright (c) 2025 phpBB Limited <https://www.phpbb.com>
7+
* @license GNU General Public License, version 2 (GPL-2.0)
8+
*
9+
*/
10+
11+
namespace phpbb\pages\tests\text_reparser;
12+
13+
use phpbb\pages\textreparser\cron_text_reparser_factory;
14+
use Symfony\Component\DependencyInjection\ContainerInterface;
15+
16+
class cron_text_reparser_factory_test extends \phpbb_test_case
17+
{
18+
/** @var \PHPUnit\Framework\MockObject\MockObject|ContainerInterface */
19+
protected $container;
20+
21+
/** @var cron_text_reparser_factory */
22+
protected $factory;
23+
24+
protected function setUp(): void
25+
{
26+
$this->container = $this->createMock(ContainerInterface::class);
27+
$this->factory = new cron_text_reparser_factory();
28+
}
29+
30+
public function test_create_reparser()
31+
{
32+
// Mock the necessary services
33+
$config = $this->createMock(\phpbb\config\config::class);
34+
$config_text = $this->createMock(\phpbb\config\db_text::class);
35+
$reparse_lock = $this->createMock(\phpbb\lock\db::class);
36+
$reparser_manager = $this->createMock(\phpbb\textreparser\manager::class);
37+
$reparsers = $this->createMock(\phpbb\di\service_collection::class);
38+
39+
// Configure a container to return our mocked services
40+
$this->container->method('has')
41+
->willReturnCallback(function($service) {
42+
$valid_services = [
43+
'config' => true,
44+
'config_text' => true,
45+
'text_reparser.lock' => true,
46+
'text_reparser.manager' => true,
47+
'text_reparser_collection' => true,
48+
];
49+
return $valid_services[$service] ?? false;
50+
});
51+
52+
$this->container->method('get')
53+
->willReturnCallback(function($service) use ($config, $config_text, $reparse_lock, $reparser_manager, $reparsers) {
54+
$services = [
55+
'config' => $config,
56+
'config_text' => $config_text,
57+
'text_reparser.lock' => $reparse_lock,
58+
'text_reparser.manager' => $reparser_manager,
59+
'text_reparser_collection' => $reparsers,
60+
];
61+
return $services[$service] ?? null;
62+
});
63+
64+
$reparser = $this->factory->create($this->container);
65+
66+
// Assert the reparser was created successfully
67+
$this->assertInstanceOf(\phpbb\cron\task\text_reparser\reparser::class, $reparser);
68+
$this->assertEquals('cron.task.text_reparser.phpbb_pages', $reparser->get_name());
69+
}
70+
71+
public function test_missing_required_service()
72+
{
73+
// Mock container to simulate missing service
74+
$this->container->method('has')
75+
->willReturn(false);
76+
77+
$this->container->method('get')
78+
->willReturn(null);
79+
80+
$this->expectException(\ArgumentCountError::class);
81+
$this->expectExceptionMessage('Too few arguments to function phpbb\cron\task\text_reparser\reparser::__construct(), 0 passed and exactly 5 expected');
82+
83+
$this->factory->create($this->container);
84+
}
85+
86+
public function test_service_name_mapping()
87+
{
88+
$reflection = new \ReflectionClass(cron_text_reparser_factory::class);
89+
$method = $reflection->getMethod('get_service_name');
90+
$method->setAccessible(true);
91+
92+
$expected_mappings = [
93+
'config' => 'config',
94+
'config_text' => 'config_text',
95+
'reparse_lock' => 'text_reparser.lock',
96+
'reparser_manager' => 'text_reparser.manager',
97+
'reparsers' => 'text_reparser_collection',
98+
'unknown_param' => 'unknown_param',
99+
];
100+
101+
foreach ($expected_mappings as $param => $expected)
102+
{
103+
$this->assertEquals(
104+
$expected,
105+
$method->invoke($this->factory, $param),
106+
"Service mapping failed for parameter '$param'"
107+
);
108+
}
109+
}
110+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
/**
3+
*
4+
* Pages extension for the phpBB Forum Software package.
5+
*
6+
* @copyright (c) 2025 phpBB Limited <https://www.phpbb.com>
7+
* @license GNU General Public License, version 2 (GPL-2.0)
8+
*
9+
*/
10+
11+
namespace phpbb\pages\textreparser;
12+
13+
/**
14+
* Factory for creating cron text reparser task instances
15+
*
16+
* This factory handles the dynamic creation of text reparser tasks,
17+
* ensuring compatibility with different phpBB versions by using reflection
18+
* to determine and provide the correct constructor arguments.
19+
*/
20+
class cron_text_reparser_factory
21+
{
22+
/**
23+
* Creates a new instance of the text reparser cron task
24+
*
25+
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container Service container
26+
* @return \phpbb\cron\task\text_reparser\reparser Configured a text reparser cron task
27+
* @throws \ReflectionException If the reparser class cannot be reflected
28+
*/
29+
public function create($container)
30+
{
31+
$args = $this->get_constructor_arguments($container);
32+
33+
// Using ReflectionClass to instantiate with a variable number of arguments
34+
$reflection = new \ReflectionClass(\phpbb\cron\task\text_reparser\reparser::class);
35+
$reparser = $reflection->newInstanceArgs($args);
36+
37+
$reparser->set_name('cron.task.text_reparser.phpbb_pages');
38+
$reparser->set_reparser('phpbb.pages.text_reparser.page_text');
39+
return $reparser;
40+
}
41+
42+
/**
43+
* Gets the constructor arguments for the reparser based on reflection
44+
*
45+
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container Service container
46+
* @return array Array of constructor arguments
47+
* @throws \ReflectionException If the reparser class cannot be reflected
48+
*/
49+
private function get_constructor_arguments($container)
50+
{
51+
$reflection = new \ReflectionClass(\phpbb\cron\task\text_reparser\reparser::class);
52+
$constructor = $reflection->getConstructor();
53+
$params = $constructor->getParameters();
54+
55+
$arguments = array();
56+
foreach ($params as $param)
57+
{
58+
$service_name = $this->get_service_name($param->getName());
59+
if ($container->has($service_name))
60+
{
61+
$arguments[] = $container->get($service_name);
62+
}
63+
else if ($param->isOptional())
64+
{
65+
$arguments[] = $param->getDefaultValue();
66+
}
67+
}
68+
69+
return $arguments;
70+
}
71+
72+
/**
73+
* Maps parameter names to their corresponding service IDs
74+
*
75+
* @param string $param_name Name of the parameter from the constructor
76+
* @return string Service ID corresponding to the parameter
77+
*/
78+
private function get_service_name($param_name)
79+
{
80+
$serviceMap = [
81+
'config' => 'config',
82+
'config_text' => 'config_text',
83+
'reparse_lock' => 'text_reparser.lock',
84+
'reparser_manager' => 'text_reparser.manager',
85+
'reparsers' => 'text_reparser_collection'
86+
];
87+
88+
return $serviceMap[$param_name] ?? $param_name;
89+
}
90+
}

0 commit comments

Comments
 (0)