it-swarm.com.de

flush_rewrite_rules on save_post Funktioniert beim Speichern des ersten Beitrags nicht

Ich entwickle ein Plugin für meine eigene schnelle Entwicklung, das einen benutzerdefinierten Beitragstyp erstellt. Die 'Liste' für diesen Beitragstyp wird auf einer bestimmten Seite angezeigt, die vom Plugin erstellt und verwaltet wird. Diese Seite kann an einer beliebigen Stelle in der Seitenhierarchie der Site platziert werden, sodass der Slug für die einzelnen Posts aktualisiert werden muss, wenn der Site-Administrator den Speicherort der Listenseite ändert.

Beim Erstellen des Beitragstyps während der init weise ich dem benutzerdefinierten Beitragstyp (der Kürze halber gekürzter Code) die folgenden Umschreiberegeln zu:

$post_type_slug = "/" . get_page_uri( $page_id );
register_post_type( 'post_type_name',
        ... 
        'rewrite'   => array( 'slug' => $post_type_slug, 'with_front' => true),
        ...
      )
);  

Dies scheint perfekt zu funktionieren, um zunächst alles einzurichten. Wenn der Benutzer die Seite "Liste" speichert, führe ich den folgenden Code aus, um die Umschreiberegeln zu aktualisieren:

add_action( 'save_post', array(__CLASS__, 'flush_permalinks'), 2000 );
function flush_permalinks( $post_id ) {
  if($post_id == get_option( $custom_page_id )){
    flush_rewrite_rules(false);
  }
}

Wenn der Benutzer jedoch den Speicherort der Seite ändert, geben die neu aktualisierten Permalinks 404 zurück (obwohl die Listenseite die Links korrekt anzeigt). Aber wenn ich die Seite ein zweites Mal speichere, funktioniert es perfekt! Ich habe versucht, die Priorität der Aktion save_post zu ändern (von 1 auf 2000), aber das scheint keinen Unterschied zu machen. Ich habe auch versucht, die Umschreiberegeln sowohl hart als auch weich zu löschen, aber das ändert nichts am Zwei-Speichern (das erste Speichern ändert nichts an den Umschreiberegeln, aber das zweite tut es).

Irgendwelche Vorschläge, was ich falsch machen könnte?

3
Eric K

Ich weiß, dass dies bereits beantwortet wurde, aber ich hatte das Gefühl, dass es nicht 100% ig klar war, was die eigentliche Lösung war.

Hier ist meine Antwort, um Klarheit zu schaffen.

Er hat recht ... Sie können keine Rewrite-Regeln für save_post löschen, da dieser Aktions-Hook ausgelöst wird, NACHDEM der Aktions-Hook init ausgelöst wurde.

Wie Sie wissen, werden Beitragstypen und Taxonomien im Hook init registriert.

TLDR; Sie können nicht flush_rewrite_rules(); auf save_post Aktionshook.

Es gibt eine Problemumgehung ...

Sie müssen für save_post action hook einen Optionswert auf 1 setzen. Aktivieren Sie dann diese Option für den Wert 1 und löschen Sie die Umschreibregeln für den Aktions-Hook init.

Beispiel:

function mbe_late_init_example() {

    if ( ! $option = get_option( 'my-plugin-flush-rewrite-rules' ) ) {
        return false;
    }

    if ( $option == 1 ) {

        flush_rewrite_rules();
        update_option( 'my-plugin-flush-rewrite-rules', 0 );

    }

    return true;

}

add_action( 'init', 'mbe_late_init_example', 999999 );


function mbe_save_post_example( Int $post_id = null, \WP_Post $post_object = null ) {

    if ( ! $post_id || ! $post_object ) {
        return false;
    }

    # Specific Post Type
    if ( $post_object->post_type != 'my-plugin-settings' ) {
        return false;
    }

    # Specific Post Object (OPTIONAL)
    if ( $post_object->post_name != 'general-settings' ) {
        return false;
    }

    update_option( 'my-plugin-flush-rewrite-rules', 1 );

    return true;

}

add_action( 'save_post', 'mbe_save_post_example', 10, 2 );
3
Michael Ecklund

Ich konnte dieses Problem lösen. Es scheint, dass die Aktion 'save_post' vor der init stattfindet, die den benutzerdefinierten Beitragstyp registriert. Daher wird der Überschreibungs-Slug des Post-Typs vor der Anforderung von flush_rewrite_rules nicht aktualisiert, was im Wesentlichen zu keiner Aktualisierung führt. Dies erklärt auch, warum es funktioniert, wenn der Beitrag ein zweites Mal gespeichert wird, da der Beitragstyp die Möglichkeit hat, seine Umschreiberegeln zu aktualisieren.

Deshalb löse ich das Problem, indem ich meinen Code wie folgt ändere:

add_action( 'save_post', array(__CLASS__, 'flush_permalinks'));
function flush_permalinks( $post_id ) { 
  if($post_id == get_option( $custom_page_id )){
    update_option( 'unique_page_updated_key', 'true');
  }
}

Ich habe dann direkt unter meinem register_post_type den folgenden Code hinzugefügt:

if((bool)get_option( 'unique_page_updated_key' )){
  flush_rewrite_rules(); 
  update_option( 'unique_page_updated_key', 'false');
}

Dies verhindert, dass die Umschreiberegeln für jede einzelne init gelöscht werden.

1
Eric K