%s

', wp_kses_post( sprintf( /* translators: %s: Mintall privacy policy URL. */ __( 'If page-view capture is turned on in Mintall Keep, each time a product page is viewed this site sends the visitor\'s browser User-Agent string to Mintall (api.mintall.ai), along with the product\'s Mintall ID, to count visits from AI shopping agents. No IP address or cookies are sent. See the Mintall Privacy Policy.', 'mintall-keep' ), 'https://www.mintall.ai/privacy' ) ) ); wp_add_privacy_policy_content( __( 'Mintall Keep', 'mintall-keep' ), $content ); } /** * Register admin menu under WooCommerce. */ public function register_menu() { add_submenu_page( 'woocommerce', __( 'Mintall Keep', 'mintall-keep' ), __( 'Mintall Keep', 'mintall-keep' ), 'manage_woocommerce', 'mintall-keep', [ $this, 'render_admin_page' ] ); } /** * Render the React admin SPA mount point. */ public function render_admin_page() { echo '
'; } /** * Enqueue admin scripts and styles. */ public function enqueue_scripts( $hook ) { // Main admin SPA. if ( 'woocommerce_page_mintall-keep' === $hook ) { $asset_file = MINTALL_KEEP_PLUGIN_DIR . 'build/index.asset.php'; $assets = file_exists( $asset_file ) ? require $asset_file : [ 'dependencies' => [], 'version' => MINTALL_KEEP_VERSION, ]; wp_enqueue_script( 'mintall-keep-admin', MINTALL_KEEP_PLUGIN_URL . 'build/index.js', $assets['dependencies'], $assets['version'], true ); wp_enqueue_style( 'mintall-keep-admin', MINTALL_KEEP_PLUGIN_URL . 'build/index.css', [ 'wp-components' ], $assets['version'] ); wp_localize_script( 'mintall-keep-admin', 'mintallKeep', [ 'apiBase' => rest_url( 'mintall/v1' ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'adminUrl' => admin_url(), 'adminEmail' => get_option( 'admin_email', '' ), 'appUrl' => MINTALL_APP_URL, 'featureInDevelopment' => MINTALL_FEATURE_IN_DEVELOPMENT, // The runtime constant PHP is actually configured with, so the // frontend can catch a mismatch against MINTALL_EDITION - the // separate compile-time constant baked into this JS bundle by // webpack (see webpack.config.js). The two are set at different // times by different tools reading the same env var name, so // nothing stops them disagreeing; see EditionMismatchBanner. 'edition' => MINTALL_KEEP_EDITION, ] ); } // Product edit metabox. $screen = get_current_screen(); if ( $screen && 'product' === $screen->post_type && 'post' === $screen->base ) { $asset_file = MINTALL_KEEP_PLUGIN_DIR . 'build/product-edit.asset.php'; $assets = file_exists( $asset_file ) ? require $asset_file : [ 'dependencies' => [], 'version' => MINTALL_KEEP_VERSION, ]; wp_enqueue_script( 'mintall-keep-product-edit', MINTALL_KEEP_PLUGIN_URL . 'build/product-edit.js', $assets['dependencies'], $assets['version'], true ); wp_enqueue_style( 'mintall-keep-product-edit', MINTALL_KEEP_PLUGIN_URL . 'build/product-edit.css', [ 'wp-components' ], $assets['version'] ); $product = wc_get_product( get_the_ID() ); wp_localize_script( 'mintall-keep-product-edit', 'mintallKeepProduct', [ 'apiBase' => rest_url( 'mintall/v1' ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'productId' => get_the_ID(), 'productName' => $product ? $product->get_name() : '', ] ); } } /** * Add "Mintall Keep" metabox on product edit screen. */ public function add_product_metabox() { add_meta_box( 'mintall-keep-metabox', __( 'Mintall Keep', 'mintall-keep' ), [ $this, 'render_product_metabox' ], 'product', 'side', 'default' ); } /** * Render metabox content (React mount point). */ public function render_product_metabox( $post ) { echo '
'; } /** * Add Mintall's bulk actions - protect, and enable/disable AI visibility * - to the WooCommerce product list's bulk actions dropdown, for * merchants who work from the native product list rather than the * Mintall Products tab. */ public function register_bulk_actions( $bulk_actions ) { $bulk_actions['mintall_bulk_mint'] = __( 'Protect with Mintall Keep', 'mintall-keep' ); $bulk_actions['mintall_bulk_enable_visibility'] = __( 'Enable AI Visibility (Mintall)', 'mintall-keep' ); $bulk_actions['mintall_bulk_disable_visibility'] = __( 'Disable AI Visibility (Mintall)', 'mintall-keep' ); return $bulk_actions; } /** * Redirect a Mintall bulk selection into the Mintall Keep Products tab. * The selected ids travel in the URL (inside the HashRouter's own path, * so WordPress's own query-arg handling around bulk-action redirects * leaves them alone); Products.tsx picks them up on mount and runs the * matching action - BulkProtectPanel over POST /mint/bulk for protect, or * a direct call to POST /products/visibility for enable/disable - the * same endpoints the in-page checkbox selection uses. */ public function handle_bulk_action( $redirect_to, $action, $post_ids ) { if ( empty( $post_ids ) ) { return $redirect_to; } $ids_param = implode( ',', array_map( 'absint', $post_ids ) ); $url = add_query_arg( 'page', 'mintall-keep', admin_url( 'admin.php' ) ); switch ( $action ) { case 'mintall_bulk_mint': return $url . '#/products?bulk_mint_ids=' . $ids_param; case 'mintall_bulk_enable_visibility': return $url . '#/products?bulk_visibility_ids=' . $ids_param . '&bulk_visibility_enabled=1'; case 'mintall_bulk_disable_visibility': return $url . '#/products?bulk_visibility_ids=' . $ids_param . '&bulk_visibility_enabled=0'; default: return $redirect_to; } } /** * Store-wide notice when the Mintall connection needs re-authorization. * * The backend can no longer sign callbacks for the pubkey this site holds, * so protection is paused until the merchant reconnects. Shown on every * admin page (not just the Mintall screen) so it's actually noticed; clears * automatically once the reconnect re-derives a matching keypair. */ public function reauth_required_admin_notice() { if ( ! current_user_can( 'manage_woocommerce' ) ) { return; } if ( ! Connection_Manager::is_reauth_required() ) { return; } // The Mintall Keep app renders its own top banner; skip this notice there // to avoid a duplicate, but keep it on every other admin screen. $screen = get_current_screen(); if ( $screen && 'woocommerce_page_mintall-keep' === $screen->id ) { return; } $settings_url = admin_url( 'admin.php?page=mintall-keep' ); printf( '

%s %s

', esc_html__( 'Your Mintall Keep store connection needs to be re-authorized.', 'mintall-keep' ), esc_url( $settings_url ), esc_html__( 'Reconnect your store', 'mintall-keep' ) ); } }