Newwebshop/app/Core/ServiceContainer.php

492 lines
11 KiB
PHP

<?php
/**
* Copyright seit 2024 Webshop System
*
* Service-Container für PrestaShop-Modul-Kompatibilität
*
* @author Webshop System
* @license GPL v3
*/
namespace App\Core;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception;
class ServiceContainer
{
private static $instance = null;
private $services = [];
private $parameters = [];
private $factories = [];
private $aliases = [];
private function __construct()
{
$this->initializeDefaultServices();
}
/**
* Singleton-Instanz abrufen
*/
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Standard-Services initialisieren
*/
private function initializeDefaultServices()
{
// Datenbankverbindung
$this->set('database', function() {
return DriverManager::getConnection([
'url' => getenv('DATABASE_URL') ?: 'mysql://root:password@localhost/webshop'
]);
});
// Context
$this->set('context', function() {
return Context::getContext();
});
// Hook-System
$this->set('hook', function() {
return new Hook();
});
// Override-System
$this->set('override', function() {
return new Override();
});
// Translator
$this->set('translator', function() {
return new Translator();
});
// Cache
$this->set('cache', function() {
return new Cache();
});
// Logger
$this->set('logger', function() {
return new Logger();
});
// Event Dispatcher
$this->set('event_dispatcher', function() {
return new EventDispatcher();
});
// Module Manager
$this->set('module_manager', function() {
return new ModuleManager();
});
// Configuration
$this->set('configuration', function() {
return new Configuration();
});
// Security
$this->set('security', function() {
return new Security();
});
// Session
$this->set('session', function() {
return new Session();
});
}
/**
* Service registrieren
*/
public function set($id, $service)
{
$this->services[$id] = $service;
return $this;
}
/**
* Service mit Factory registrieren
*/
public function setFactory($id, $factory)
{
$this->factories[$id] = $factory;
return $this;
}
/**
* Service-Alias registrieren
*/
public function setAlias($alias, $id)
{
$this->aliases[$alias] = $id;
return $this;
}
/**
* Parameter setzen
*/
public function setParameter($name, $value)
{
$this->parameters[$name] = $value;
return $this;
}
/**
* Parameter abrufen
*/
public function getParameter($name, $default = null)
{
return isset($this->parameters[$name]) ? $this->parameters[$name] : $default;
}
/**
* Service abrufen
*/
public function get($id)
{
// Alias auflösen
if (isset($this->aliases[$id])) {
$id = $this->aliases[$id];
}
// Service bereits instanziiert
if (isset($this->services[$id]) && is_object($this->services[$id])) {
return $this->services[$id];
}
// Factory verwenden
if (isset($this->factories[$id])) {
$service = call_user_func($this->factories[$id], $this);
$this->services[$id] = $service;
return $service;
}
// Service-Callback ausführen
if (isset($this->services[$id]) && is_callable($this->services[$id])) {
$service = call_user_func($this->services[$id], $this);
$this->services[$id] = $service;
return $service;
}
// Service direkt
if (isset($this->services[$id])) {
return $this->services[$id];
}
throw new \InvalidArgumentException("Service '$id' nicht gefunden");
}
/**
* Service prüfen
*/
public function has($id)
{
return isset($this->services[$id]) || isset($this->factories[$id]) || isset($this->aliases[$id]);
}
/**
* Service entfernen
*/
public function remove($id)
{
unset($this->services[$id]);
unset($this->factories[$id]);
unset($this->aliases[$id]);
return $this;
}
/**
* Alle Services abrufen
*/
public function getServices()
{
$services = [];
foreach (array_keys($this->services) as $id) {
try {
$services[$id] = $this->get($id);
} catch (\Exception $e) {
$services[$id] = null;
}
}
return $services;
}
/**
* Service-Statistiken
*/
public function getStatistics()
{
return [
'services' => count($this->services),
'factories' => count($this->factories),
'aliases' => count($this->aliases),
'parameters' => count($this->parameters)
];
}
/**
* Service-Container zurücksetzen
*/
public function reset()
{
$this->services = [];
$this->factories = [];
$this->aliases = [];
$this->parameters = [];
$this->initializeDefaultServices();
return $this;
}
/**
* Service-Container exportieren
*/
public function export()
{
return [
'services' => array_keys($this->services),
'factories' => array_keys($this->factories),
'aliases' => $this->aliases,
'parameters' => $this->parameters
];
}
}
// Hilfsklassen für Service-Container
class Cache
{
private $cache = [];
public function get($key, $default = null)
{
return isset($this->cache[$key]) ? $this->cache[$key] : $default;
}
public function set($key, $value, $ttl = 3600)
{
$this->cache[$key] = [
'value' => $value,
'expires' => time() + $ttl
];
}
public function delete($key)
{
unset($this->cache[$key]);
}
public function clear()
{
$this->cache = [];
}
}
class Logger
{
public function info($message, $context = [])
{
$this->log('INFO', $message, $context);
}
public function error($message, $context = [])
{
$this->log('ERROR', $message, $context);
}
public function warning($message, $context = [])
{
$this->log('WARNING', $message, $context);
}
public function debug($message, $context = [])
{
$this->log('DEBUG', $message, $context);
}
private function log($level, $message, $context = [])
{
$logFile = __DIR__ . '/../../logs/webshop.log';
$logDir = dirname($logFile);
if (!is_dir($logDir)) {
mkdir($logDir, 0755, true);
}
$timestamp = date('Y-m-d H:i:s');
$contextStr = !empty($context) ? ' ' . json_encode($context) : '';
$logEntry = "[$timestamp] [$level] $message$contextStr" . PHP_EOL;
file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX);
}
}
class EventDispatcher
{
private $listeners = [];
public function addListener($eventName, $listener, $priority = 0)
{
if (!isset($this->listeners[$eventName])) {
$this->listeners[$eventName] = [];
}
$this->listeners[$eventName][] = [
'listener' => $listener,
'priority' => $priority
];
// Nach Priorität sortieren
usort($this->listeners[$eventName], function($a, $b) {
return $b['priority'] - $a['priority'];
});
}
public function dispatch($eventName, $event = null)
{
if (!isset($this->listeners[$eventName])) {
return $event;
}
foreach ($this->listeners[$eventName] as $listenerData) {
$listener = $listenerData['listener'];
$event = call_user_func($listener, $event, $eventName, $this);
}
return $event;
}
public function removeListener($eventName, $listener)
{
if (!isset($this->listeners[$eventName])) {
return;
}
foreach ($this->listeners[$eventName] as $key => $listenerData) {
if ($listenerData['listener'] === $listener) {
unset($this->listeners[$eventName][$key]);
}
}
}
}
class ModuleManager
{
private $modules = [];
public function registerModule($moduleName, $moduleClass)
{
$this->modules[$moduleName] = $moduleClass;
}
public function getModule($moduleName)
{
return isset($this->modules[$moduleName]) ? $this->modules[$moduleName] : null;
}
public function getAllModules()
{
return $this->modules;
}
public function isModuleActive($moduleName)
{
return isset($this->modules[$moduleName]);
}
}
class Configuration
{
private $config = [];
public function get($key, $default = null)
{
return isset($this->config[$key]) ? $this->config[$key] : $default;
}
public function set($key, $value)
{
$this->config[$key] = $value;
}
public function has($key)
{
return isset($this->config[$key]);
}
public function remove($key)
{
unset($this->config[$key]);
}
}
class Security
{
public function hash($password)
{
return password_hash($password, PASSWORD_DEFAULT);
}
public function verify($password, $hash)
{
return password_verify($password, $hash);
}
public function generateToken()
{
return bin2hex(random_bytes(32));
}
public function validateToken($token, $expected)
{
return hash_equals($token, $expected);
}
}
class Session
{
public function __construct()
{
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
}
public function get($key, $default = null)
{
return isset($_SESSION[$key]) ? $_SESSION[$key] : $default;
}
public function set($key, $value)
{
$_SESSION[$key] = $value;
}
public function has($key)
{
return isset($_SESSION[$key]);
}
public function remove($key)
{
unset($_SESSION[$key]);
}
public function clear()
{
session_destroy();
}
public function regenerate()
{
session_regenerate_id(true);
}
}