feat(core): add config loader and request context
This commit is contained in:
1 parent
787e5fa3e2
commit
bcd3572890
3 files changed
+157
No files matched your search
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Bazaar\Core;
|
||||
|
||||
final class Config
|
||||
{
|
||||
private static array $values = [];
|
||||
private static bool $loaded = false;
|
||||
|
||||
public static function load(string $envFile): void
|
||||
{
|
||||
self::$loaded = true;
|
||||
if (!is_file($envFile)) {
|
||||
self::hydrateDefaults();
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
|
||||
$line = trim($line);
|
||||
if ($line === '' || $line[0] === '#') {
|
||||
continue;
|
||||
}
|
||||
[$name, $value] = array_pad(explode('=', $line, 2), 2, '');
|
||||
$name = trim($name);
|
||||
$value = trim($value);
|
||||
if (strlen($value) >= 2 && ($value[0] === '"' || $value[0] === "'")) {
|
||||
$value = substr($value, 1, -1);
|
||||
}
|
||||
self::$values[$name] = $value;
|
||||
}
|
||||
self::hydrateDefaults();
|
||||
}
|
||||
|
||||
private static function hydrateDefaults(): void
|
||||
{
|
||||
self::$values += [
|
||||
'APP_ENV' => 'production',
|
||||
'APP_DEBUG' => 'false',
|
||||
'APP_URL' => 'http://127.0.0.1:8000',
|
||||
'DB_DRIVER' => 'sqlite',
|
||||
'DB_DATABASE' => basePath('database/bazaar.sqlite'),
|
||||
'DB_HOST' => '127.0.0.1',
|
||||
'DB_PORT' => '3306',
|
||||
'DB_USERNAME' => 'root',
|
||||
'DB_PASSWORD' => '',
|
||||
'STRIPE_SECRET_KEY' => 'sk_test_placeholder',
|
||||
'STRIPE_PUBLISHABLE_KEY' => 'pk_test_placeholder',
|
||||
'STRIPE_WEBHOOK_SECRET' => 'whsec_placeholder',
|
||||
'CURRENCY' => 'usd',
|
||||
];
|
||||
}
|
||||
|
||||
public static function get(string $key, mixed $default = null): mixed
|
||||
{
|
||||
if (!self::$loaded) {
|
||||
self::hydrateDefaults();
|
||||
self::$loaded = true;
|
||||
}
|
||||
return self::$values[$key] ?? $default;
|
||||
}
|
||||
|
||||
public static function set(string $key, mixed $value): void
|
||||
{
|
||||
self::$values[$key] = $value;
|
||||
}
|
||||
|
||||
public static function stripeConfigured(): bool
|
||||
{
|
||||
$key = (string) self::get('STRIPE_SECRET_KEY');
|
||||
return str_starts_with($key, 'sk_') && !str_contains($key, 'placeholder');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Bazaar\Core;
|
||||
|
||||
use Bazaar\Repositories\AttributeRepository;
|
||||
use Bazaar\Repositories\CategoryRepository;
|
||||
use Bazaar\Repositories\CouponRepository;
|
||||
use Bazaar\Repositories\OrderRepository;
|
||||
use Bazaar\Repositories\ProductRepository;
|
||||
use Bazaar\Repositories\ReviewRepository;
|
||||
use Bazaar\Repositories\UserRepository;
|
||||
use Bazaar\Repositories\VariantRepository;
|
||||
use Bazaar\Repositories\WishlistRepository;
|
||||
use Bazaar\Services\Analytics;
|
||||
use Bazaar\Services\Auth;
|
||||
use Bazaar\Services\Cart;
|
||||
use Bazaar\Services\CouponService;
|
||||
use Bazaar\Services\OrderService;
|
||||
use Bazaar\Services\ProductSearch;
|
||||
use Bazaar\Services\ReviewService;
|
||||
use Bazaar\Support\Translator;
|
||||
|
||||
final class Context
|
||||
{
|
||||
public function __construct(
|
||||
public readonly Request $request,
|
||||
public readonly Session $session,
|
||||
public readonly Csrf $csrf,
|
||||
public readonly View $view,
|
||||
public readonly Auth $auth,
|
||||
public readonly Cart $cart,
|
||||
public readonly OrderService $orderService,
|
||||
public readonly UserRepository $users,
|
||||
public readonly CategoryRepository $categories,
|
||||
public readonly ProductRepository $products,
|
||||
public readonly OrderRepository $orders,
|
||||
public readonly AttributeRepository $attributes,
|
||||
public readonly VariantRepository $variants,
|
||||
public readonly CouponRepository $coupons,
|
||||
public readonly ReviewRepository $reviews,
|
||||
public readonly WishlistRepository $wishlist,
|
||||
public readonly CouponService $couponService,
|
||||
public readonly ReviewService $reviewService,
|
||||
public readonly ProductSearch $productSearch,
|
||||
public readonly Analytics $analytics,
|
||||
public readonly Translator $translator
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Bazaar\Core;
|
||||
|
||||
final class Csrf
|
||||
{
|
||||
private const KEY = 'csrfToken';
|
||||
|
||||
public function __construct(private readonly Session $session)
|
||||
{
|
||||
}
|
||||
|
||||
public function token(): string
|
||||
{
|
||||
$token = $this->session->get(self::KEY);
|
||||
if (!is_string($token) || $token === '') {
|
||||
$token = bin2hex(random_bytes(32));
|
||||
$this->session->put(self::KEY, $token);
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function verify(?string $candidate): bool
|
||||
{
|
||||
$token = $this->session->get(self::KEY);
|
||||
if (!is_string($token) || !is_string($candidate) || $candidate === '') {
|
||||
return false;
|
||||
}
|
||||
return hash_equals($token, $candidate);
|
||||
}
|
||||
|
||||
public function field(): string
|
||||
{
|
||||
return '<input type="hidden" name="csrfToken" value="' . e($this->token()) . '">';
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user