base || $screen->is_block_editor() ) {
return;
}
$entry = self::entry_for_current_post();
if ( null === $entry ) {
return;
}
printf(
'
',
esc_html( self::message() ),
esc_url( self::compare_url( $entry ) ),
esc_html( self::compare_label() ),
esc_url( self::dismiss_url( $entry ) ),
esc_html( self::dismiss_label() )
);
}
/**
* Hinweis im Block-Editor ueber den Notice-Store von WordPress.
*
* @return void
*/
public static function enqueue_block_editor(): void {
$entry = self::entry_for_current_post();
if ( null === $entry ) {
return;
}
$data = array(
'message' => self::message(),
'actions' => array(
array(
'label' => self::compare_label(),
'url' => self::compare_url( $entry ),
),
array(
'label' => self::dismiss_label(),
'url' => self::dismiss_url( $entry ),
),
),
);
wp_register_script( self::SCRIPT_HANDLE, false, array( 'wp-data', 'wp-dom-ready', 'wp-notices' ), AIVOR_CONTENT_VERSION, true );
wp_enqueue_script( self::SCRIPT_HANDLE );
wp_add_inline_script(
self::SCRIPT_HANDLE,
sprintf(
'( function ( wp, data ) { wp.domReady( function () { wp.data.dispatch( "core/notices" ).createNotice( "info", data.message, { id: "aivor-content-extension", isDismissible: false, actions: data.actions } ); } ); } )( window.wp, %s );',
wp_json_encode( $data )
)
);
}
/**
* Etikett in der Beitragsliste.
*
* @param array $states Bisherige Etiketten.
* @param \WP_Post $post Beitrag.
* @return array
*/
public static function post_state( $states, $post ): array {
$states = is_array( $states ) ? $states : array();
if ( $post instanceof \WP_Post && null !== Extension::comparable_for( $post->ID ) ) {
$states['aivor_extension'] = esc_html__( 'Aivor extension waiting', 'aivor-content-import' );
}
return $states;
}
/**
* Blendet den Hinweis aus; die Revision bleibt im Verlauf.
*
* @return void
*/
public static function handle_dismiss(): void {
$post_id = isset( $_GET['post'] ) ? absint( wp_unslash( $_GET['post'] ) ) : 0;
check_admin_referer( self::DISMISS_ACTION . '_' . $post_id );
if ( ! current_user_can( 'edit_post', $post_id ) ) {
wp_die( esc_html__( 'Sorry, you are not allowed to edit this post.', 'aivor-content-import' ), 403 );
}
$entry = Extension::waiting_for( $post_id );
if ( null !== $entry ) {
Extension::dismiss( $entry['draft_hash'] );
}
wp_safe_redirect( (string) get_edit_post_link( $post_id, 'raw' ) );
exit;
}
/**
* Die wartende Fassung des gerade bearbeiteten Beitrags.
*
* @return array{draft_hash: string, site_hash: string, job_id: int, post_id: int, revision_id: int, description: string, state: string, time: int}|null
*/
private static function entry_for_current_post(): ?array {
$post = get_post();
if ( ! $post instanceof \WP_Post || ! current_user_can( 'edit_post', $post->ID ) ) {
return null;
}
return Extension::comparable_for( $post->ID );
}
/**
* Text des Hinweises.
*
* @return string
*/
private static function message(): string {
return __( 'Aivor has delivered an extended version of this article and saved it as a revision. Nothing changes on your website until you restore it.', 'aivor-content-import' );
}
/**
* Beschriftung des Vergleichs.
*
* @return string
*/
private static function compare_label(): string {
return __( 'Compare and apply', 'aivor-content-import' );
}
/**
* Beschriftung des Ausblendens.
*
* @return string
*/
private static function dismiss_label(): string {
return __( 'Hide notice', 'aivor-content-import' );
}
/**
* Das klassische Revisionsfenster, in 6.8 und 7.1 mit „Diese Revision wiederherstellen".
*
* Bewusst nicht die visuelle Ansicht von 7.1 (post.php?…&revision=): Per
* Link aus dem Block-Editor geoeffnet, renderte sie im Browser-Test danach
* nicht mehr (2026-10-21, Ursache offen). Ueber „Revisionen" in der
* Seitenleiste funktioniert sie und wird ebenfalls als Uebernahme erkannt.
*
* @param array{revision_id: int} $entry Fassung.
* @return string
*/
private static function compare_url( array $entry ): string {
return add_query_arg( 'revision', $entry['revision_id'], admin_url( 'revision.php' ) );
}
/**
* Adresse zum Ausblenden mit Nonce.
*
* Bewusst nicht wp_nonce_url(): Die escaped „&" zu „&", und der
* Block-Editor setzt die Adresse unveraendert als Link.
*
* @param array{post_id: int} $entry Fassung.
* @return string Unescaped, fuer HTML durch esc_url().
*/
private static function dismiss_url( array $entry ): string {
return add_query_arg(
array(
'action' => self::DISMISS_ACTION,
'post' => $entry['post_id'],
'_wpnonce' => wp_create_nonce( self::DISMISS_ACTION . '_' . $entry['post_id'] ),
),
admin_url( 'admin-post.php' )
);
}
}