'/', 'title' => __('Home', 'arrayfunnel')], ['path' => '/side-cart', 'title' => __('Side Cart', 'arrayfunnel')], ['path' => '/checkout', 'title' => __('Checkout', 'arrayfunnel')], ['path' => '/order-bumps', 'title' => __('Order Bumps', 'arrayfunnel')], ['path' => '/abandoned-cart', 'title' => __('Abandoned Cart', 'arrayfunnel')], ['path' => '/modules', 'title' => __('Modules', 'arrayfunnel')], ['path' => '/settings', 'title' => __('Settings', 'arrayfunnel')], ['path' => '/help', 'title' => __('Help', 'arrayfunnel')], ]; foreach ($items as $item) { add_submenu_page( self::MENU_SLUG, $item['title'], $item['title'], self::CAPABILITY, self::MENU_SLUG . '#' . $item['path'], [$this, 'render'] ); } remove_submenu_page(self::MENU_SLUG, self::MENU_SLUG); } public function enableMenuOrder(bool $enabled): bool { return $enabled || current_user_can(self::CAPABILITY); } /** * Position ArrayFunnel after ArraySubs and directly before WooCommerce. * * @param array $menuOrder Current WordPress menu ordering. */ public function orderMenu(array $menuOrder): array { if (!in_array(self::MENU_SLUG, $menuOrder, true)) { return $menuOrder; } $ordered = array_values(array_filter($menuOrder, static fn($slug) => self::MENU_SLUG !== $slug)); $woocommerceIndex = array_search('woocommerce', $ordered, true); $arraysubsIndex = array_search('arraysubs-mainadmin', $ordered, true); if (false !== $woocommerceIndex) { array_splice($ordered, $woocommerceIndex, 0, [self::MENU_SLUG]); } elseif (false !== $arraysubsIndex) { array_splice($ordered, $arraysubsIndex + 1, 0, [self::MENU_SLUG]); } else { return $menuOrder; } return $ordered; } public function render(): void { if (!current_user_can(self::CAPABILITY)) { wp_die(esc_html__('You do not have permission to access this page.', 'arrayfunnel')); } require __DIR__ . '/../views/mainadmin.php'; } public function enqueueAssets(string $hook): void { if ('toplevel_page_' . self::MENU_SLUG !== $hook || !current_user_can(self::CAPABILITY)) { return; } $buildUrl = (string) Config::get('plugin.public_url') . 'build/admin/'; $metadataFile = (string) Config::get('plugin.public_path') . 'build/admin/mainadmin.asset.php'; $metadata = is_readable($metadataFile) ? require $metadataFile : null; $dependencies = is_array($metadata) && isset($metadata['dependencies']) && is_array($metadata['dependencies']) ? $metadata['dependencies'] : ['wp-element']; $version = is_array($metadata) && !empty($metadata['version']) ? (string) $metadata['version'] : ARRAYFUNNEL_VERSION; wp_enqueue_style( 'arrayfunnel-mainadmin', $buildUrl . 'mainadmin.css', ['wp-components'], $version ); // The build emits a mirrored stylesheet; let WordPress swap it in on RTL locales. wp_style_add_data('arrayfunnel-mainadmin', 'rtl', 'replace'); wp_enqueue_script( 'arrayfunnel-mainadmin', $buildUrl . 'mainadmin.js', $dependencies, $version, true ); wp_set_script_translations( 'arrayfunnel-mainadmin', 'arrayfunnel', (string) Config::get('plugin.path') . 'languages' ); wp_localize_script('arrayfunnel-mainadmin', 'arrayfunnelAdmin', $this->getScriptData()); } /** * Data handed to the admin application. * * @return array */ private function getScriptData(): array { return [ 'pluginVersion' => ARRAYFUNNEL_VERSION, 'canManagePluginNotifications' => current_user_can('manage_options'), 'notificationDefaults' => current_user_can('manage_options') ? PluginNotificationSettings::recipientDefaults() : [], 'wpVersion' => get_bloginfo('version'), 'wcVersion' => defined('WC_VERSION') ? WC_VERSION : '', 'apiUrl' => esc_url_raw(rest_url('arrayfunnel/v1')), 'logoUrl' => esc_url_raw((string) Config::get('plugin.public_url') . 'images/brand/logo-mark.png'), 'nonce' => wp_create_nonce('wp_rest'), 'currency' => [ 'symbol' => get_woocommerce_currency_symbol(), 'code' => get_woocommerce_currency(), 'position' => get_option('woocommerce_currency_pos'), ], ]; } }