Skip to content

Commit 00a6b35

Browse files
committed
Extension: better URL handling [closes #43]
1 parent bcaad99 commit 00a6b35

File tree

4 files changed

+104
-7
lines changed

4 files changed

+104
-7
lines changed

src/DI/ConsoleExtension.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
use Contributte\Console\Application;
66
use Contributte\Console\CommandLoader\ContainerCommandLoader;
7+
use Contributte\Console\Http\ConsoleRequestFactory;
78
use Nette\DI\CompilerExtension;
89
use Nette\DI\Definitions\ServiceDefinition;
910
use Nette\DI\Definitions\Statement;
1011
use Nette\DI\MissingServiceException;
1112
use Nette\DI\ServiceCreationException;
12-
use Nette\Http\Request;
13-
use Nette\Http\UrlScript;
13+
use Nette\Http\RequestFactory;
1414
use Nette\Schema\Expect;
1515
use Nette\Schema\Schema;
1616
use stdClass;
@@ -125,10 +125,17 @@ public function beforeCompile(): void
125125
$applicationDef = $builder->getDefinition($this->prefix('application'));
126126

127127
// Setup URL for CLI
128-
if ($config->url !== null && $builder->hasDefinition('http.request')) {
129-
/** @var ServiceDefinition $httpDef */
130-
$httpDef = $builder->getDefinition('http.request');
131-
$httpDef->setFactory(Request::class, [new Statement(UrlScript::class, [$config->url])]);
128+
if ($config->url !== null && $builder->hasDefinition('http.requestFactory')) {
129+
$httpDef = $builder->getDefinition('http.requestFactory');
130+
assert($httpDef instanceof ServiceDefinition);
131+
$factoryEntity = $httpDef->getFactory()->getEntity();
132+
if ($factoryEntity === RequestFactory::class) {
133+
$httpDef->setFactory(ConsoleRequestFactory::class, [$config->url]);
134+
} else {
135+
throw new ServiceCreationException(
136+
'Custom http.requestFactory is used, argument console.url should be removed.'
137+
);
138+
}
132139
}
133140

134141
// Add all commands to map for command loader

src/Http/ConsoleRequestFactory.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Contributte\Console\Http;
4+
5+
use Nette\Http\Request;
6+
use Nette\Http\RequestFactory;
7+
use Nette\Http\UrlScript;
8+
9+
class ConsoleRequestFactory extends RequestFactory
10+
{
11+
12+
private string $url;
13+
14+
public function __construct(string $url)
15+
{
16+
$this->url = $url;
17+
}
18+
19+
public function fromGlobals(): Request
20+
{
21+
return new Request(new UrlScript($this->url));
22+
}
23+
24+
public function createHttpRequest(): Request
25+
{
26+
return $this->fromGlobals();
27+
}
28+
29+
}

tests/cases/DI/ConsoleExtension.phpt

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use Symfony\Component\Console\Command\Command;
1515
use Tester\Assert;
1616
use Tester\FileMock;
1717
use Tests\Fixtures\FooCommand;
18+
use Tests\Fixtures\FooRequestFactory;
1819

1920
require_once __DIR__ . '/../../bootstrap.php';
2021

@@ -52,7 +53,7 @@ Toolkit::test(function (): void {
5253
Assert::type(FooCommand::class, $container->getByType(Command::class));
5354
});
5455

55-
// Provide URL
56+
// Provide URL using default request factory
5657
Toolkit::test(function (): void {
5758
$loader = new ContainerLoader(Environment::getTestDir(), true);
5859
$class = $loader->load(function (Compiler $compiler): void {
@@ -209,3 +210,39 @@ Toolkit::test(function (): void {
209210
$application = $container->getByType(Application::class);
210211
Assert::equal('Hello world', $application->getName());
211212
});
213+
214+
// Use custom request Factory
215+
Toolkit::test(function (): void {
216+
$loader = new ContainerLoader(Environment::getTestDir(), true);
217+
$class = $loader->load(function (Compiler $compiler): void {
218+
$compiler->addExtension('console', new ConsoleExtension(true));
219+
$compiler->addExtension('http', new HttpExtension(true));
220+
$compiler->loadConfig(FileMock::create('
221+
services:
222+
http.requestFactory: Tests\Fixtures\FooRequestFactory
223+
', 'neon'));
224+
}, [getmypid(), 11]);
225+
226+
/** @var Container $container */
227+
$container = new $class();
228+
229+
Assert::equal(FooRequestFactory::CUSTOM_URL, (string) $container->getService('http.request')->getUrl());
230+
});
231+
232+
// Throw error on custom factory and console.url set
233+
Toolkit::test(function (): void {
234+
Assert::exception(function (): void {
235+
$loader = new ContainerLoader(Environment::getTestDir(), true);
236+
$class = $loader->load(function (Compiler $compiler): void {
237+
$compiler->addExtension('console', new ConsoleExtension(true));
238+
$compiler->addExtension('http', new HttpExtension(true));
239+
$compiler->loadConfig(FileMock::create('
240+
services:
241+
http.requestFactory: Tests\Fixtures\FooRequestFactory
242+
console:
243+
url: https://contributte.org/
244+
', 'neon'));
245+
}, [getmypid(), 12]);
246+
new $class();
247+
}, ServiceCreationException::class, 'Custom http.requestFactory is used, argument console.url should be removed.');
248+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Tests\Fixtures;
4+
5+
use Nette\Http\Request;
6+
use Nette\Http\RequestFactory;
7+
use Nette\Http\UrlScript;
8+
9+
class FooRequestFactory extends RequestFactory
10+
{
11+
12+
public const CUSTOM_URL = 'http://custom/';
13+
14+
public function fromGlobals(): Request
15+
{
16+
return new Request(new UrlScript(self::CUSTOM_URL));
17+
}
18+
19+
public function createHttpRequest(): Request
20+
{
21+
return $this->fromGlobals();
22+
}
23+
24+
}

0 commit comments

Comments
 (0)