4
4
5
5
use Closure ;
6
6
use Exception ;
7
+ use FF \container \PHPDIContainer ;
7
8
use FF \exceptions \MethodAlreadyRegistered ;
8
9
use FF \exceptions \UnavailableRequestException ;
9
10
use FF \http \Request ;
10
11
use FF \http \Response ;
11
12
use FF \logger \MonologLogger ;
12
13
use FF \router \Router ;
13
14
use FF \router \RouterInterface ;
15
+ use FF \view \TemplateEngine ;
16
+ use FF \view \View ;
17
+ use Monolog \Logger ;
14
18
use Psr \Container \ContainerExceptionInterface ;
15
19
use Psr \Container \ContainerInterface ;
16
20
use Psr \Container \NotFoundExceptionInterface ;
@@ -22,23 +26,65 @@ class Application extends BaseApplication
22
26
public RouterInterface $ router ;
23
27
public LoggerInterface $ logger ;
24
28
25
- private Request $ request ;
29
+ /** @var bool is application running correctly */
26
30
private bool $ status = true ;
27
31
28
32
/**
29
33
* @param ContainerInterface $container
34
+ * @param RouterInterface $router
35
+ * @param LoggerInterface $logger
30
36
* @param array $config
31
- * @throws ContainerExceptionInterface
32
- * @throws NotFoundExceptionInterface
33
37
*/
34
- public function __construct (ContainerInterface $ container , array $ config = [])
38
+ public function __construct (
39
+ ContainerInterface $ container ,
40
+ RouterInterface $ router ,
41
+ LoggerInterface $ logger ,
42
+ array $ config = []
43
+ )
35
44
{
36
45
parent ::__construct ($ container , $ config );
37
46
38
- $ this ->router = $ this ->container ->get (Router::class);
47
+ $ this ->logger = $ logger ;
48
+
49
+ $ this ->router = $ router ;
39
50
$ this ->router ->setConfig ($ config );
40
- $ this ->request = $ this ->container ->get (Request::class);
41
- $ this ->logger = $ this ->container ->get (MonologLogger::class);
51
+ }
52
+
53
+ /**
54
+ * Hide construction from client code
55
+ *
56
+ * @param array $config
57
+ * @return static
58
+ * @throws Exception
59
+ */
60
+ public static function construct (array $ config ): static
61
+ {
62
+ $ definitions = [
63
+ LoggerInterface::class => function () use ($ config ) {
64
+ return new MonologLogger (new Logger ($ config ['appName ' ] ?? 'ff-core-app ' ));
65
+ },
66
+ RouterInterface::class => function () {
67
+ return new Router ();
68
+ },
69
+ ];
70
+
71
+ if (isset ($ config ['viewPath ' ])) {
72
+ $ definitions [View::class] = function () use ($ config ) {
73
+ return new View (new TemplateEngine ($ config ['viewPath ' ]));
74
+ };
75
+ }
76
+
77
+ if (isset ($ config ['definitions ' ]) && is_array ($ config ['definitions ' ])) {
78
+ $ definitions = array_merge ($ definitions , $ config ['definitions ' ]);
79
+ }
80
+
81
+ $ container = new PHPDIContainer ($ definitions );
82
+ return new static (
83
+ $ container ,
84
+ $ container ->get (RouterInterface::class),
85
+ $ container ->get (LoggerInterface::class),
86
+ $ config
87
+ );
42
88
}
43
89
44
90
/**
@@ -48,55 +94,43 @@ public function __construct(ContainerInterface $container, array $config = [])
48
94
*/
49
95
public function run (): int
50
96
{
51
- try {
52
- $ response = new Response ();
97
+ $ request = $ this -> createRequest ();
98
+ $ response = $ this -> createResponse ();
53
99
54
- [$ controllerName , $ action , $ handler ] = $ this ->router ->parseRequest ($ this ->request );
100
+ try {
101
+ [$ controllerName , $ action , $ handler ] = $ this ->router ->parseRequest ($ request );
55
102
56
103
try {
57
104
if ($ handler !== null ) {
58
- $ handler ($ this -> request , $ response );
105
+ $ handler ($ request , $ response );
59
106
} elseif ($ controllerName !== null && $ action !== null ) {
60
107
$ controller = $ this ->container ->get ($ controllerName );
61
108
$ controller ->setRouter ($ this ->router );
62
109
63
- $ controller ->$ action ($ this -> request , $ response );
110
+ $ controller ->$ action ($ request , $ response );
64
111
} else {
65
112
throw new Exception ("No handlers for request found " );
66
113
}
67
114
} catch (Throwable $ e ) {
68
- $ this ->logger ->error ($ e ->getMessage (), $ this -> getContext ());
115
+ $ this ->logger ->error ($ e ->getMessage (), $ request -> context ());
69
116
$ response ->setBody ($ e ->getMessage ());
70
117
$ this ->status = false ;
71
118
}
72
119
73
- try {
74
- // TODO: add response headers and code
75
- echo $ response ;
76
- } catch (\Throwable $ e ) {
77
- $ this ->status = false ;
78
- $ this ->logger ->error ($ e ->getMessage (), $ this ->getContext ());
79
- }
120
+ $ response ->send ();
80
121
81
122
return $ this ->status ? ExitCode::SUCCESS : ExitCode::ERROR ;
82
123
} catch (UnavailableRequestException $ e ) {
83
- $ this ->logger ->error ('Not available request ' , $ this -> getContext ());
124
+ $ this ->logger ->error ('Not available request ' , $ request -> context ());
84
125
$ this ->showErrorPage ($ e , '404 Page not found ' );
85
126
} catch (Exception $ e ) {
86
- $ this ->logger ->error ($ e ->getMessage (), $ this -> getContext ());
127
+ $ this ->logger ->error ($ e ->getMessage (), $ request -> context ());
87
128
$ this ->showErrorPage ($ e );
88
129
}
89
130
90
131
return ExitCode::ERROR ;
91
132
}
92
133
93
- private function getContext (): array
94
- {
95
- return [
96
- 'request ' => $ this ->request ->server ('REQUEST_URI ' ),
97
- 'ip ' => $ this ->request ->server ('REMOTE_ADDR ' )
98
- ];
99
- }
100
134
101
135
/**
102
136
* @param Exception $e
@@ -130,4 +164,20 @@ public function post(string $path, Closure $handler): void
130
164
{
131
165
$ this ->router ->post ($ path , $ handler );
132
166
}
167
+
168
+ /**
169
+ * @return Request
170
+ */
171
+ private function createRequest (): Request
172
+ {
173
+ return new Request ();
174
+ }
175
+
176
+ /**
177
+ * @return Response
178
+ */
179
+ private function createResponse (): Response
180
+ {
181
+ return new Response ;
182
+ }
133
183
}
0 commit comments