/
Application.php
142 lines (119 loc) · 3.72 KB
/
Application.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
namespace Flow;
use DI\ContainerBuilder;
use DI\Container;
use Psr\Container\ContainerInterface;
use Northwoods\Broker\Broker;
use FastRoute\RouteCollector;
use FastRoute\Dispatcher\GroupCountBased as RouteDispatcher;
use FastRoute\RouteParser\Std as StdRouteParser;
use FastRoute\DataGenerator\GroupCountBased as GroupCountBasedGenerator;
use Symfony\Component\Console\Application as Console;
use Flow\Console\CommandLoader\LazyCommandLoader;
use Flow\Middleware\RouterMiddleware;
use Flow\Emitter\HttpEmitter;
use Nyholm\Psr7\Factory\Psr17Factory as HttpFactory;
use Nyholm\Psr7Server\ServerRequestCreatorInterface;
use Nyholm\Psr7Server\ServerRequestCreator;
/**
* Main application class.
*
* @author Sebastian Pająk <spconv@gmail.com>
*/
final class Application
{
private $bootstrapped;
private $broker;
private $routeCollector;
private $console;
private $commandLoader;
private $httpFactory;
private $containerBuilder;
private $container;
public function __construct()
{
// Broker (Handler & Middleware)
$this->broker = new Broker;
// Route Collector
$this->routeCollector = new RouteCollector(
new StdRouteParser,
new GroupCountBasedGenerator
);
// Console
$this->console = new Console;
$this->commandLoader = new LazyCommandLoader;
$this->console->setCommandLoader($this->commandLoader);
// Psr7 Factories
$this->httpFactory = new HttpFactory;
// DI Container
$this->containerBuilder = new ContainerBuilder;
$this->containerBuilder->useAutowiring(false);
$this->containerBuilder->useAttributes(false);
$this->containerBuilder->addDefinitions([
'console' => function() { return $this->console; },
'http_factory' => function() { return $this->httpFactory; }
]);
}
public function getContainerBuilder(): ContainerBuilder
{
return $this->containerBuilder;
}
public function getBroker(): Broker
{
return $this->broker;
}
public function getRouteCollector(): RouteCollector
{
return $this->routeCollector;
}
public function getConsole(): Console
{
return $this->console;
}
public function getCommandLoader(): LazyCommandLoader
{
return $this->commandLoader;
}
public function getHttpFactory(): HttpFactory
{
return $this->httpFactory;
}
public function getContainer(): ContainerInterface
{
if (!isset($this->container)) {
return new Container;
}
return $this->container;
}
public function getServerRequestCreator(): ServerRequestCreatorInterface
{
return new ServerRequestCreator(
$this->httpFactory, // ServerRequestFactory
$this->httpFactory, // UriFactory
$this->httpFactory, // UploadedFileFactory
$this->httpFactory // StreamFactory
);
}
public function run(): void
{
$this->bootstrap();
if (php_sapi_name() === 'cli') {
$this->console->run();
} else {
$request = $this->getServerRequestCreator()->fromGlobals();
$response = $this->broker->handle($request);
(new HttpEmitter)->emit($response);
}
}
private function bootstrap(): void
{
if ($this->bootstrapped) {
return;
}
$this->container = $this->containerBuilder->build();
$dispatcher = new RouteDispatcher($this->routeCollector->getData());
$router = new RouterMiddleware($dispatcher, $this->httpFactory);
$this->broker->append($router);
$this->bootstrapped = true;
}
}