Skip to content

Commit 486811c

Browse files
committed
feat: add service provider and configs glob load
1 parent 46605d5 commit 486811c

File tree

5 files changed

+248
-106
lines changed

5 files changed

+248
-106
lines changed

src/AbstractKernel.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace MaplePHP\Core;
66

77
use MaplePHP\Core\Configs\LoadConfigFiles;
8+
use MaplePHP\Core\Support\ServiceProvider;
89
use MaplePHP\Emitron\Contracts\KernelInterface;
910
use MaplePHP\Http\Stream;
1011
use Psr\Container\ContainerInterface;
@@ -37,9 +38,10 @@ public function __construct(string $dir)
3738
$config = (new LoadConfigFiles())
3839
->add("dir", $this->dir)
3940
->loadEnvFile($this->dir . "/.env")
40-
->loadFile($this->dir . "/configs/configs.php");
41+
->loadFiles($this->dir . "/configs/");
4142

4243
$this->config = $config->fetch();
44+
4345
$app = App::boot(new Dir($this->dir), $this->config);
4446
$this->container = new Container();
4547
$this->container->set("config", $this->config);
@@ -56,9 +58,40 @@ public function __construct(string $dir)
5658
*/
5759
protected function load(ServerRequestInterface $request, ?DispatchConfigInterface $config = null): KernelInterface
5860
{
61+
62+
$this->bootServiceProviders();
5963
return new Kernel($this->container, $this->middlewares, $config);
6064
}
6165

66+
/**
67+
* Boot servcice providers
68+
*
69+
* @return void
70+
*/
71+
protected function bootServiceProviders()
72+
{
73+
if(isset($this->config['providers'])) {
74+
$providers = [];
75+
76+
// We want to register first, that way the providers could talk to eachother
77+
// through the container or event listners if you want.
78+
foreach ($this->config['providers'] as $providerClass) {
79+
$provider = new $providerClass();
80+
if(!($provider instanceof ServiceProvider)) {
81+
throw new \RuntimeException(
82+
"$providerClass is not an instance of " . ServiceProvider::class . "!"
83+
);
84+
}
85+
$provider->register($this->container);
86+
$providers[] = $provider;
87+
}
88+
89+
foreach ($providers as $provider) {
90+
$provider->boot();
91+
}
92+
}
93+
}
94+
6295
/**
6396
* @param Stream $stream
6497
* @return $this

src/Configs/LoadConfigFiles.php

Lines changed: 134 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -9,109 +9,138 @@
99

1010
class LoadConfigFiles
1111
{
12-
private array $data = [];
13-
14-
/**
15-
* Check if config parameter exists
16-
*
17-
* @param string $key
18-
* @return bool
19-
*/
20-
public function has(string $key): bool
21-
{
22-
return isset($this->data[$key]);
23-
}
24-
25-
/**
26-
* Add one config parameter
27-
*
28-
* @param string $key
29-
* @param mixed $value
30-
* @return $this
31-
*/
32-
public function add(string $key, mixed $value): self
33-
{
34-
if($this->has($key)) {
35-
throw new \InvalidArgumentException('Config parameter "' . $key . '" already exists.');
36-
}
37-
$inst = clone $this;
38-
$inst->data[$key] = $value;
39-
return $inst;
40-
}
41-
42-
/**
43-
* Immutable load config from PHP file
44-
*
45-
* @param string $filePath
46-
* @return $this
47-
* @throws Exception
48-
*/
49-
public function loadFile(string $filePath): self
50-
{
51-
if (!$this->hasExt($filePath, "php")) {
52-
throw new \InvalidArgumentException("The file '$filePath' is not a valid PHP file extension");
53-
}
54-
55-
$inst = clone $this;
56-
$inst->data = array_merge($inst->data, $this->loadConfigFile($filePath));
57-
return $inst;
58-
}
59-
60-
/**
61-
* Immutable load config from env file
62-
*
63-
* @param string $filePath
64-
* @return $this
65-
*/
66-
public function loadEnvFile(string $filePath): self
67-
{
68-
if (!$this->hasExt($filePath, "env")) {
69-
throw new \InvalidArgumentException("The file '$filePath' is not a valid env file extension");
70-
}
71-
72-
$inst = clone $this;
73-
$env = new Env($filePath);
74-
$env->execute();
75-
//$inst->data = array_merge($inst->data, $env->getData());
76-
return $inst;
77-
}
78-
79-
/**
80-
* Creates a configuration with cache
81-
*
82-
* @return array
83-
*/
84-
public function fetch(): array
85-
{
86-
return $this->data;
87-
}
88-
89-
private function hasExt(string $filePath, string $extension): bool
90-
{
91-
$ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
92-
return $ext === strtolower($extension);
93-
}
94-
95-
/**
96-
* Load a config file that returns a array
97-
*
98-
* @param string $path
99-
* @return array
100-
* @throws Exception
101-
*/
102-
protected function loadConfigFile(string $path): array
103-
{
104-
$path = realpath($path);
105-
106-
if ($path === false) {
107-
throw new Exception('The config file does not exist');
108-
}
109-
110-
$config = require $path;
111-
// Add JSON logic here in the future
112-
if (!is_array($config)) {
113-
throw new Exception('The config file do not return a array');
114-
}
115-
return $config;
116-
}
12+
private array $data = [];
13+
14+
/**
15+
* Check if config parameter exists
16+
*
17+
* @param string $key
18+
* @return bool
19+
*/
20+
public function has(string $key): bool
21+
{
22+
return isset($this->data[$key]);
23+
}
24+
25+
/**
26+
* Add one config parameter
27+
*
28+
* @param string $key
29+
* @param mixed $value
30+
* @return $this
31+
*/
32+
public function add(string $key, mixed $value): self
33+
{
34+
if ($this->has($key)) {
35+
throw new \InvalidArgumentException('Config parameter "' . $key . '" already exists.');
36+
}
37+
$inst = clone $this;
38+
$inst->data[$key] = $value;
39+
return $inst;
40+
}
41+
42+
/**
43+
* Immutable load config from PHP file
44+
*
45+
* @param string $filePath
46+
* @param bool $failSilently
47+
* @return $this
48+
* @throws Exception
49+
*/
50+
public function loadFile(string $filePath, bool $failSilently = false): self
51+
{
52+
if (!$this->hasExt($filePath, "php")) {
53+
throw new \InvalidArgumentException("The file '$filePath' is not a valid PHP file extension");
54+
}
55+
$inst = clone $this;
56+
$name = pathinfo($filePath, PATHINFO_FILENAME);
57+
$data[$name] = $inst->loadConfigFile($filePath, $failSilently);
58+
if ($data[$name] !== []) {
59+
$inst->data = array_merge($inst->data, $data);
60+
}
61+
return $inst;
62+
}
63+
64+
/**
65+
* Load all config files in directory
66+
*
67+
* @param string $path
68+
* @return $this
69+
* @throws Exception
70+
*/
71+
public function loadFiles(string $path): self
72+
{
73+
if (!is_dir($path)) {
74+
throw new \InvalidArgumentException("The dir '$path' does not exists.");
75+
}
76+
77+
$inst = clone $this;
78+
$arr = glob($path . "*.php");
79+
foreach ($arr as $file) {
80+
$inst = $inst->loadFile($file, true);
81+
}
82+
return $inst;
83+
}
84+
85+
/**
86+
* Immutable load config from env file
87+
*
88+
* @param string $filePath
89+
* @return $this
90+
*/
91+
public function loadEnvFile(string $filePath): self
92+
{
93+
if (!$this->hasExt($filePath, "env")) {
94+
throw new \InvalidArgumentException("The file '$filePath' is not a valid env file extension");
95+
}
96+
97+
$inst = clone $this;
98+
$env = new Env($filePath);
99+
$env->execute();
100+
//$inst->data = array_merge($inst->data, $env->getData());
101+
return $inst;
102+
}
103+
104+
/**
105+
* Creates a configuration with cache
106+
*
107+
* @return array
108+
*/
109+
public function fetch(): array
110+
{
111+
return $this->data;
112+
}
113+
114+
private function hasExt(string $filePath, string $extension): bool
115+
{
116+
$ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
117+
return $ext === strtolower($extension);
118+
}
119+
120+
/**
121+
* Load a config file that returns a array
122+
*
123+
* @param string $path
124+
* @param bool $failSilently
125+
* @return array
126+
* @throws Exception
127+
*/
128+
protected function loadConfigFile(string $path, bool $failSilently = false): array
129+
{
130+
$path = realpath($path);
131+
132+
if ($path === false) {
133+
throw new Exception('The config file does not exist');
134+
}
135+
136+
$config = require $path;
137+
// Add JSON logic here in the future
138+
if (!is_array($config)) {
139+
if ($failSilently) {
140+
return [];
141+
}
142+
throw new Exception('The config file do not return a array');
143+
}
144+
return $config;
145+
}
117146
}

src/Middlewares/TestMiddleware.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MaplePHP\Core\Middlewares;
6+
7+
use MaplePHP\Container\Autowire;
8+
use MaplePHP\Core\Exceptions\HttpException;
9+
use MaplePHP\Core\Interfaces\ErrorPageInterface;
10+
use MaplePHP\Core\Render\Errors\SimpleErrorPage;
11+
use MaplePHP\Http\ResponseFactory;
12+
use MaplePHP\Http\StreamFactory;
13+
use MaplePHP\Validate\Inp;
14+
use Psr\Container\ContainerInterface;
15+
use Psr\Http\Server\MiddlewareInterface;
16+
use Psr\Http\Server\RequestHandlerInterface;
17+
use Psr\Http\Message\ResponseInterface;
18+
use Psr\Http\Message\ServerRequestInterface;
19+
20+
class TestMiddleware implements MiddlewareInterface
21+
{
22+
23+
private ContainerInterface $container;
24+
25+
public function __construct(ContainerInterface $container)
26+
{
27+
$this->container = $container;
28+
}
29+
30+
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
31+
{
32+
$this->container->set("TestMiddleware", "Hello World!");
33+
return $handler->handle($request);
34+
}
35+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MaplePHP\Core\Providers;
6+
7+
use MaplePHP\Core\Support\ServiceProvider;
8+
use Psr\Container\ContainerInterface;
9+
10+
class TestServiceProvider extends ServiceProvider
11+
{
12+
/**
13+
* Just a test service provider
14+
*
15+
* @param ContainerInterface $container
16+
* @return void
17+
*/
18+
public function register(ContainerInterface $container): void
19+
{
20+
$container->set("TestServiceProvider", "Hello World!");
21+
}
22+
}

src/Support/ServiceProvider.php

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 MaplePHP\Core\Support;
6+
7+
use Psr\Container\ContainerInterface;
8+
9+
abstract class ServiceProvider
10+
{
11+
12+
/**
13+
*
14+
* @param ContainerInterface $container
15+
* @return void
16+
*/
17+
abstract public function register(ContainerInterface $container): void;
18+
19+
public function boot(): void
20+
{
21+
22+
}
23+
}

0 commit comments

Comments
 (0)