Skip to content

Commit de61932

Browse files
committed
Make preparations for version 3.
Signed-off-by: Joshua Parker <[email protected]>
1 parent e36c624 commit de61932

File tree

1 file changed

+147
-29
lines changed

1 file changed

+147
-29
lines changed

Application.php

Lines changed: 147 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,54 +6,79 @@
66

77
use Codefy\Framework\Factory\FileLoggerFactory;
88
use Codefy\Framework\Factory\FileLoggerSmtpFactory;
9+
use Codefy\Framework\Pipeline\PipelineBuilder;
10+
use Codefy\Framework\Support\BasePathDetector;
11+
use Codefy\Framework\Support\LocalStorage;
912
use Codefy\Framework\Support\Paths;
13+
use Dotenv\Dotenv;
1014
use Psr\Container\ContainerInterface;
1115
use Psr\Http\Message\ResponseInterface;
1216
use Psr\Http\Message\ServerRequestInterface;
1317
use Psr\Log\LoggerInterface;
1418
use Qubus\Config\ConfigContainer;
1519
use Qubus\Dbal\Connection;
1620
use Qubus\Dbal\DB;
21+
use Qubus\EventDispatcher\ActionFilter\Observer;
22+
use Qubus\EventDispatcher\EventDispatcher;
1723
use Qubus\Exception\Data\TypeException;
1824
use Qubus\Exception\Exception;
1925
use Qubus\Expressive\OrmBuilder;
26+
use Qubus\Http\Cookies\Factory\HttpCookieFactory;
27+
use Qubus\Http\Session\Flash;
28+
use Qubus\Http\Session\PhpSession;
2029
use Qubus\Inheritance\InvokerAware;
2130
use Qubus\Injector\Config\InjectorFactory;
2231
use Qubus\Injector\Psr11\Container;
2332
use Qubus\Injector\ServiceContainer;
2433
use Qubus\Injector\ServiceProvider\BaseServiceProvider;
2534
use Qubus\Injector\ServiceProvider\Bootable;
2635
use Qubus\Injector\ServiceProvider\Serviceable;
36+
use Qubus\Mail\Mailer;
37+
use Qubus\Support\ArrayHelper;
38+
use Qubus\Support\Assets;
39+
use Qubus\Support\StringHelper;
2740
use ReflectionException;
2841

42+
use function dirname;
2943
use function get_class;
3044
use function is_string;
45+
use function Qubus\Config\Helpers\env;
46+
use function Qubus\Support\Helpers\is_null__;
3147
use function rtrim;
3248

3349
use const DIRECTORY_SEPARATOR;
3450

3551
/**
3652
* @property-read ServerRequestInterface $request
3753
* @property-read ResponseInterface $response
38-
* @property-read \Qubus\Support\Assets $assets
39-
* @property-read \Qubus\Mail\Mailer $mailer
40-
* @property-read \Qubus\Http\Session\PhpSession $session
41-
* @property-read \Qubus\Http\Session\Flash $flash
42-
* @property-read \Qubus\EventDispatcher\EventDispatcher $event
43-
* @property-read \Qubus\Http\Cookies\Factory\HttpCookieFactory $httpCookie
44-
* @property-read Support\LocalStorage $localStorage
45-
* @property-read \Qubus\Config\ConfigContainer $configContainer
54+
* @property-read Assets $assets
55+
* @property-read Mailer $mailer
56+
* @property-read PhpSession $session
57+
* @property-read Flash $flash
58+
* @property-read EventDispatcher $event
59+
* @property-read HttpCookieFactory $httpCookie
60+
* @property-read LocalStorage $localStorage
61+
* @property-read ConfigContainer $configContainer
62+
* @property-read PipelineBuilder $pipeline
63+
* @property-read Observer $hook
64+
* @property-read StringHelper $string
65+
* @property-read ArrayHelper $array
4666
*/
4767
final class Application extends Container
4868
{
4969
use InvokerAware;
5070

51-
public const APP_VERSION = '2.0.9';
71+
public const APP_VERSION = '2.1.0';
5272

5373
public const MIN_PHP_VERSION = '8.2';
5474

5575
public const DS = DIRECTORY_SEPARATOR;
5676

77+
/**
78+
* The current globally available Application (if any).
79+
*
80+
* @var ?self
81+
*/
5782
public static ?Application $APP = null;
5883

5984
public string $charset = 'UTF-8';
@@ -62,9 +87,9 @@ final class Application extends Container
6287

6388
public string $controllerNamespace = 'App\\Infrastructure\\Http\\Controllers';
6489

65-
public static string $ROOT_PATH;
90+
public static string $ROOT_PATH = '';
6691

67-
protected ?string $basePath = null;
92+
protected string $basePath = '';
6893

6994
protected ?string $appPath = null;
7095

@@ -93,35 +118,66 @@ public function __construct(array $params)
93118
$this->withBasePath(basePath: $params['basePath']);
94119
}
95120

96-
self::$APP = $this;
97-
self::$ROOT_PATH = $this->basePath;
98-
99121
parent::__construct(InjectorFactory::create(config: $this->coreAliases()));
122+
$this->registerBaseBindings();
100123
$this->registerDefaultServiceProviders();
124+
$this->registerPropertyBindings();
125+
}
101126

102-
$this->init();
127+
private function registerBaseBindings(): void
128+
{
129+
self::$APP = $this;
130+
self::$ROOT_PATH = $this->basePath;
131+
$this->alias(original: 'app', alias: self::class);
103132
}
104133

105-
private function init(): void
134+
/**
135+
* Dynamically created properties.
136+
*
137+
* @return void
138+
* @throws TypeException
139+
*/
140+
private function registerPropertyBindings(): void
106141
{
107142
$contracts = [
108143
'request' => ServerRequestInterface::class,
109144
'response' => ResponseInterface::class,
110-
'assets' => \Qubus\Support\Assets::class,
111-
'mailer' => \Qubus\Mail\Mailer::class,
112-
'session' => \Qubus\Http\Session\PhpSession::class,
113-
'flash' => \Qubus\Http\Session\Flash::class,
114-
'event' => \Qubus\EventDispatcher\EventDispatcher::class,
115-
'httpCookie' => \Qubus\Http\Cookies\Factory\HttpCookieFactory::class,
145+
'assets' => Assets::class,
146+
'mailer' => Mailer::class,
147+
'session' => PhpSession::class,
148+
'flash' => Flash::class,
149+
'event' => EventDispatcher::class,
150+
'httpCookie' => HttpCookieFactory::class,
116151
'localStorage' => Support\LocalStorage::class,
117-
'configContainer' => \Qubus\Config\ConfigContainer::class,
152+
'configContainer' => ConfigContainer::class,
153+
'pipeline' => PipelineBuilder::class,
154+
'hook' => Observer::class,
155+
'string' => StringHelper::class,
156+
'array' => ArrayHelper::class,
118157
];
119158

120159
foreach ($contracts as $property => $name) {
121160
$this->{$property} = $this->make(name: $name);
122161
}
123162

124-
Codefy::$PHP = $this;
163+
Codefy::$PHP = $this::getInstance();
164+
}
165+
166+
/**
167+
* Infer the application's base directory
168+
* from the environment and server.
169+
*
170+
* @return string|null
171+
*/
172+
protected static function inferBasePath(): ?string
173+
{
174+
$basePath = (new BasePathDetector())->getBasePath();
175+
176+
return match (true) {
177+
(env('APP_BASE_PATH') !== null && env('APP_BASE_PATH') !== false) => env('APP_BASE_PATH'),
178+
$basePath !== '' => $basePath,
179+
default => dirname(path: __FILE__, levels: 2),
180+
};
125181
}
126182

127183
/**
@@ -138,6 +194,7 @@ public static function getLogger(): LoggerInterface
138194
* FileLogger with SMTP support.
139195
*
140196
* @throws ReflectionException
197+
* @throws TypeException
141198
*/
142199
public static function getSmtpLogger(): LoggerInterface
143200
{
@@ -213,8 +270,10 @@ public function singleton(string $key, callable $value): void
213270
*/
214271
protected function registerDefaultServiceProviders(): void
215272
{
216-
foreach ([
273+
foreach (
274+
[
217275
Providers\ConfigServiceProvider::class,
276+
Providers\PdoServiceProvider::class,
218277
Providers\FlysystemServiceProvider::class,
219278
] as $serviceProvider
220279
) {
@@ -228,11 +287,11 @@ public function bootstrapWith(array $bootstrappers): void
228287
$this->hasBeenBootstrapped = true;
229288

230289
foreach ($bootstrappers as $bootstrapper) {
231-
$this->make(name: \Qubus\EventDispatcher\EventDispatcher::class)->dispatch("bootstrapping.{$bootstrapper}");
290+
$this->make(name: EventDispatcher::class)->dispatch("bootstrapping.{$bootstrapper}");
232291

233292
$this->make(name: $bootstrapper)->bootstrap($this);
234293

235-
$this->make(name: \Qubus\EventDispatcher\EventDispatcher::class)->dispatch("bootstrapped.{$bootstrapper}");
294+
$this->make(name: EventDispatcher::class)->dispatch("bootstrapped.{$bootstrapper}");
236295
}
237296
}
238297

@@ -668,7 +727,7 @@ public function getBaseMiddlewares(): array
668727

669728
public function isRunningInConsole(): bool
670729
{
671-
return php_sapi_name() === 'cli' || php_sapi_name() == 'phpdbg';
730+
return in_array(php_sapi_name(), ['cli', 'phpdbg']);
672731
}
673732

674733
/**
@@ -709,7 +768,7 @@ protected function coreAliases(): array
709768
\Qubus\Config\ConfigContainer::class => \Qubus\Config\Collection::class,
710769
\Qubus\EventDispatcher\EventDispatcher::class => \Qubus\EventDispatcher\Dispatcher::class,
711770
\Qubus\Mail\Mailer::class => \Codefy\Framework\Support\CodefyMailer::class,
712-
'mailer' => \Qubus\Mail\Mailer::class,
771+
'mailer' => Mailer::class,
713772
'dir.path' => \Codefy\Framework\Support\Paths::class,
714773
'container' => self::class,
715774
'codefy' => self::class,
@@ -738,6 +797,21 @@ protected function coreAliases(): array
738797
];
739798
}
740799

800+
/**
801+
* Load environment file(s).
802+
*
803+
* @return void
804+
*/
805+
private function loadEnvironment(): void
806+
{
807+
$dotenv = Dotenv::createImmutable(
808+
paths: $this->basePath(),
809+
names: ['.env','.env.local','.env.staging','.env.development','.env.production'],
810+
shortCircuit: false
811+
);
812+
$dotenv->safeLoad();
813+
}
814+
741815
public function __get(mixed $name)
742816
{
743817
return $this->param[$name];
@@ -765,4 +839,48 @@ public function __destruct()
765839
$this->serviceProvidersRegistered = [];
766840
$this->baseMiddlewares = [];
767841
}
842+
843+
/**
844+
* Determine if the application is in production.
845+
*
846+
* @return bool
847+
*/
848+
public function isProduction(): bool
849+
{
850+
return env(key: 'APP_ENV') === 'production';
851+
}
852+
853+
/**
854+
* Determine if the application is in development.
855+
*
856+
* @return bool
857+
*/
858+
public function isDevelopment(): bool
859+
{
860+
return env(key: 'APP_ENV') === 'development';
861+
}
862+
863+
/**
864+
* Get the globally available instance of the container.
865+
*
866+
* @return static
867+
* @throws TypeException
868+
*/
869+
public static function getInstance(?string $path = null): self
870+
{
871+
$basePath = match (true) {
872+
is_string($path) && $path !== '' => $path,
873+
default => self::inferBasePath(),
874+
};
875+
876+
if (is_null__(self::$APP)) {
877+
self::$APP = new self(
878+
params: [
879+
'basePath' => $basePath,
880+
]
881+
);
882+
}
883+
884+
return self::$APP;
885+
}
768886
}

0 commit comments

Comments
 (0)