base, array( 'plugins', 'plugins-network' ), true ) ) { return; } if ( self::is_manager_active() ) { return; } if ( ! current_user_can( 'install_plugins' ) ) { return; } if ( '1' === get_user_meta( get_current_user_id(), self::DISMISS_KEY, true ) ) { return; } $dismiss_url = wp_nonce_url( add_query_arg( self::DISMISS_ARG, 1 ), self::DISMISS_ACTION ); echo '

' . wp_kses( self::message(), array( 'a' => array( 'href' => true ) ) ) . ' ' . esc_html__( 'Dismiss', 'robotstxt-mediaaudit' ) . '' . '

'; } /** * Renders the permanent inline notice for the Settings pages (not dismissible). * * Used on both the site Settings page and the Network Settings page. * * @return void */ public static function render_settings_notice(): void { if ( self::is_manager_active() ) { return; } echo '
' . '

' . wp_kses( self::message(), array( 'a' => array( 'href' => true ) ) ) . '

' . '
'; } /** * Handles the dismiss link: verifies the nonce, stores the dismissal (PRG). * * Also clears a stored dismissal once Manager is active again, so the * notice returns if Manager is ever removed. * * @return void */ public static function handle_dismiss(): void { $user_id = get_current_user_id(); $dismissed = $user_id && get_user_meta( $user_id, self::DISMISS_KEY, true ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- presence check only; state changes require the nonce below. if ( ! isset( $_GET[ self::DISMISS_ARG ] ) && ! $dismissed ) { return; } if ( self::is_manager_active() ) { if ( $dismissed ) { delete_user_meta( $user_id, self::DISMISS_KEY ); } return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- no state change without the nonce check below. if ( ! isset( $_GET[ self::DISMISS_ARG ] ) ) { return; } if ( ! current_user_can( 'install_plugins' ) ) { return; } check_admin_referer( self::DISMISS_ACTION ); update_user_meta( $user_id, self::DISMISS_KEY, '1' ); wp_safe_redirect( remove_query_arg( array( self::DISMISS_ARG, '_wpnonce' ) ) ); exit; } /** * Builds the shared notice message (translation with a link placeholder). * * The result must be passed through wp_kses() at output time. * * @return string Unescaped message HTML. */ private static function message(): string { return sprintf( /* translators: %s: Manager plugin page URL. */ __( 'To receive plugin updates, the plugin Manager (by ROBOTSTXT) must be installed and active.', 'robotstxt-mediaaudit' ), esc_url( self::MANAGER_URL ) ); } }