current_conflict(); if ( null === $conflict ) { return; } $message = sprintf( /* translators: %s: name of the detected SEO plugin. */ __( 'Acez SEO AI detected an active SEO plugin (%s). To avoid duplicate meta tags, Acez SEO AI\'s own meta tags and canonical URL have been automatically disabled.', 'acez-seo' ), $conflict ); $override_link = ''; if ( null !== ConflictOverrideRegistry::for_active_conflict() ) { $override_link = sprintf( ' %2$s', esc_url( admin_url( 'admin.php?page=acez-seo&tab=settings' ) ), esc_html__( 'Want to force your own Open Graph/Twitter Cards anyway? →', 'acez-seo' ) ); } printf( '

%2$s%3$s

', esc_attr( $conflict ), esc_html( $message ), wp_kses( $override_link, KsesTags::link() ) ); } public function enqueue(): void { if ( null === $this->current_conflict() ) { return; } wp_enqueue_script( 'acez-seo-conflict-notice', ACEZ_SEO_URL . 'assets/js/conflict-notice.js', array(), ACEZ_SEO_VERSION, true ); wp_localize_script( 'acez-seo-conflict-notice', 'AcezSeoConflictNotice', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'action' => self::AJAX_ACTION, 'nonce' => wp_create_nonce( self::AJAX_ACTION ), ) ); } public function handle_dismiss(): void { check_ajax_referer( self::AJAX_ACTION, 'nonce' ); if ( ! current_user_can( 'activate_plugins' ) ) { wp_die( '', 403 ); } $conflict = isset( $_POST['conflict'] ) ? sanitize_text_field( wp_unslash( $_POST['conflict'] ) ) : ''; if ( '' !== $conflict ) { $dismissed = $this->dismissed_conflicts(); $dismissed[] = $conflict; update_user_meta( get_current_user_id(), self::DISMISSED_META_KEY, array_values( array_unique( $dismissed ) ) ); } wp_die(); } private function current_conflict(): ?string { $conflict = SeoPluginDetector::detect(); if ( null === $conflict || ! current_user_can( 'activate_plugins' ) ) { return null; } return in_array( $conflict, $this->dismissed_conflicts(), true ) ? null : $conflict; } /** * @return array */ private function dismissed_conflicts(): array { // NOT `(array) get_user_meta(...)` — when the meta key doesn't exist // yet, get_user_meta() with $single=true returns '' (empty string, // WP's documented "not found" value), and casting THAT to an array // gives array( '' ) (PHP wraps a non-empty scalar in a one-element // array), not an empty array — silently seeding every fresh user's // dismissal list with a bogus empty-string entry. $stored = get_user_meta( get_current_user_id(), self::DISMISSED_META_KEY, true ); return is_array( $stored ) ? $stored : array(); } }