Skip to content
Merged
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
3 changes: 1 addition & 2 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@
</UndefinedGlobalVariable>
</file>
<file src="tests/_support/Config/Routes.php">
<UndefinedGlobalVariable occurrences="2">
<code>$routes</code>
<UndefinedGlobalVariable occurrences="5">
<code>$routes</code>
</UndefinedGlobalVariable>
</file>
Expand Down
24 changes: 22 additions & 2 deletions system/Commands/Utilities/Routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ class Routes extends BaseCommand
* @var array<string, string>
*/
protected $options = [
'-h' => 'Sort by Handler.',
'-h' => 'Sort by Handler.',
'--host' => 'Specify hostname in request URI.',
];

/**
Expand All @@ -78,9 +79,24 @@ class Routes extends BaseCommand
public function run(array $params)
{
$sortByHandler = array_key_exists('h', $params);
$host = $params['host'] ?? null;

// Set HTTP_HOST
if ($host) {
$request = Services::request();
$_SERVER = $request->getServer();
$_SERVER['HTTP_HOST'] = $host;
$request->setGlobal('server', $_SERVER);
}

$collection = Services::routes()->loadRoutes();
$methods = [

// Reset HTTP_HOST
if ($host) {
unset($_SERVER['HTTP_HOST']);
}

$methods = [
'get',
'head',
'post',
Expand Down Expand Up @@ -171,6 +187,10 @@ public function run(array $params)
usort($tbody, static fn ($handler1, $handler2) => strcmp($handler1[3], $handler2[3]));
}

if ($host) {
CLI::write('Host: ' . $host);
}

CLI::table($tbody, $thead);
}
}
3 changes: 3 additions & 0 deletions tests/_support/Config/Routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@
// This is a simple file to include for testing the RouteCollection class.
$routes->add('testing', 'TestController::index', ['as' => 'testing-index']);
$routes->get('closure', static fn () => 'closure test');
$routes->get('/', 'Blog::index', ['hostname' => 'blog.example.com']);
$routes->get('/', 'Sub::index', ['subdomain' => 'sub']);
$routes->get('/all', 'AllDomain::index', ['subdomain' => '*']);
61 changes: 59 additions & 2 deletions tests/system/Commands/RoutesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private function getCleanRoutes(): RouteCollection

public function testRoutesCommand()
{
$this->getCleanRoutes();
Services::injectMock('routes', null);

command('routes');

Expand All @@ -79,7 +79,7 @@ public function testRoutesCommand()

public function testRoutesCommandSortByHandler()
{
$this->getCleanRoutes();
Services::injectMock('routes', null);

command('routes -h');

Expand All @@ -103,6 +103,62 @@ public function testRoutesCommandSortByHandler()
$this->assertStringContainsString($expected, $this->getBuffer());
}

public function testRoutesCommandHostHostname()
{
Services::injectMock('routes', null);

command('routes --host blog.example.com');

$expected = <<<'EOL'
Host: blog.example.com
+---------+---------+---------------+----------------------------------------+----------------+---------------+
| Method | Route | Name | Handler | Before Filters | After Filters |
+---------+---------+---------------+----------------------------------------+----------------+---------------+
| GET | / | » | \App\Controllers\Blog::index | | toolbar |
| GET | closure | » | (Closure) | | toolbar |
| GET | all | » | \App\Controllers\AllDomain::index | | toolbar |
| GET | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| HEAD | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| POST | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| PUT | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| DELETE | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| OPTIONS | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| TRACE | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| CONNECT | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| CLI | testing | testing-index | \App\Controllers\TestController::index | | |
+---------+---------+---------------+----------------------------------------+----------------+---------------+
EOL;
$this->assertStringContainsString($expected, $this->getBuffer());
}

public function testRoutesCommandHostSubdomain()
{
Services::injectMock('routes', null);

command('routes --host sub.example.com');

$expected = <<<'EOL'
Host: sub.example.com
+---------+---------+---------------+----------------------------------------+----------------+---------------+
| Method | Route | Name | Handler | Before Filters | After Filters |
+---------+---------+---------------+----------------------------------------+----------------+---------------+
| GET | / | » | \App\Controllers\Sub::index | | toolbar |
| GET | closure | » | (Closure) | | toolbar |
| GET | all | » | \App\Controllers\AllDomain::index | | toolbar |
| GET | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| HEAD | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| POST | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| PUT | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| DELETE | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| OPTIONS | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| TRACE | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| CONNECT | testing | testing-index | \App\Controllers\TestController::index | | toolbar |
| CLI | testing | testing-index | \App\Controllers\TestController::index | | |
+---------+---------+---------------+----------------------------------------+----------------+---------------+
EOL;
$this->assertStringContainsString($expected, $this->getBuffer());
}

public function testRoutesCommandAutoRouteImproved()
{
$routes = $this->getCleanRoutes();
Expand Down Expand Up @@ -139,6 +195,7 @@ public function testRoutesCommandAutoRouteImproved()
public function testRoutesCommandRouteLegacy()
{
$routes = $this->getCleanRoutes();
$routes->loadRoutes();

$routes->setAutoRoute(true);
$namespace = 'Tests\Support\Controllers';
Expand Down
3 changes: 3 additions & 0 deletions user_guide_src/source/changelogs/v4.4.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ Enhancements
Commands
========

- Now ``spark routes`` command can specify the host in the request URL.
See :ref:`routing-spark-routes-specify-host`.

Testing
=======

Expand Down
11 changes: 11 additions & 0 deletions user_guide_src/source/incoming/routing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -858,3 +858,14 @@ Sort by Handler
You can sort the routes by *Handler*::

> php spark routes -h

.. _routing-spark-routes-specify-host:

Specify Host
------------

.. versionadded:: 4.4.0

You can specify the host in the request URL with the ``--host`` option::

> php spark routes --host accounts.example.com