'', 'dismissible' => false, 'id' => '', 'additional_classes' => array(), 'attributes' => array(), 'paragraph_wrap' => true, ); $args = wp_parse_args( $args, $defaults ); $args = apply_filters( 'wp_admin_notice_args', $args, $message ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- replicates WordPress core's own wp_admin_notice_args filter for compatibility with code hooking the real core filter. $id = ''; $classes = 'notice'; $attributes = ''; if ( is_string( $args['id'] ) ) { $trimmed_id = trim( $args['id'] ); if ( '' !== $trimmed_id ) { $id = 'id="' . $trimmed_id . '" '; } } if ( is_string( $args['type'] ) ) { $type = trim( $args['type'] ); if ( '' !== $type ) { $classes .= ' notice-' . $type; } } if ( true === $args['dismissible'] ) { $classes .= ' is-dismissible'; } if ( is_array( $args['additional_classes'] ) && ! empty( $args['additional_classes'] ) ) { $classes .= ' ' . implode( ' ', $args['additional_classes'] ); } if ( is_array( $args['attributes'] ) && ! empty( $args['attributes'] ) ) { foreach ( $args['attributes'] as $attr => $val ) { if ( is_bool( $val ) ) { $attributes .= $val ? ' ' . $attr : ''; } elseif ( is_int( $attr ) ) { $attributes .= ' ' . esc_attr( trim( $val ) ); } elseif ( $val ) { $attributes .= ' ' . $attr . '="' . esc_attr( trim( $val ) ) . '"'; } } } if ( false !== $args['paragraph_wrap'] ) { $message = "

$message

"; } $markup = sprintf( '
%4$s
', $id, $classes, $attributes, $message ); return apply_filters( 'wp_admin_notice_markup', $markup, $message, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- replicates WordPress core's own wp_admin_notice_markup filter for compatibility with code hooking the real core filter. } } if ( ! function_exists( 'ao_autoload_values_to_autoload' ) ) { /** * Gets the values that should be considered for autoloading from the options table. * Uses WP 6.6's wp_autoload_values_to_autoload() if available, otherwise falls back to * the pre-6.6 'yes'/'no' autoload values. * * @return string[] */ // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- ao_ is this plugin's established short-form prefix. function ao_autoload_values_to_autoload() { if ( function_exists( 'wp_autoload_values_to_autoload' ) ) { // phpcs:ignore PluginCheck.CodeAnalysis.Compatibility.wp_function_not_compatible_with_requires_wp -- guarded by function_exists(); only reached on WP 6.6+ where this function exists. NOTE: sniff code unconfirmed, pending re-scan verification. return wp_autoload_values_to_autoload(); } return array( 'yes' ); } } if ( ! function_exists( 'ao_admin_notice' ) ) { /** * Outputs an admin notice. Uses WP 6.4's wp_admin_notice() if available, * otherwise falls back to a backport of it. * * @param string $message The notice message (HTML allowed). * @param array $args Optional arguments: type, dismissible, id, additional_classes, attributes, paragraph_wrap. * @return void */ // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- ao_ is this plugin's established short-form prefix. function ao_admin_notice( $message, $args = array() ) { if ( function_exists( 'wp_admin_notice' ) ) { // phpcs:ignore PluginCheck.CodeAnalysis.Compatibility.wp_function_not_compatible_with_requires_wp -- guarded by function_exists(); only reached on WP 6.4+ where this function exists. wp_admin_notice( $message, $args ); return; } do_action( 'wp_admin_notice', $message, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- replicates WordPress core's own wp_admin_notice action for compatibility with code hooking the real core action. echo wp_kses_post( ao_get_admin_notice( $message, $args ) ); } } if ( ! function_exists( 'ao_get_upgrade_url' ) ) { /** * Build a Pro upgrade URL tagged with an `ao_src` attribution label. * * Every in-plugin "Upgrade to Pro" nudge should link out through this * helper rather than hardcoding the pricing URL, so the destination * domain stays in one place and each link is tagged with a static, * human-chosen label identifying which nudge sent the visitor. * * `ao_src` is not a tracking/analytics parameter: it carries no site * URL, user ID, email, license key or plugin version, requires no * JavaScript, network request, cookie or storage, and only reaches the * destination site when the user chooses to click the link. See * docs/ao-src-labels.md for the full list of registered labels. * * @param string $placement Registered label for this nudge, e.g. 'seo-manager-pro-options'. * Must match /^[a-z0-9-]{1,40}$/; an invalid label is silently * dropped and the URL is returned without ao_src. * @param array $args Optional extra query args to merge in (e.g. an existing * plan or product parameter). Never pass tracking parameters * (utm_*, gclid, etc.) here. * @return string Unescaped URL. Callers must wrap the result in esc_url(). */ // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- ao_ is this plugin's established short-form prefix. function ao_get_upgrade_url( string $placement, array $args = array() ) { $url = ADMINOPTIMIZER_UPGRADE_URL; if ( ! empty( $args ) ) { $url = add_query_arg( $args, $url ); } if ( 1 === preg_match( '/^[a-z0-9-]{1,40}$/', $placement ) ) { $url = add_query_arg( array( 'ao_src' => $placement ), $url ); } return $url; } }