core = $core; $this->support = new Support( $core ); add_action( 'admin_menu', [ $this, 'register_menu' ] ); add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] ); } /** * Capability for the Patchwork menu: the first module capability the current * user has, or null when they can't manage any module. */ public static function menu_cap( Core $core ): ?string { foreach ( $core->modules() as $module ) { if ( current_user_can( $module->settings_capability() ) ) return $module->settings_capability(); } return null; } public static function current_user_can_menu( Core $core ): bool { return self::menu_cap( $core ) !== null; } /** Menu icon: the Patchwork mark (3×3 patches in braces), single colour so WP can tint it. */ public static function icon_svg( string $fill = 'black' ): string { $brace = 'M5 2.5H4C2.9 2.5 2.4 3.2 2.4 4.3v3.3c0 .8-.4 1.3-1.4 1.4v2c1 .1 1.4.6 1.4 1.4v3.3c0 1.1.5 1.8 1.6 1.8h1v-1.6h-.6c-.4 0-.5-.3-.5-.8v-3.2c0-1-.4-1.6-1.2-1.9.8-.3 1.2-.9 1.2-1.9V4.9c0-.5.1-.8.5-.8H5z'; $rects = ''; foreach ( [ 6.1, 8.9, 11.7 ] as $y ) { foreach ( [ 6.1, 8.9, 11.7 ] as $x ) { $rects .= sprintf( '', $x, $y ); } } $svg = '' . $rects . ''; return 'data:image/svg+xml;base64,' . base64_encode( $svg ); } // ─── Menu ───────────────────────────────────────────────────────────────── public function register_menu(): void { $modules = $this->core->modules(); if ( ! $modules ) return; // The menu shows if the user can manage at least one module. $menu_cap = self::menu_cap( $this->core ); if ( ! $menu_cap ) return; add_menu_page( 'Patchwork', 'Patchwork', $menu_cap, self::SLUG, [ $this, 'render_overview' ], self::icon_svg(), 56 ); add_submenu_page( self::SLUG, __( 'Patchwork overview', 'patchwork-order-split' ), __( 'Overview', 'patchwork-order-split' ), $menu_cap, self::SLUG, [ $this, 'render_overview' ] ); foreach ( $modules as $module ) { add_submenu_page( self::SLUG, $module->name(), self::short_name( $module ), $module->settings_capability(), 'patchwork-' . $module->id(), function() use ( $module ) { $this->render_module( $module ); } ); } add_submenu_page( self::SLUG, __( 'Get support', 'patchwork-order-split' ), __( 'Support', 'patchwork-order-split' ), $menu_cap, Support::PAGE, [ $this->support, 'render' ] ); } /** "Patchwork Split" → "Split" inside the Patchwork menu. */ private static function short_name( Module $module ): string { return preg_replace( '/^Patchwork\s+/i', '', $module->name() ); } public function enqueue(): void { $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; if ( ! $screen ) return; $is_patchwork = strpos( $screen->id, self::SLUG ) !== false; $is_orders = in_array( $screen->id, [ 'woocommerce_page_wc-orders', 'edit-shop_order', 'shop_order' ], true ); if ( ! $is_patchwork && ! $is_orders ) return; wp_enqueue_style( 'patchwork-core', PATCHWORK_CORE_URL . 'assets/core.css', [], PATCHWORK_CORE_VERSION ); } // ─── Overview ───────────────────────────────────────────────────────────── public function render_overview(): void { $modules = $this->core->modules(); ?>
dashboard_card(); $can = current_user_can( $module->settings_capability() ); ?>

name() ); ?> is_pro() ) : ?>

version() ) ); ?>
description() ) : ?>

description() ); ?>

render_catalog(); ?>
core->catalog(), $this->core->modules() ); if ( ! $missing ) return; ?>

__( 'Settings', 'patchwork-order-split' ), 'activity' => __( 'Activity', 'patchwork-order-split' ), 'licence' => __( 'Licence', 'patchwork-order-split' ), ]; if ( ! isset( $tabs[ $tab ] ) ) $tab = 'settings'; ?>
name(), $module->description(), $module ); ?>

id() ); } elseif ( $tab === 'licence' ) { self::render_licence( $module ); } else { Settings_Page::render( $module ); } ?>
is_pro(); $features = $module->pro_features(); ?>

name() ); ?>

is_dev_pro() ) : ?>

upgrade_url() ) : ?> account_url() ) : ?>


icon(); if ( strpos( $icon, 'dashicons-' ) === 0 ) { echo ''; } else { echo ''; } } }