Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 20 additions & 59 deletions routing/page_loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,78 +3,39 @@
*
* Pages extension for the phpBB Forum Software package.
*
* @copyright (c) 2015 phpBB Limited <https://www.phpbb.com>
* @copyright (c) 2025 phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
*/
// phpcs:disable PSR1.Files.SideEffects

namespace phpbb\pages\routing;

use phpbb\db\driver\driver_interface;
use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use ReflectionMethod;
use Symfony\Component\Config\Loader\LoaderInterface;

/**
* Loads routes defined in Page's database.
* This code determines which page_loader class to use based on the phpBB version.
* It checks if the Symfony LoaderInterface::load() method has a return type,
* which indicates Symfony 7+ (phpBB4), otherwise falls back to phpBB3 compatibility.
* The conditional is mandatory to ensure we only define the class if it does not
* already exist in this request.
*
* @noinspection PhpMultipleClassDeclarationsInspection
*/
class page_loader extends Loader
if (!class_exists(page_loader::class, false))
{
/** @var driver_interface */
protected $db;

/** @var string */
protected $pages_table;

/**
* Constructor
*
* @param driver_interface $db Database connection
* @param string $pages_table Table name
* @access public
*/
public function __construct(driver_interface $db, $pages_table)
{
$this->db = $db;
$this->pages_table = $pages_table;
}
$method = new ReflectionMethod(LoaderInterface::class, 'load');

/**
* Loads routes defined in Page's database.
*
* @param string $resource Resource (not used, but required by parent interface)
* @param string|null $type The resource type
*
* @return RouteCollection A RouteCollection instance
*
* @api
*/
public function load($resource, $type = null)
// phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
if ($method->hasReturnType())
{
$collection = new RouteCollection();

$sql = 'SELECT page_id, page_route
FROM ' . $this->pages_table;
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$route = new Route('/' . $row['page_route']);
$route->setDefault('_controller', 'phpbb.pages.controller:display');
$route->setDefault('route', $row['page_route']);
$collection->add('phpbb_pages_dynamic_route_' . $row['page_id'], $route);
}
$this->db->sql_freeresult();

return $collection;
class page_loader extends page_loader_phpbb4 {}
}

/**
* {@inheritdoc}
*
* @api
*/
public function supports($resource, $type = null)
else
{
return $type === 'phpbb_pages_route';
class page_loader extends page_loader_phpbb3 {}
}
// phpcs:enable PSR1.Classes.ClassDeclaration.MultipleClasses
}
// phpcs:enable PSR1.Files.SideEffects
76 changes: 76 additions & 0 deletions routing/page_loader_core.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
/**
*
* Pages extension for the phpBB Forum Software package.
*
* @copyright (c) 2015 phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
*/

namespace phpbb\pages\routing;

use phpbb\db\driver\driver_interface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

/**
* Core loader logic for loading routes from the database.
*/
class page_loader_core
{
/** @var driver_interface */
protected $db;

/** @var string */
protected $pages_table;

/**
* Constructor for the page_loader_core class.
*
* @param driver_interface $db The database driver instance.
* @param string $pages_table The name of the pages table in the database.
*/
public function __construct(driver_interface $db, string $pages_table)
{
$this->db = $db;
$this->pages_table = $pages_table;
}

/**
* Loads routes defined in Page's database.
*
* @return RouteCollection A RouteCollection instance
*
* @api
*/
public function loadRoutes(): RouteCollection
{
$collection = new RouteCollection();

$sql = 'SELECT page_id, page_route
FROM ' . $this->pages_table;
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$route = new Route('/' . $row['page_route']);
$route->setDefault('_controller', 'phpbb.pages.controller:display');
$route->setDefault('route', $row['page_route']);
$collection->add('phpbb_pages_dynamic_route_' . $row['page_id'], $route);
}
$this->db->sql_freeresult();

return $collection;
}

/**
* Checks if the loader supports the specified type.
*
* @param mixed $type The type to check support for.
* @return bool True if the type is supported, false otherwise.
*/
public function supportsType($type): bool
{
return $type === 'phpbb_pages_route';
}
}
64 changes: 64 additions & 0 deletions routing/page_loader_phpbb3.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/**
*
* Pages extension for the phpBB Forum Software package.
*
* @copyright (c) 2025 phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
*/

namespace phpbb\pages\routing;

use InvalidArgumentException;
use phpbb\db\driver\driver_interface;
use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\Routing\RouteCollection;

/**
* phpBB 3 and Symfony 3 through 6 adapter for page loader.
*/
class page_loader_phpbb3 extends Loader
{
/** @var page_loader_core */
protected $core;

/**
* Constructor for the page_loader_phpbb3 class.
*
* @param driver_interface $db The database driver instance.
* @param string $pages_table The name of the pages table in the database.
*/
public function __construct(driver_interface $db, string $pages_table)
{
$this->core = new page_loader_core($db, $pages_table);
}

/**
* Loads routes from the database.
*
* @param mixed $resource The resource to load routes from.
* @param string|null $type The type of the resource, or null if not specified.
* @return RouteCollection The collection of loaded routes.
*/
public function load($resource, $type = null)
{
if (!is_string($type) && $type !== null)
{
throw new InvalidArgumentException('Type must be string or null');
}
return $this->core->loadRoutes();
}

/**
* Determines if the given resource is supported based on its type.
*
* @param mixed $resource The resource to be checked.
* @param string|null $type The type of the resource, or null for default processing.
* @return bool True if the resource type is supported, false otherwise.
*/
public function supports($resource, $type = null): bool
{
return $this->core->supportsType($type);
}
}
60 changes: 60 additions & 0 deletions routing/page_loader_phpbb4.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
*
* Pages extension for the phpBB Forum Software package.
*
* @copyright (c) 2025 phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
*/

namespace phpbb\pages\routing;

use phpbb\db\driver\driver_interface;
use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\Routing\RouteCollection;

/**
* phpbb 4 and Symfony 7 adapter for page loader.
*/
class page_loader_phpbb4 extends Loader
{
/** @var page_loader_core */
protected page_loader_core $core;

/**
* Constructor for the page_loader_phpbb4 class.
*
* @param driver_interface $db The database driver instance.
* @param string $pages_table The name of the pages table in the database.
*/
public function __construct(driver_interface $db, string $pages_table)
{
$this->core = new page_loader_core($db, $pages_table);
parent::__construct();
}

/**
* Loads a set of routes from a specified resource.
*
* @param mixed $resource The resource to load routes from.
* @param string|null $type The type of the resource, or null if not specified.
* @return RouteCollection The collection of loaded routes.
*/
public function load(mixed $resource, ?string $type = null): RouteCollection
{
return $this->core->loadRoutes();
}

/**
* Checks if the loader supports the specified resource and type.
*
* @param mixed $resource The resource to check support for.
* @param string|null $type The type of the resource, or null if not specified.
* @return bool True if the loader supports the resource and type, false otherwise.
*/
public function supports(mixed $resource, string $type = null): bool
{
return $this->core->supportsType($type);
}
}