Files
shop-old/core/payments/Registry.php
T
Tom Bartelt 85bc1d8c9a feat(payments): Block Zahlungsvorgang im Bestell-Editor, Storno-Felder bei automatischem Storno
- Bestell-Editor rechts: Zahlungsvorgang (Status, Grund, Transaktions-ID,
  Referenz, Betraege, Zeiten, Verlauf aus PG payment_log), anbieterneutral
  ueber payment_transactions (Payments\Overview, Log::forOrder)
- markCancelled() fuellt Stornodatum, Stornostatus, Stornogrund und
  Storno-Nachricht der Bestellung (nur leere Felder)
- neuer Stornogrund 'Zahlung beim Anbieter nicht abgeschlossen' (install.sql)
- reconcile: 404-Grund lesbar mit Alter des Vorgangs
2026-09-22 09:30:52 +02:00

88 lines
2.7 KiB
PHP

<?php
declare(strict_types=1);
namespace Payments;
/**
* Findet den Anbieter zu einem payment_methods.module.
*
* Konvention: core/payments/providers/<module>/Provider.php mit Klasse
* Payments\Providers\<Module in StudlyCase>\Provider
* Beispiel: module 'paypal_v2' -> Payments\Providers\PaypalV2\Provider
*
* Neuer Anbieter = neues Verzeichnis, sonst nichts.
*/
final class Registry
{
/** @var array<string,ProviderInterface|null> */
private static array $cache = [];
public static function has(string $module): bool
{
$module = self::clean($module);
return $module !== '' && \is_file(self::dir($module) . '/Provider.php');
}
public static function get(string $module, object $base): ?ProviderInterface
{
$module = self::clean($module);
if ($module === '') {
return null;
}
if (\array_key_exists($module, self::$cache)) {
return self::$cache[$module];
}
$file = self::dir($module) . '/Provider.php';
if (!\is_file($file)) {
return self::$cache[$module] = null;
}
self::requireCore();
require_once $file;
$class = 'Payments\\Providers\\' . self::studly($module) . '\\Provider';
if (!\class_exists($class)) {
\error_log('Payments: Provider-Klasse fehlt: ' . $class);
return self::$cache[$module] = null;
}
$p = new $class($base);
return self::$cache[$module] = ($p instanceof ProviderInterface ? $p : null);
}
/** Alle installierten Anbieter (fuer Backend-Liste und Abgleicher). @return list<string> */
public static function all(): array
{
$out = [];
foreach (\glob(__DIR__ . '/providers/*/Provider.php') ?: [] as $f) {
$out[] = \basename(\dirname($f));
}
\sort($out);
return $out;
}
public static function requireCore(): void
{
foreach (['ProviderInterface', 'Result', 'Secrets', 'Log', 'Overview', 'AbstractProvider'] as $c) {
require_once __DIR__ . '/' . $c . '.php';
}
}
private static function dir(string $module): string
{
return __DIR__ . '/providers/' . $module;
}
private static function clean(string $module): string
{
return \preg_match('/^[a-z0-9_]+$/', $module) ? $module : '';
}
private static function studly(string $module): string
{
return \str_replace('_', '', \ucwords($module, '_'));
}
}
// Wer die Registry laedt, bekommt die Kernklassen gleich mit (Secrets, Log, Result ...),
// nicht erst beim ersten Provider. Sonst faellt z.B. der Zahlart-Editor um, der nur
// Secrets braucht.
Registry::requireCore();