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); } }