| 1 |
<?php |
| 2 |
/** |
| 3 |
* Platform registry. |
| 4 |
* |
| 5 |
* Holds the platforms registered by each active product's bootstrap and resolves |
| 6 |
* the right platform for a given context. There is intentionally no ambiguous |
| 7 |
* "current platform" accessor: every consumer resolves by an explicit context |
| 8 |
* (registered key, admin screen, install check, or on-disk host). |
| 9 |
* |
| 10 |
* @package YayMail\Platform |
| 11 |
*/ |
| 12 |
|
| 13 |
namespace YayMail\Platform; |
| 14 |
|
| 15 |
defined( 'ABSPATH' ) || exit; |
| 16 |
|
| 17 |
final class PlatformRegistry { |
| 18 |
|
| 19 |
/** |
| 20 |
* Registered platforms keyed by PlatformInterface::key(). |
| 21 |
* |
| 22 |
* @var array<string, PlatformInterface> |
| 23 |
*/ |
| 24 |
private static $platforms = []; |
| 25 |
|
| 26 |
/** |
| 27 |
* Register a platform. Idempotent: last registration wins for a given key, so |
| 28 |
* both products registering (both-active) is safe. |
| 29 |
* |
| 30 |
* @param PlatformInterface $platform Platform to register. |
| 31 |
* @return void |
| 32 |
*/ |
| 33 |
public static function register( PlatformInterface $platform ) { |
| 34 |
self::$platforms[ $platform->key() ] = $platform; |
| 35 |
} |
| 36 |
|
| 37 |
/** |
| 38 |
* Whether a platform is registered for the given key. |
| 39 |
* |
| 40 |
* @param string $key Platform key. |
| 41 |
* @return bool |
| 42 |
*/ |
| 43 |
public static function has( string $key ): bool { |
| 44 |
return isset( self::$platforms[ $key ] ); |
| 45 |
} |
| 46 |
|
| 47 |
/** |
| 48 |
* Get a registered platform by key, or null when not registered. |
| 49 |
* |
| 50 |
* @param string $key Platform key. |
| 51 |
* @return PlatformInterface|null |
| 52 |
*/ |
| 53 |
public static function get( string $key ) { |
| 54 |
return self::$platforms[ $key ] ?? null; |
| 55 |
} |
| 56 |
|
| 57 |
/** |
| 58 |
* Resolve the platform whose settings screen matches the given admin screen. |
| 59 |
* |
| 60 |
* @param \WP_Screen|null $screen Current admin screen. |
| 61 |
* @return PlatformInterface|null |
| 62 |
*/ |
| 63 |
public static function from_screen( $screen ) { |
| 64 |
if ( ! $screen || empty( $screen->id ) ) { |
| 65 |
return null; |
| 66 |
} |
| 67 |
|
| 68 |
foreach ( self::$platforms as $platform ) { |
| 69 |
if ( $platform->hook_suffix() === $screen->id ) { |
| 70 |
return $platform; |
| 71 |
} |
| 72 |
} |
| 73 |
|
| 74 |
return null; |
| 75 |
} |
| 76 |
|
| 77 |
/** |
| 78 |
* The platform that physically hosts the loaded core on disk. |
| 79 |
* |
| 80 |
* Preserves the historical behavior of Helpers::get_plugin_path/url: the WP |
| 81 |
* plugin hosts the core when YayMail lite + Yay WP Pro are both active, |
| 82 |
* otherwise the WooCommerce plugin does. Consumed only by get_plugin_path/url. |
| 83 |
* |
| 84 |
* @return PlatformInterface |
| 85 |
*/ |
| 86 |
public static function host_platform(): PlatformInterface { |
| 87 |
if ( self::wp_hosts_core() && self::has( 'email-builder' ) ) { |
| 88 |
return self::$platforms['email-builder']; |
| 89 |
} |
| 90 |
|
| 91 |
if ( self::has( 'yaymail' ) ) { |
| 92 |
return self::$platforms['yaymail']; |
| 93 |
} |
| 94 |
|
| 95 |
// No 'yaymail' platform registered. Historically get_plugin_path/url returned |
| 96 |
// the YAYMAIL_PLUGIN_* constants in this case, which YaymailPlatform mirrors. |
| 97 |
// Only warn on a genuinely empty registry (a too-early read before bootstrap). |
| 98 |
if ( empty( self::$platforms ) && defined( 'YAYMAIL_IS_DEVELOPMENT' ) && YAYMAIL_IS_DEVELOPMENT && function_exists( '_doing_it_wrong' ) ) { |
| 99 |
_doing_it_wrong( __METHOD__, 'PlatformRegistry read before any platform was registered.', '4.4.2' ); |
| 100 |
} |
| 101 |
|
| 102 |
return new YaymailPlatform(); |
| 103 |
} |
| 104 |
|
| 105 |
/** |
| 106 |
* Whether the Yay WP Email Customizer plugin hosts the shared core on disk. |
| 107 |
* |
| 108 |
* True when YayMail lite is active alongside the Yay WP Pro plugin; in that |
| 109 |
* setup the WP plugin provides the authoritative core files, so paths/URLs |
| 110 |
* resolve to it. Preserves the exact detection formerly in |
| 111 |
* Helpers::is_yaymail_lite_and_yay_wp_pro_active(). |
| 112 |
* |
| 113 |
* @return bool |
| 114 |
*/ |
| 115 |
private static function wp_hosts_core(): bool { |
| 116 |
// Set by this addon's bootstrap: true whenever the active yaymail-core |
| 117 |
// variant (free "yaymail", or paid "yaymail-pro" / "email-customizer- |
| 118 |
// for-woocommerce") is <= 4.4.2, i.e. too old to provide the shared |
| 119 |
// src/ files this addon's own classes now depend on. Takes priority |
| 120 |
// over the legacy free-lite-only check below. |
| 121 |
if ( defined( 'YAYWP_HOSTS_CORE' ) ) { |
| 122 |
return YAYWP_HOSTS_CORE; |
| 123 |
} |
| 124 |
|
| 125 |
$is_yaymail_lite_active = function_exists( 'is_plugin_active' ) && is_plugin_active( 'yaymail/yaymail.php' ); |
| 126 |
$is_yay_wp_pro_active = function_exists( 'YayMail\wp_mail_init' ) |
| 127 |
&& class_exists( 'YaymailWpPluginAdapter', false ) |
| 128 |
&& method_exists( 'YaymailWpPluginAdapter', 'is_licensed' ); |
| 129 |
|
| 130 |
return $is_yaymail_lite_active && $is_yay_wp_pro_active; |
| 131 |
} |
| 132 |
} |
| 133 |
|