diff --git a/includes/Admin.php b/includes/Admin.php index e3224ee..e81bab5 100644 --- a/includes/Admin.php +++ b/includes/Admin.php @@ -37,6 +37,13 @@ class Admin { */ private $menu_ids = array(); + /** + * Registered screen handlers. + * + * @var array + */ + private $screen_handlers = array(); + /** * Constructor. * @@ -51,6 +58,18 @@ public function __construct() { add_action( 'admin_menu', array( $this, 'admin_menu' ), 5 ); add_action( 'admin_init', array( $this, 'init' ) ); add_action( 'current_screen', array( $this, 'current_screen' ) ); + + // register the screen handlers. + $this->screen_handlers = array( + 'options-permalink' => Permalink::class, + 'product' => Single_Product::class, + 'edit-product' => List_Products::class, + 'shop_order' => Single_Order::class, + 'edit-shop_order' => List_Orders::class, + 'plugins' => Plugins::class, + 'woocommerce_page_wc-orders' => array( $this, 'handle_wc_hpos_orders_screen' ), + 'woocommerce_page_wc-admin' => array( $this, 'handle_wc_analytics_screen' ), + ); } /** @@ -70,91 +89,77 @@ public function admin_menu(): void { 'toplevel' => $menu->toplevel_screen_id, 'settings' => $menu->settings_screen_id, ); + + /** + * Add the settings screen using the WooCommerce POS menu ID. + */ + $this->screen_handlers[ $this->menu_ids['settings'] ] = Settings::class; } /** * Conditionally load subclasses based on admin screen. * + * @TODO - I need to register the instances to allow remove_action/remove_filter. + * * @param \WP_Screen $current_screen Current screen object. */ public function current_screen( $current_screen ): void { - $action = $_GET['action'] ?? ''; - - // Main switch for screen IDs. - switch ( $current_screen->id ) { - case 'options-permalink': - new Permalink(); - - return; - case 'product': - $single_product_class = apply_filters( 'woocommerce_pos_single_product_admin_class', Single_Product::class ); - new $single_product_class(); - - return; - case 'edit-product': - new List_Products(); - - return; - case 'shop_order': - new Single_Order(); - - return; - case 'edit-shop_order': - new List_Orders(); - - return; - case 'woocommerce_page_wc-orders': - if ( 'edit' === $action ) { - new HPOS_Single_Order(); - } else { - new HPOS_List_Orders(); - } - - return; - case 'plugins': - new Plugins(); - - return; - default: - // Check if the current screen matches a custom setting page ID. - if ( $this->is_woocommerce_pos_setting_page( $current_screen ) ) { - new Settings(); - - return; - } - // Check if the current screen is for WooCommerce Analytics. - if ( $this->is_woocommerce_analytics( $current_screen ) ) { - new Analytics(); - - return; - } + /** + * Backwards compatibility for WooCommerce POS Pro 1.4.2 and below. + * + * @TODO: Remove in WooCommerce POS 2.0.0. + */ + $this->screen_handlers['product'] = apply_filters( 'woocommerce_pos_single_product_admin_class', Single_Product::class ); + + /** + * Filters the screen handlers for WooCommerce POS admin screens. + * + * @since 1.4.10 + * + * @param array $handlers Associative array of screen IDs and their corresponding handlers. + * Handler can be a class name or a callback array. + * @param \WP_Screen $current_screen The current WP_Screen object being loaded in the admin. + */ + $handlers = apply_filters( 'woocommerce_pos_admin_screen_handlers', $this->screen_handlers, $current_screen ); + + // Check if the current screen has a handler. + if ( isset( $handlers[ $current_screen->id ] ) ) { + $handler = $handlers[ $current_screen->id ]; + + if ( is_array( $handler ) && method_exists( $handler[0], $handler[1] ) ) { + call_user_func( $handler ); + } elseif ( class_exists( $handler ) ) { + new $handler(); + } } } /** - * Check if the current screen matches the POS setting page ID. * - * @param \WP_Screen $current_screen Current screen object. */ - private function is_woocommerce_pos_setting_page( $current_screen ) { - return \array_key_exists( 'settings', $this->menu_ids ) && $this->menu_ids['settings'] === $current_screen->id; + public function handle_wc_hpos_orders_screen() { + if ( 'edit' === $_GET['action'] ) { + new HPOS_Single_Order(); + } else { + new HPOS_List_Orders(); + } } /** - * Check if the current screen is for WooCommerce Analytics. * - * @param \WP_Screen $current_screen Current screen object. */ - private function is_woocommerce_analytics( $current_screen ) { + public function handle_wc_analytics_screen() { if ( class_exists( '\Automattic\WooCommerce\Admin\PageController' ) ) { $wc_admin_page_controller = PageController::get_instance(); - $wc_admin_current_page = $wc_admin_page_controller->get_current_page(); - $id = $wc_admin_current_page['id'] ?? null; - $parent = $wc_admin_current_page['parent'] ?? null; + if ( $wc_admin_page_controller ) { + $wc_admin_current_page = $wc_admin_page_controller->get_current_page(); + $id = $wc_admin_current_page['id'] ?? null; + $parent = $wc_admin_current_page['parent'] ?? null; - return 'woocommerce-analytics' === $id || 'woocommerce-analytics' === $parent; + if ( 'woocommerce-analytics' === $id || 'woocommerce-analytics' === $parent ) { + new Analytics(); + } + } } - - return false; } } diff --git a/includes/Admin/Menu.php b/includes/Admin/Menu.php index 8808455..c353ecc 100644 --- a/includes/Admin/Menu.php +++ b/includes/Admin/Menu.php @@ -1,11 +1,11 @@ * * @see http://wcpos.com + * @package WCPOS\WooCommercePOS */ namespace WCPOS\WooCommercePOS\Admin; @@ -13,14 +13,21 @@ use const HOUR_IN_SECONDS; use const WCPOS\WooCommercePOS\PLUGIN_NAME; +/** + * + */ class Menu { /** - * @vars string Unique top level menu identifier + * Unique top level menu identifier. + * + * @var string */ public $toplevel_screen_id; /** - * @vars string Unique top level menu identifier + * Unique top level menu identifier. + * + * @var string */ public $settings_screen_id; @@ -34,7 +41,7 @@ public function __construct() { add_filter( 'menu_order', array( $this, 'menu_order' ), 9, 1 ); } -// add_filter( 'woocommerce_analytics_report_menu_items', array( $this, 'analytics_menu_items' ) ); + // add_filter( 'woocommerce_analytics_report_menu_items', array( $this, 'analytics_menu_items' ) ); } /** @@ -56,7 +63,7 @@ public function menu_order( array $menu_order ): array { if ( false !== $woo && false !== $pos ) { // rearrange menu unset( $menu_order[ $pos ] ); - array_splice( $menu_order, ++ $woo, 0, PLUGIN_NAME ); + array_splice( $menu_order, ++$woo, 0, PLUGIN_NAME ); // rearrange submenu global $submenu; @@ -98,22 +105,27 @@ public function display_upgrade_page(): void { * Add POS submenu to WooCommerce Analytics menu. */ public function analytics_menu_items( array $report_pages ): array { - // Find the position of the 'Orders' item + // Find the position of the 'Orders' item. $position = array_search( 'Orders', array_column( $report_pages, 'title' ), true ); - // Use array_splice to add the new item - array_splice($report_pages, $position + 1, 0, array( + // Use array_splice to add the new item. + array_splice( + $report_pages, + $position + 1, + 0, array( - 'id' => 'woocommerce-analytics-pos', - 'title' => __( 'POS', 'woocommerce-pos' ), - 'parent' => 'woocommerce-analytics', - 'path' => '/analytics/pos', - 'nav_args' => array( - 'order' => 45, - 'parent' => 'woocommerce-analytics', + array( + 'id' => 'woocommerce-analytics-pos', + 'title' => __( 'POS', 'woocommerce-pos' ), + 'parent' => 'woocommerce-analytics', + 'path' => '/analytics/pos', + 'nav_args' => array( + 'order' => 45, + 'parent' => 'woocommerce-analytics', + ), ), - ), - )); + ) + ); return $report_pages; } @@ -172,9 +184,12 @@ private function register_pos_admin(): void { * @type string $settings The settings submenu ID. * } */ - do_action( 'woocommerce_pos_register_pos_admin', array( - 'toplevel' => $this->toplevel_screen_id, - 'settings' => $this->settings_screen_id, - ) ); + do_action( + 'woocommerce_pos_register_pos_admin', + array( + 'toplevel' => $this->toplevel_screen_id, + 'settings' => $this->settings_screen_id, + ) + ); } } diff --git a/includes/Admin/Products/Single_Product.php b/includes/Admin/Products/Single_Product.php index e2ee273..bd706cf 100644 --- a/includes/Admin/Products/Single_Product.php +++ b/includes/Admin/Products/Single_Product.php @@ -12,6 +12,7 @@ namespace WCPOS\WooCommercePOS\Admin\Products; +use WCPOS\WooCommercePOS\Registry; use const DOING_AUTOSAVE; class Single_Product { @@ -29,8 +30,10 @@ class Single_Product { * @var string */ private $pro_link = ''; - + public function __construct() { + Registry::get_instance()->set( get_class( $this ), $this ); + $this->barcode_field = woocommerce_pos_get_settings( 'general', 'barcode_field' ); $this->pro_link = '' . __( 'Upgrade to Pro', 'woocommerce-pos' ) . '.'; @@ -44,7 +47,7 @@ public function __construct() { if ( $this->barcode_field && '_sku' !== $this->barcode_field ) { add_action( 'woocommerce_product_options_sku', array( $this, 'woocommerce_product_options_sku' ) ); add_action( 'woocommerce_process_product_meta', array( $this, 'woocommerce_process_product_meta' ) ); - add_action('woocommerce_product_after_variable_attributes', array( $this, 'after_variable_attributes_barcode_field' ), 10, 3); + add_action( 'woocommerce_product_after_variable_attributes', array( $this, 'after_variable_attributes_barcode_field' ), 10, 3 ); add_action( 'woocommerce_save_product_variation', array( $this, 'save_product_variation_barcode_field' ) ); } @@ -52,7 +55,7 @@ public function __construct() { add_action( 'save_post', array( $this, 'save_post' ), 10, 2 ); add_action( 'post_submitbox_misc_actions', array( $this, 'post_submitbox_misc_actions' ), 99 ); add_action( 'woocommerce_product_after_variable_attributes', array( $this, 'after_variable_attributes_pos_only_products' ), 10, 3 ); - add_action( 'woocommerce_save_product_variation', array( $this, 'save_product_variation_pos_only_products', ) ); + add_action( 'woocommerce_save_product_variation', array( $this, 'save_product_variation_pos_only_products' ) ); } add_action( 'woocommerce_product_options_pricing', array( $this, 'add_store_price_fields' ) ); @@ -87,8 +90,8 @@ public function add_store_price_fields(): void { 'label' => '', 'value' => true, 'cbvalue' => false, - 'description' => __('Enable POS specific prices.', 'woocommerce-pos') . ' ' . $this->pro_link, - 'custom_attributes' => array('disabled' => 'disabled'), + 'description' => __( 'Enable POS specific prices.', 'woocommerce-pos' ) . ' ' . $this->pro_link, + 'custom_attributes' => array( 'disabled' => 'disabled' ), ) ); } @@ -107,8 +110,8 @@ public function add_store_tax_fields(): void { 'label' => '', 'value' => true, 'cbvalue' => false, - 'description' => __('Enable POS specific taxes.', 'woocommerce-pos') . ' ' . $this->pro_link, - 'custom_attributes' => array('disabled' => 'disabled'), + 'description' => __( 'Enable POS specific taxes.', 'woocommerce-pos' ) . ' ' . $this->pro_link, + 'custom_attributes' => array( 'disabled' => 'disabled' ), ) ); } @@ -220,6 +223,7 @@ public function post_submitbox_misc_actions(): void { } /**s + * * @param $loop * @param $variation_data * @param $variation diff --git a/includes/Init.php b/includes/Init.php index 651e557..80144b6 100644 --- a/includes/Init.php +++ b/includes/Init.php @@ -19,6 +19,9 @@ use WP_REST_Request; use WP_REST_Server; +/** + * + */ class Init { /** * Constructor. diff --git a/includes/Registry.php b/includes/Registry.php new file mode 100644 index 0000000..5fb3755 --- /dev/null +++ b/includes/Registry.php @@ -0,0 +1,60 @@ + + * @see https://wcpos.com + * @package WCPOS\WooCommercePOS + */ + +namespace WCPOS\WooCommercePOS; + +/** + * + */ +class Registry { + /** + * Singleton instance. + * + * @var Registry + */ + private static $instance = null; + + /** + * Storage for the registry. + * + * @var array + */ + private $storage = array(); + + /** + * Gets the singleton instance of the registry. + */ + public static function get_instance() { + if ( null === self::$instance ) { + self::$instance = new self(); + } + return self::$instance; + } + + /** + * Registers a new instance. + * + * @param string $key + * @param object $object + */ + public function set( $key, $object ) { + $this->storage[ $key ] = $object; + } + + /** + * Retrieves an instance by key. + * + * @param string $key + */ + public function get( $key ) { + return isset( $this->storage[ $key ] ) ? $this->storage[ $key ] : null; + } +} diff --git a/readme.txt b/readme.txt index 51d8b00..53ed140 100644 --- a/readme.txt +++ b/readme.txt @@ -65,7 +65,7 @@ There is more information on our website at [https://wcpos.com](https://wcpos.co = 1.4.9 - 2024/01/21 = = 1.4.8 - 2024/01/21 = -* Fix: duplicating Products in WC Admin also duplicated POS UUID, which casued problems +* Fix: duplicating Products in WC Admin also duplicated POS UUID, which caused problems = 1.4.7 - 2024/01/18 = * Bump: web application to version 1.4.1