| @@ -33,8 +33,9 @@ | ||
| 33 | 33 | |
| 34 | 34 | $this->includes_not_hooked(); |
| 35 | 35 | |
| 36 | 36 | add_action( 'init', array( $this, 'includes' ) ); |
| 37 | + add_action( 'plugins_loaded', array( $this, 'includes_after_plugins_loaded' ) ); | |
| 37 | 38 | |
| 38 | 39 | add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles_scripts' ) ); |
| 39 | 40 | add_action( 'plugin_action_links_' . MERCHANT_BASE, array( $this, 'action_links' ) ); |
| 40 | 41 | add_filter( 'admin_body_class', array( $this, 'add_admin_body_class' ), 999 ); |
| @@ -40,8 +41,17 @@ | ||
| 40 | 41 | add_filter( 'admin_body_class', array( $this, 'add_admin_body_class' ), 999 ); |
| 41 | 42 | } |
| 42 | 43 | |
| 43 | 44 | /** |
| 45 | + * Include files after plugins loaded. | |
| 46 | + * | |
| 47 | + * Before init hook. | |
| 48 | + */ | |
| 49 | + public function includes_after_plugins_loaded() { | |
| 50 | + require_once MERCHANT_DIR . 'admin/classes/class-merchant-admin-statistics-tracking.php'; | |
| 51 | + } | |
| 52 | + | |
| 53 | + /** | |
| 44 | 54 | * No hooked includes. |
| 45 | 55 | * These files are included without any WordPress hook. |
| 46 | 56 | */ |
| 47 | 57 | public function includes_not_hooked() { |
| @@ -57,13 +67,34 @@ | ||
| 57 | 67 | // Notices. |
| 58 | 68 | require_once MERCHANT_DIR . 'admin/notices/class-merchant-notice.php'; |
| 59 | 69 | require_once MERCHANT_DIR . 'admin/notices/class-merchant-notice-review.php'; |
| 60 | 70 | require_once MERCHANT_DIR . 'admin/notices/class-merchant-notice-upsell.php'; |
| 71 | + require_once MERCHANT_DIR . 'admin/notices/class-merchant-notice-campaign.php'; | |
| 72 | + require_once MERCHANT_DIR . 'admin/notices/class-merchant-patcher-eol-notice.php'; | |
| 61 | 73 | |
| 74 | + // Admin classes. | |
| 62 | 75 | require_once MERCHANT_DIR . 'admin/classes/class-merchant-admin-menu.php'; |
| 76 | + | |
| 77 | + // Field architecture. | |
| 78 | + require_once MERCHANT_DIR . 'admin/classes/admin-options/interface-merchant-field.php'; | |
| 79 | + require_once MERCHANT_DIR . 'admin/classes/admin-options/class-merchant-abstract-field.php'; | |
| 80 | + require_once MERCHANT_DIR . 'admin/classes/admin-options/class-merchant-field-registry.php'; | |
| 81 | + | |
| 82 | + // Extracted SRP classes. | |
| 83 | + require_once MERCHANT_DIR . 'admin/classes/admin-options/class-merchant-admin-assets.php'; | |
| 84 | + require_once MERCHANT_DIR . 'admin/classes/admin-options/class-merchant-select2-choices.php'; | |
| 85 | + require_once MERCHANT_DIR . 'admin/classes/admin-options/class-merchant-settings-saver.php'; | |
| 86 | + require_once MERCHANT_DIR . 'admin/classes/admin-options/class-merchant-settings-renderer.php'; | |
| 87 | + | |
| 63 | 88 | require_once MERCHANT_DIR . 'admin/classes/class-merchant-admin-options.php'; |
| 89 | + require_once MERCHANT_DIR . 'admin/classes/class-merchant-admin-ajax.php'; | |
| 64 | 90 | require_once MERCHANT_DIR . 'admin/classes/class-merchant-admin-utils.php'; |
| 65 | 91 | require_once MERCHANT_DIR . 'admin/classes/class-merchant-admin-preview.php'; |
| 92 | + // Plugin installer. | |
| 93 | + require_once MERCHANT_DIR . 'admin/classes/class-merchant-plugin-installer.php'; | |
| 94 | + | |
| 95 | + // White Label settings section. | |
| 96 | + require_once MERCHANT_DIR . 'admin/classes/class-merchant-white-label-settings.php'; | |
| 66 | 97 | } |
| 67 | 98 | |
| 68 | 99 | /** |
| 69 | 100 | * Enqueue admin styles and scripts. |
| @@ -68,16 +99,22 @@ | ||
| 68 | 99 | /** |
| 69 | 100 | * Enqueue admin styles and scripts. |
| 70 | 101 | */ |
| 71 | 102 | public function enqueue_styles_scripts() { |
| 72 | - | |
| 73 | - $page = ( ! empty( $_GET['page'] ) ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 103 | + $section = sanitize_text_field( wp_unslash( $_GET['section'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 74 | 104 | |
| 75 | 105 | wp_register_script( 'merchant-select2', MERCHANT_URI . 'assets/vendor/select2/select2.full.min.js', array( 'jquery' ), '4.0.13', true ); |
| 106 | + wp_register_style( 'merchant-select2', MERCHANT_URI . 'assets/vendor/select2/select2.min.css', array(), '4.0.13' ); | |
| 76 | 107 | |
| 77 | - wp_register_style( 'merchant-select2', MERCHANT_URI . 'assets/vendor/select2/select2.min.css', array(), '4.0.13' ); | |
| 108 | + // Registering stays unconditional so other screens can enqueue the handles; the | |
| 109 | + // enqueues below are for Merchant's own screens only. | |
| 110 | + if ( $this->is_merchant_screen() ) { | |
| 78 | 111 | |
| 79 | - if ( ! empty( $page ) && false !== strpos( $page, 'merchant' ) ) { | |
| 112 | + // For settings page only | |
| 113 | + if ( $section === 'settings' ) { | |
| 114 | + wp_enqueue_code_editor( array( 'type' => 'text/css' ) ); // No need to enqueue again for JS. It'll be handled by JS. | |
| 115 | + wp_enqueue_script( 'merchant-settings', MERCHANT_URI . 'assets/js/admin/settings.min.js', array( 'jquery', 'code-editor' ), MERCHANT_VERSION, true ); | |
| 116 | + } | |
| 80 | 117 | |
| 81 | 118 | wp_enqueue_media(); |
| 82 | 119 | |
| 83 | 120 | wp_enqueue_style( 'merchant-admin', MERCHANT_URI . 'assets/css/admin/admin.min.css', array(), MERCHANT_VERSION ); |
| @@ -92,10 +129,12 @@ | ||
| 92 | 129 | |
| 93 | 130 | wp_enqueue_script( 'merchant-admin', MERCHANT_URI . 'assets/js/admin/admin.min.js', array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-core', 'jquery-ui-accordion', 'wp-util' ), MERCHANT_VERSION, true ); |
| 94 | 131 | |
| 95 | 132 | $localized_data = array( |
| 96 | - 'nonce' => wp_create_nonce( 'merchant' ), | |
| 97 | - 'ajax_url' => admin_url( 'admin-ajax.php' ), | |
| 133 | + 'nonce' => wp_create_nonce( 'merchant' ), | |
| 134 | + 'ajax_url' => admin_url( 'admin-ajax.php' ), | |
| 135 | + 'ai_prompt_copy_hint' => esc_html__( 'Click to copy', 'merchant' ), | |
| 136 | + 'ai_prompt_copied_label' => esc_html__( 'Copied!', 'merchant' ), | |
| 98 | 137 | ); |
| 99 | 138 | |
| 100 | 139 | /** |
| 101 | 140 | * Hook 'merchant_admin_localize_script' |
| @@ -107,9 +146,9 @@ | ||
| 107 | 146 | wp_localize_script( 'merchant-admin', 'merchant', $localized_data ); |
| 108 | 147 | |
| 109 | 148 | $module = ( ! empty( $_GET['module'] ) ) ? sanitize_text_field( wp_unslash( $_GET['module'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 110 | 149 | |
| 111 | - if( !empty($module) ) { | |
| 150 | + if ( ! empty( $module ) ) { | |
| 112 | 151 | wp_enqueue_script( 'merchant-admin-preview', MERCHANT_URI . 'assets/js/admin/merchant-preview.min.js', array( 'jquery' ), MERCHANT_VERSION, true ); |
| 113 | 152 | } |
| 114 | 153 | } |
| 115 | 154 | } |
| @@ -130,29 +169,40 @@ | ||
| 130 | 169 | |
| 131 | 170 | /** |
| 132 | 171 | * Add admin body class. |
| 133 | 172 | */ |
| 134 | - public function add_admin_body_class( $classes ) { | |
| 135 | - $page = ( ! empty( $_GET['page'] ) ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 136 | - $module = ( ! empty( $_GET['module'] ) ) ? sanitize_text_field( wp_unslash( $_GET['module'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 173 | + public function add_admin_body_class( $classes ) { | |
| 174 | + if ( ! $this->is_merchant_screen() ) { | |
| 175 | + return $classes; | |
| 176 | + } | |
| 137 | 177 | |
| 138 | - if ( ! empty( $page ) && false !== strpos( $page, 'merchant' ) ) { | |
| 178 | + $module = ( ! empty( $_GET['module'] ) ) ? sanitize_text_field( wp_unslash( $_GET['module'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 179 | + $section = ( ! empty( $_GET['section'] ) ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 139 | 180 | |
| 140 | - if ( ! empty( $module ) ) { | |
| 181 | + if ( ! empty( $module ) ) { | |
| 182 | + return $classes . ' merchant-admin-page-module'; | |
| 183 | + } | |
| 141 | 184 | |
| 142 | - $classes .= ' merchant-admin-page-module'; | |
| 185 | + $section = $section ? 'merchant-admin-page__' . $section : 'merchant-admin-page__dashboard'; | |
| 143 | 186 | |
| 144 | - } else { | |
| 187 | + return $classes . ' merchant-admin-page ' . $section; | |
| 188 | + } | |
| 145 | 189 | |
| 146 | - $classes .= ' merchant-admin-page'; | |
| 190 | + /** | |
| 191 | + * Whether the screen being rendered is one of Merchant's own. | |
| 192 | + * | |
| 193 | + * Exact match, not a substring one: every Merchant screen arrives as | |
| 194 | + * `page=merchant`, and a substring match leaked the admin bundle onto foreign | |
| 195 | + * screens such as `page=merchant-delivery-calendar`, where it hid admin notices. | |
| 196 | + * | |
| 197 | + * @return bool | |
| 198 | + */ | |
| 199 | + private function is_merchant_screen() { | |
| 200 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 201 | + $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; | |
| 147 | 202 | |
| 148 | - } | |
| 149 | - | |
| 150 | - } | |
| 151 | - | |
| 152 | - return $classes; | |
| 203 | + return 'merchant' === $page; | |
| 153 | 204 | } |
| 154 | 205 | } |
| 155 | 206 | |
| 156 | 207 | Merchant_Admin_Loader::instance(); |
| 157 | - | |
| 158 | 208 | } |