mirror of
https://github.com/Heretek-AI/heretek-control-core.git
synced 2026-10-12 02:03:55 +00:00
feat(redirects): suggest-only redirects on delete-post + slug change
Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
70a4dc6353
commit
102a323656
@@ -763,6 +763,16 @@ class EMCP_Tools_Content_Abilities {
|
||||
$emcp_before = array( 'fields' => $emcp_bf, 'meta' => $emcp_bm, 'terms' => $emcp_bt );
|
||||
}
|
||||
|
||||
// A slug change on a published post kills its old permalink — capture it
|
||||
// (before the update) for a suggested redirect.
|
||||
$emcp_slug_old_url = '';
|
||||
if ( ! empty( $input['slug'] )
|
||||
&& isset( $postarr['post_name'] )
|
||||
&& $postarr['post_name'] !== $post->post_name
|
||||
&& 'publish' === $post->post_status ) {
|
||||
$emcp_slug_old_url = (string) get_permalink( $post_id );
|
||||
}
|
||||
|
||||
$res = wp_update_post( wp_slash( $postarr ), true );
|
||||
if ( is_wp_error( $res ) ) {
|
||||
return $res;
|
||||
@@ -789,6 +799,9 @@ class EMCP_Tools_Content_Abilities {
|
||||
if ( $warnings ) {
|
||||
$result['warnings'] = $warnings;
|
||||
}
|
||||
if ( '' !== $emcp_slug_old_url ) {
|
||||
$result = $this->with_redirect_suggestion( $result, $emcp_slug_old_url, 'slug-changed', $post_id );
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -842,6 +855,8 @@ class EMCP_Tools_Content_Abilities {
|
||||
$force = ! empty( $input['force'] );
|
||||
$has_rec = class_exists( 'EMCP_Tools_Change_Recorder' );
|
||||
$target = trim( (string) get_the_title( $post_id ) . ' (#' . $post_id . ')' );
|
||||
// The now-dead URL, captured before deletion, for a suggested redirect.
|
||||
$old_url = (string) get_permalink( $post_id );
|
||||
|
||||
if ( $force ) {
|
||||
// Snapshot the whole post BEFORE deleting so it can be re-inserted.
|
||||
@@ -850,13 +865,38 @@ class EMCP_Tools_Content_Abilities {
|
||||
if ( $has_rec && $res ) {
|
||||
EMCP_Tools_Change_Recorder::record_post_delete( $post_id, $snapshot, true, sprintf( 'Deleted post #%d', $post_id ), $target );
|
||||
}
|
||||
return array( 'success' => (bool) $res, 'post_id' => $post_id, 'deleted' => 'deleted' );
|
||||
$out = array( 'success' => (bool) $res, 'post_id' => $post_id, 'deleted' => 'deleted' );
|
||||
return $res ? $this->with_redirect_suggestion( $out, $old_url, 'post-deleted', $post_id ) : $out;
|
||||
}
|
||||
$res = wp_trash_post( $post_id );
|
||||
if ( $has_rec && $res ) {
|
||||
EMCP_Tools_Change_Recorder::record_post_delete( $post_id, array(), false, sprintf( 'Trashed post #%d', $post_id ), $target );
|
||||
}
|
||||
return array( 'success' => (bool) $res, 'post_id' => $post_id, 'deleted' => 'trashed' );
|
||||
$out = array( 'success' => (bool) $res, 'post_id' => $post_id, 'deleted' => 'trashed' );
|
||||
return $res ? $this->with_redirect_suggestion( $out, $old_url, 'post-deleted', $post_id ) : $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue a suggested redirect for a now-dead URL and annotate the tool
|
||||
* response. Suggest-only: it never writes a redirect. Safe no-op when the
|
||||
* Redirect Manager is absent.
|
||||
*
|
||||
* @param array $out The tool response to annotate.
|
||||
* @param string $old_url The dead permalink.
|
||||
* @param string $reason 'post-deleted' | 'slug-changed'.
|
||||
* @param int $post_id The source post.
|
||||
* @return array
|
||||
*/
|
||||
private function with_redirect_suggestion( array $out, string $old_url, string $reason, int $post_id ): array {
|
||||
if ( '' === $old_url || ! class_exists( 'EMCP_Tools_Redirect_Abilities' ) ) {
|
||||
return $out;
|
||||
}
|
||||
EMCP_Tools_Redirect_Abilities::push_suggestion( $old_url, $reason, $post_id );
|
||||
$out['redirect_suggestion'] = array(
|
||||
'old_url' => $old_url,
|
||||
'message' => __( 'This URL is now dead — call create-redirect to point it somewhere so visitors and search engines do not hit a 404.', 'emcp-tools' ),
|
||||
);
|
||||
return $out;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
@@ -48,6 +48,16 @@ class RedirectAbilitiesTest extends \PHPUnit\Framework\TestCase {
|
||||
$this->assertSame( '/old-a', $q[ count( $q ) - 1 ]['old_path'] );
|
||||
}
|
||||
|
||||
public function test_push_suggestion_caps_queue() {
|
||||
for ( $i = 0; $i < 60; $i++ ) {
|
||||
EMCP_Tools_Redirect_Abilities::push_suggestion( '/p' . $i, 'post-deleted', $i );
|
||||
}
|
||||
$q = get_option( 'emcp_tools_redirect_suggestions', array() );
|
||||
$this->assertCount( 50, $q );
|
||||
// FIFO: the oldest were dropped, the newest kept.
|
||||
$this->assertSame( '/p59', $q[ count( $q ) - 1 ]['old_path'] );
|
||||
}
|
||||
|
||||
public function test_push_suggestion_ignores_root_and_empty() {
|
||||
EMCP_Tools_Redirect_Abilities::push_suggestion( '/', 'post-deleted', 1 );
|
||||
EMCP_Tools_Redirect_Abilities::push_suggestion( '', 'post-deleted', 2 );
|
||||
|
||||
Reference in New Issue
Block a user