feat(core): add config loader and request context

This commit is contained in:
dualfroz committed 2026-08-23 12:19:16 +02:00
1 parent 787e5fa3e2
commit bcd3572890
3 files changed
+157

No files matched your search

+72
View File
@@ -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');
}
}
+49
View File
@@ -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
) {
}
}
+36
View File
@@ -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()) . '">';
}
}