ExternalPluginMenuAdapter.php
4 months ago
MenuSuppressor.php
4 months ago
PagesRouter.php
4 months ago
PluginSubmenu.php
3 months ago
TopLevelMenu.php
4 months ago
PluginSubmenu.php
81 lines
| 1 | <?php |
| 2 | |
| 3 | namespace WhatsappScoped\YayCommerce\AdminShell\Menu; |
| 4 | |
| 5 | use WhatsappScoped\YayCommerce\AdminShell\Contracts\PluginMenuAdapter; |
| 6 | use WhatsappScoped\YayCommerce\AdminShell\License\Contracts\LicenseConfigAdapter; |
| 7 | use WhatsappScoped\YayCommerce\AdminShell\License\License; |
| 8 | /** |
| 9 | * Registers a plugin-named submenu under YayCommerce. |
| 10 | * Works with any PluginMenuAdapter (lite or pro). |
| 11 | * |
| 12 | * For pro plugins: automatically redirects to Licenses page when license |
| 13 | * is not active — no developer action needed. |
| 14 | * @internal |
| 15 | */ |
| 16 | class PluginSubmenu |
| 17 | { |
| 18 | private PluginMenuAdapter $adapter; |
| 19 | public function __construct(PluginMenuAdapter $adapter) |
| 20 | { |
| 21 | $this->adapter = $adapter; |
| 22 | } |
| 23 | public function init() : void |
| 24 | { |
| 25 | add_action('admin_menu', [$this, 'register'], 10); |
| 26 | } |
| 27 | public function register() : void |
| 28 | { |
| 29 | $menu_slug = $this->adapter->get_menu_slug(); |
| 30 | if (empty($menu_slug)) { |
| 31 | return; |
| 32 | } |
| 33 | global $submenu; |
| 34 | $has_menu = \false; |
| 35 | $is_override = \false; |
| 36 | if (isset($submenu['yaycommerce'])) { |
| 37 | $yaycommerce_menu = $submenu['yaycommerce']; |
| 38 | foreach ($yaycommerce_menu as $key => $value) { |
| 39 | if ($value[2] === $menu_slug) { |
| 40 | if (\method_exists($this->adapter, 'is_licensed') && $this->adapter->is_licensed() || !\method_exists($this->adapter, 'is_licensed')) { |
| 41 | remove_submenu_page('yaycommerce', $menu_slug); |
| 42 | $is_override = \true; |
| 43 | } else { |
| 44 | $has_menu = \true; |
| 45 | } |
| 46 | break; |
| 47 | } |
| 48 | } |
| 49 | } |
| 50 | if ($has_menu) { |
| 51 | return; |
| 52 | } |
| 53 | $callback = $this->adapter->get_settings_page_callback(); |
| 54 | // Guard: ensure callback is actually callable |
| 55 | if (null !== $callback && !\is_callable($callback)) { |
| 56 | $callback = null; |
| 57 | } |
| 58 | // Pro plugins without active license → override callback to redirect |
| 59 | $needs_redirect = \false; |
| 60 | if ($this->adapter instanceof LicenseConfigAdapter) { |
| 61 | $license = new License($this->adapter); |
| 62 | if (!$license->is_active() || $license->is_expired()) { |
| 63 | $needs_redirect = \true; |
| 64 | $callback = null; |
| 65 | } |
| 66 | } |
| 67 | $page_id = add_submenu_page('yaycommerce', $this->adapter->get_page_title(), $this->adapter->get_menu_title(), $this->adapter->get_capability(), $menu_slug, $callback ?? '__return_false', $this->adapter->get_settings_page_position()); |
| 68 | if ($is_override) { |
| 69 | \remove_all_actions('load-' . $page_id); |
| 70 | } |
| 71 | if ($needs_redirect) { |
| 72 | add_action('load-' . $page_id, [__CLASS__, 'redirect_to_licenses']); |
| 73 | } |
| 74 | } |
| 75 | public static function redirect_to_licenses() : void |
| 76 | { |
| 77 | wp_safe_redirect(\admin_url('admin.php?page=yaycommerce-licenses')); |
| 78 | exit; |
| 79 | } |
| 80 | } |
| 81 |