it-swarm.com.de

Bearbeiten Sie die Beitragskategorie nach und nach

Nachdem ich einige Beiträge zur Manipulation von Beitragskategorien zu einem bestimmten Zeitpunkt gelesen hatte, wollte ich ein Plugin erstellen, das Beiträge nach einem Datum manipuliert. Meine ursprüngliche Beitragsreferenz stammt aus dem Jahr vor sechs Jahren: " Plugin zum Ändern der Kategorie eines Beitrags basierend auf dem Datum des Beitrags? ", aber ich habe auf mehrere Beiträge zum Thema Manipulation verwiesen:

Die Kategorie wird jedoch nicht entfernt und die neue hinzugefügt:

Code:

function check_if_cat_has_reached_time() {
    // test if term exists and if doesn't return
    $test_term1 = term_exists('Uncategorized', 'category');
    if ($test_term1 !== 0 && $test_term1 !== null) :
        // $default_cat = get_term_by('id', 'Uncategorized', 'category');
        $default_cat = get_cat_ID('uncategorized');
    else :
        return;
    endif;

    // test if term exists and if doesn't return
    $test_term2 = term_exists('failed', 'category');
    if ($test_term2 !== 0 && $test_term2 !== null) :
        $new_cat = get_cat_ID('failed');
    else :
        return;
    endif;

    global $post;

    // the Post ID
    $the_ID = $post->ID;

    // Post creation time in Epoch
    // $post_creation   = get_the_time('U',$the_ID);
    // current time in Epoch
    $current_time = time();

    // two years in Epoch
    $two_years = 31556926*2;

    // post time plus two years
    $post_plus_two = (int)$two_years + (int)get_the_time('U',$the_ID);

    if ($current_time >= $post_plus_two && has_category($default_cat,$the_ID)) :
        wp_remove_object_terms($the_ID, $default_cat, 'category');
        $update_post_cat = array(
            'post_category' => array($new_cat),
        );
        wp_insert_post($update_post_cat);
    endif;
}
add_action('save_post', 'check_if_cat_has_reached_time');

Gibt es einen Grund, warum wp_remove_object_terms() nicht funktioniert? Ich habe dies nach dem Lesen von Bestimmte Kategorie aus einem Beitrag entfernen verwendet.

Meine Fragen sind also:

  • Entferne ich die Kategorie richtig?
  • Aktualisiere ich die Kategorie richtig?
  • Gibt es einen besseren Haken, um Beiträge in einem Plugin zu manipulieren?
  • Gibt es Leistungsprobleme, wenn dies auf einer Site mit mehreren tausend Posts implementiert wird?

BEARBEITEN:

Die folgende Antwort habe ich versucht, in die function.php meines Themas zu implementieren, aber sie funktioniert immer noch nicht. Ich verwende ein Standarddesign mit WP Test . Vor der Funktion stelle ich sicher, dass die Kategorien erstellt werden mit:

function create_foo_category() {
    wp_insert_term(
        'Foo',
        'category',
        array(
            'description'   => 'This is the Foo',
            'slug'          => 'foo'
        )
    );
}
add_action('after_setup_theme', 'create_foo_category');

dann für bar:

function create_bar_category() {
    wp_insert_term(
        'Bar',
        'category',
        array(
            'description'   => 'This is the bar',
            'slug'          => 'bar'
        )
    );
}
add_action('after_setup_theme', 'create_bar_category');

Ich habe versucht, die angegebene Antwort zu manipulieren mit:

function check_if_cat_has_reached_time() {
    global $post; 

    $the_ID = $post->ID;

    if (!wp_is_post_revision($the_ID)) {

    // unhook this function so it doesn't loop infinitely
    remove_action('save_post', 'check_if_cat_has_reached_time');

    // test if term exists and if doesn't return
    $check_default_cat = term_exists('Foo', 'category');
    if ($check_default_cat !== 0 && $check_default_cat !== null) {
        $default_cat = get_cat_ID('foo');
    } else {
        return;
    }

    // test if term exists and if doesn't return
    $check_new_cat = term_exists('Bar', 'category');
    if ($check_new_cat !== 0 && $check_new_cat !== null) {
        $new_cat = get_cat_ID('bar');
    } else {
        return;
    }

    // current time in Epoch
    $current_time = time();

    // two years in Epoch
    $two_years = 31556926*2;

    // post time plus two years
    $post_plus_two = (int)$two_years + (int)get_the_time('U',$the_ID);

    if ($current_time >= $post_plus_two && has_category($default_cat,$the_ID)) {
        wp_remove_object_terms($the_ID, $default_cat, 'category');
        $args = array(
            'ID'            => $the_ID,
            'post_category' => array($new_cat),
        );
        wp_update_post($args);
    }

    // re-hook this function
    add_action('save_post', 'check_if_cat_has_reached_time');
    }
}
add_action('publish_post', 'check_if_cat_has_reached_time');

BEARBEITEN:

Nachdem ich mit ein paar Leuten gesprochen habe, war mir etwas unklar, wozu das oben Genannte gedacht war. Ich versuche, die Posts zu ändern, ohne sie täglich mit etwas wie einem Event zu bearbeiten. Nachdem ich dieses Problem weiter besprochen hatte, wurde mir bewusst, dass ich wp_schedule_event() testen und bearbeiten werde.

Ihre aktuelle Funktion funktioniert ziemlich gut, ist jedoch an einen Post-Update-Hook gebunden, sodass Sie einen Post bearbeiten/aktualisieren müssen, damit er ausgeführt werden kann. Wenn Sie möchten, dass die Posts nach der angegebenen Zeit automatisch geändert werden, müssen Sie ein geplantes Ereignis einrichten. Ich kann mir zwei Möglichkeiten vorstellen, Ihren Zeitplan aufzustellen ...

1. Ein wiederkehrendes Ereignis, das alle (relevante) Posts überprüft

Wir können wp_schedule_event() verwenden, um in bestimmten Intervallen an einem Hook zu laufen:

// a custom hook to schedule
add_action( 'wpse_269529_check_posts', 'wpse_269529_check_posts_cats' );

// make sure the event hasn't been scheduled
if( !wp_next_scheduled( 'wpse_269529_check_posts' ) ) {

    // Schedule the event
    wp_schedule_event( time(), 'daily', 'wpse_269529_check_posts' );
}

Die Parameter für wp_schedule_event() sind (in Reihenfolge); Wann sollte das erste Ereignis ausgeführt werden (wir können einfach time() übergeben, um es von jetzt an auszuführen), wie oft sollten sie ausgeführt werden (entweder "stündlich", "zweimal täglich" oder "täglich") und der Hook, der ausgeführt werden soll. Sie können auch einige Argumente übergeben, aber das brauchen wir nicht.

Wir verwenden auch wp_next_scheduled() , um zu überprüfen, ob die Veranstaltung noch nicht geplant wurde.

Dann brauchen wir die Funktion, die auf diesem Haken läuft. Wir können das verwenden, um alle Posts mit der Kategorie zu durchlaufen, die Sie ersetzen möchten, und diese dann mit der neuen Kategorie zu aktualisieren:

function wpse_269529_check_posts_cats() {

    //categories
    $old_cat = get_cat_ID( 'foo' );
    $new_cat = get_cat_ID( 'bar' );

    // get all posts with the required category
    $args = array( 'posts_per_page' => -1, 'category' => $old_cat );
    $myposts = get_posts( $args );

    // loop through all posts and update with new category
    foreach ( $myposts as $mypost ) {
        $args = array(
            'ID'            => $mypost->ID,
            'post_category' => array( $new_cat ),
        );
        wp_update_post($args);
    }
}

Sie erwähnen Leistung, und dies führt eine Schleife durch all Posts mit der Kategorie, also ist es vielleicht nicht die beste Option ...

2. Eine einzelne geplante Veranstaltung pro Beitrag

Sie können dies mit wp_schedule_single_event() tun und den Zeitplan für die Erstellung von Posts erstellen (beachten Sie, dass dies nur für neue Posts und nicht für vorhandene Posts funktioniert). Sie binden eine Funktion in publish_post ein, die den Zeitplan festlegt:

// runs when a post is published
add_action( 'publish_post', 'wpse_269529_schedule_post_check' );

function wpse_269529_schedule_post_check( $post_id ) {

    // set the time when the event should be scheduled
    $timestamp = strtotime( '+2 years' );

    // Schedule the event
    wp_schedule_single_event( $timestamp, 'wpse_269529_check_post', array( $post_id ) );    
}

Da wir das jetzt an publish_post angehängt haben, können wir die Beitrags-ID an das geplante Ereignis übergeben und diesen Beitrag basierend darauf aktualisieren (denken Sie daran, die Anzahl der Parameter für den Aktions-Hook für unsere ID auf "1" zu setzen ):

// a custom hook to schedule
add_action( 'wpse_269529_check_post', 'wpse_269529_check_post_cats', 10, 1 );

// replace post categories
function wpse_269529_check_post_cats( $post_id ) {

    //categories
    $old_cat = get_cat_ID( 'foo' );
    $new_cat = get_cat_ID( 'bar' );

    // check for the old category
    if ( has_category( $old_cat, $post_id ) ) {
        // update post with new category
        $args = array(
            'ID'            => $post_id,
            'post_category' => array( $new_cat ),
        );
        wp_update_post($args);
    }
}

Sie können eine Kombination aus beidem verwenden und alle vorhandenen Beiträge zur Aktivierung des Plugins oder Themas durchlaufen (oder etwas anderes, je nachdem, wann, warum und wie Sie dies tun). Anschließend können Sie ein Update pro Beitrag für alle neuen Beiträge planen.

1
Cai

Der Hook save_post übergibt die ID des Posts an seine Rückruffunktion, sodass get_the_ID() nicht verwendet werden muss.

Wenn Sie wp_insert_post() verwenden, wird jedes Mal, wenn Sie einen Beitrag speichern, ein neuer Beitrag in die Datenbank eingefügt. Verwenden Sie stattdessen wp_update_post():

function check_if_cat_has_reached_time($post_id) {
    if ( ! wp_is_post_revision( $post_id ) ){

        // unhook this function so it doesn't loop infinitely
        remove_action('save_post', 'check_if_cat_has_reached_time');

        // test if term exists and if doesn't return
        $check_default_cat = term_exists('Uncategorized', 'category');
        if ($check_default_cat !== 0 && $check_default_cat !== null) {
            $default_cat = get_cat_ID('uncategorized');
        } else {
            return;
        }

        // test if term exists and if doesn't return
        $check_new_cat = term_exists('failed', 'category');
        if ($check_new_cat !== 0 && $check_new_cat !== null) {
            $new_cat = get_cat_ID('failed');
        } else {
            return;
        }

        // post time plus two years
        $post_plus_two = strtotime('+2 years') + strtotime(get_the_date('Y-M-d',$post_id));

        if (strototime(date('Y-M-d')) >= $post_plus_two && has_category($default_cat,$post_id)) {
            wp_remove_object_terms($post_id, $default_cat, 'category');
            $args = array(
                'ID' => $post_id,
                'post_category' => array($new_cat),
            );
            wp_update_post($args);
        }

        // re-hook this function
        add_action('save_post', 'check_if_cat_has_reached_time');
    }
}
add_action('publish_post', 'check_if_cat_has_reached_time');

Der remove_action-Teil ist wichtig, da wp_update_post bei jedem Aufruf einen save_post-Hook auslöst. Daher ist es möglich, eine Endlosschleife zu erstellen.

1
Jack Johansson