Skip to content

Commit f90c209

Browse files
authored
Merge pull request #394 from koriym/import-app-module
ImportAppModule
2 parents afda62f + fd05fa8 commit f90c209

File tree

12 files changed

+230
-9
lines changed

12 files changed

+230
-9
lines changed

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@
5656
],
5757
"FakeVendor\\HelloWorld\\": [
5858
"tests/Fake/fake-app/src/"
59+
],
60+
"Import\\HelloWorld\\": [
61+
"tests/Fake/import-app/src"
5962
]
6063
},
6164
"files": [

phpstan.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ parameters:
33
paths:
44
- src
55
- tests
6-
excludes_analyse:
6+
excludePaths:
77
- tests/hash.php
88
- tests/tmp/*
99
- tests/Fake/*

src/Compiler/FilePutContents.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class FilePutContents
1616
*
1717
* @var ArrayObject<int, string>
1818
*/
19-
private ArrayObject $overwritten;
19+
private ArrayObject $overwritten; // @phpstan-ignore-line
2020

2121
/**
2222
* @param ArrayObject<int, string> $overwritten

src/Module/Import/ImportApp.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace BEAR\Package\Module\Import;
6+
7+
use ReflectionClass;
8+
9+
use function assert;
10+
use function dirname;
11+
use function is_dir;
12+
use function sprintf;
13+
14+
final class ImportApp
15+
{
16+
public string $host;
17+
public string $appName;
18+
public string $context;
19+
public string $appDir;
20+
21+
public function __construct(string $host, string $appName, string $context)
22+
{
23+
$this->host = $host;
24+
$this->appName = $appName;
25+
$this->context = $context;
26+
/** @var class-string $appModuleClass */
27+
$appModuleClass = sprintf('%s\\Module\\AppModule', $this->appName);
28+
$appModuleClassName = (string) (new ReflectionClass($appModuleClass))->getFileName();
29+
$appDir = dirname($appModuleClassName, 3);
30+
assert(is_dir($appDir));
31+
$this->appDir = $appDir;
32+
}
33+
}

src/Module/ImportAppModule.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace BEAR\Package\Module;
6+
7+
use BEAR\Package\Module\Import\ImportApp;
8+
use BEAR\Resource\Annotation\ImportAppConfig;
9+
use BEAR\Resource\Module\SchemeCollectionProvider;
10+
use BEAR\Resource\SchemeCollectionInterface;
11+
use Ray\Di\AbstractModule;
12+
use Ray\Di\Exception\NotFound;
13+
14+
final class ImportAppModule extends AbstractModule
15+
{
16+
/**
17+
* Import scheme config
18+
*
19+
* @var array<ImportApp>
20+
*/
21+
private array $importApps = [];
22+
23+
/**
24+
* @param array<ImportApp> $importApps
25+
*/
26+
public function __construct(array $importApps)
27+
{
28+
foreach ($importApps as $importApp) {
29+
// create import config
30+
$this->importApps[] = $importApp;
31+
}
32+
33+
parent::__construct();
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*
39+
* @throws NotFound
40+
*/
41+
protected function configure(): void
42+
{
43+
$this->bind()->annotatedWith(ImportAppConfig::class)->toInstance($this->importApps);
44+
$this->bind(SchemeCollectionInterface::class)->annotatedWith('original')->toProvider(SchemeCollectionProvider::class);
45+
$this->bind(SchemeCollectionInterface::class)->toProvider(ImportSchemeCollectionProvider::class);
46+
}
47+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace BEAR\Package\Module;
6+
7+
use BEAR\Package\Injector;
8+
use BEAR\Package\Module\Import\ImportApp;
9+
use BEAR\Resource\AppAdapter;
10+
use BEAR\Resource\SchemeCollectionInterface;
11+
use Ray\Di\Di\Named;
12+
use Ray\Di\ProviderInterface;
13+
14+
final class ImportSchemeCollectionProvider implements ProviderInterface
15+
{
16+
/** @var ImportApp[] */
17+
private array $importAppConfig;
18+
private SchemeCollectionInterface $schemeCollection;
19+
20+
/**
21+
* @param ImportApp[] $importAppConfig
22+
*
23+
* @Named("importAppConfig=BEAR\Resource\Annotation\ImportAppConfig,schemeCollection=original")
24+
*/
25+
#[Named('importAppConfig=BEAR\Resource\Annotation\ImportAppConfig,schemeCollection=original')]
26+
public function __construct(array $importAppConfig, SchemeCollectionInterface $schemeCollection)
27+
{
28+
$this->importAppConfig = $importAppConfig;
29+
$this->schemeCollection = $schemeCollection;
30+
}
31+
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
public function get(): SchemeCollectionInterface
36+
{
37+
foreach ($this->importAppConfig as $app) {
38+
$injector = Injector::getInstance($app->appName, $app->context, $app->appDir);
39+
$adapter = new AppAdapter($injector, $app->appName);
40+
$this->schemeCollection
41+
->scheme('page')->host($app->host)->toAdapter($adapter)
42+
->scheme('app')->host($app->host)->toAdapter($adapter);
43+
}
44+
45+
return $this->schemeCollection;
46+
}
47+
}

tests/Fake/fake-app/src/Resource/Page/Index.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
class Index extends ResourceObject
1010
{
11+
/** @var array{greeting: string} */
12+
public $body;
1113
public function onGet($name = 'BEAR.Sunday')
1214
{
1315
$this->body = [
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Import\HelloWorld\Module;
6+
7+
use BEAR\Sunday\Extension\Application\AppInterface;
8+
9+
class App implements AppInterface
10+
{
11+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Import\HelloWorld\Module;
6+
7+
use BEAR\Resource\Annotation\AppName;
8+
use BEAR\Sunday\Extension\Application\AppInterface;
9+
use BEAR\Sunday\Module\SundayModule;
10+
use Ray\Compiler\Annotation\Compile;
11+
use Ray\Di\AbstractModule;
12+
13+
class AppModule extends AbstractModule
14+
{
15+
protected function configure(): void
16+
{
17+
$this->bind(AppInterface::class)->to(App::class);
18+
$this->bind()->annotatedWith(Compile::class)->toInstance(true);
19+
$this->install(new SundayModule());
20+
}
21+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Import\HelloWorld\Resource\Page;
6+
7+
use BEAR\Resource\ResourceObject;
8+
9+
class Index extends ResourceObject
10+
{
11+
/** @var array{greeting: string} */
12+
public $body;
13+
14+
/** @return static */
15+
public function onGet(string $name = 'World'): ResourceObject
16+
{
17+
$this->body = [
18+
'greeting' => 'Konichiwa ' . $name,
19+
];
20+
21+
return $this;
22+
}
23+
}

tests/Module/ImportAppModuleTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace BEAR\Package\Module;
6+
7+
use BEAR\Package\Module\Import\ImportApp;
8+
use BEAR\Resource\Module\ResourceModule;
9+
use BEAR\Resource\ResourceInterface;
10+
use FakeVendor\HelloWorld\Resource\Page\Index;
11+
use Import\HelloWorld\Resource\Page\Index as ImportIndex;
12+
use PHPUnit\Framework\TestCase;
13+
use Ray\Di\Injector;
14+
15+
use function assert;
16+
17+
class ImportAppModuleTest extends TestCase
18+
{
19+
public function testModule(): void
20+
{
21+
$module = new ResourceModule('FakeVendor\HelloWorld');
22+
$module->override(new ImportAppModule([new ImportApp('foo', 'Import\HelloWorld', 'app')]));
23+
$injector = new Injector($module);
24+
$resource = $injector->getInstance(ResourceInterface::class);
25+
assert($resource instanceof ResourceInterface);
26+
$ro = $resource->get('page://self/index', ['name' => 'BEAR']);
27+
assert($ro instanceof Index);
28+
$this->assertSame('Hello BEAR', $ro->body['greeting']);
29+
// import
30+
$ro = $resource->get('page://foo/index', ['name' => 'Sunday']);
31+
assert($ro instanceof ImportIndex);
32+
$this->assertSame('Konichiwa Sunday', $ro->body['greeting']);
33+
}
34+
}

vendor-bin/tools/composer.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)