web-dev-qa-db-fra.com

Manipuler une catégorie de message après le temps

Après avoir lu plusieurs articles sur la manipulation des articles après un certain temps, je voulais créer un plug-in qui manipulerait les articles après une date donnée. La référence de mon article original date d'il y a six ans: " Plugin pour changer la catégorie d'un article en fonction de sa date de publication? " mais j'ai référencé plusieurs articles concernant la manipulation:

Cependant, il ne s'agit pas de supprimer la catégorie et d'ajouter la nouvelle:

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');

Y a-t-il une raison pour laquelle wp_remove_object_terms() ne fonctionne pas? Je l'ai utilisé après avoir lu Supprimer une catégorie spécifique d'un message .

Donc mes questions sont:

  • Est-ce que je supprime correctement la catégorie?
  • Est-ce que je mets à jour la catégorie correctement?
  • Y a-t-il un meilleur hook pour manipuler les posts dans un plugin?
  • Y aurait-il des problèmes de performances si cela était implémenté sur un site contenant plusieurs milliers de publications?

EDIT:

La réponse ci-dessous que j'ai essayé d'implémenter dans le fichier function.php de mon thème mais cela ne fonctionne toujours pas. J'utilise un thème par défaut avec WP Test . Avant la fonction, je m'assure de créer les catégories avec:

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');

puis pour 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');

J'ai essayé de manipuler la réponse fournie avec:

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');

EDIT:

Après avoir parlé à quelques personnes, je pense qu’il n’était pas clair quel était le but recherché ci-dessus. Je cherche à modifier les posts sans les aborder tous les jours avec une sorte d'événement. Après avoir discuté plus en détail de cette question, j’ai été mis au courant de wp_schedule_event() que je vais tester et éditer.

Votre fonction actuelle fonctionne plutôt bien, mais elle est reliée à un crochet de post-mise à jour. Vous devez donc éditer/mettre à jour une publication pour qu'elle soit exécutée. Si vous souhaitez que les publications soient modifiées automatiquement après l'heure spécifiée, vous devez configurer un événement planifié. Je peux penser à deux façons de configurer votre emploi du temps ...

1. Un événement récurrent qui vérifie all (pertinent) posts

Nous pouvons utiliser wp_schedule_event() pour exécuter un hook à des intervalles spécifiés:

// 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' );
}

Les paramètres pour wp_schedule_event() sont (dans l’ordre); lorsque le premier événement doit s'exécuter (nous pouvons simplement passer à time() pour l'exécuter à partir de maintenant), à quelle fréquence ils doivent s'exécuter (l'un des choix suivants: "toutes les heures", "tous les deux jours" ou "tous les jours"), et le crochet pour s'exécuter. Vous pouvez également transmettre des arguments, mais nous n'en avons pas besoin.

Nous utilisons également wp_next_scheduled() pour vérifier que l'événement n'a pas déjà été planifié.

Ensuite, nous avons besoin de la fonction qui fonctionne sur ce crochet. Nous pouvons l'utiliser pour parcourir tous les articles de la catégorie que vous souhaitez remplacer, puis les mettre à jour avec la nouvelle catégorie:

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);
    }
}

Vous parlez de performance, et cela parcourt une boucle de all posts avec la catégorie, alors peut-être que ce n’est pas la meilleure option ...

2. Un seul événement programmé par message

Vous pouvez le faire avec wp_schedule_single_event() , et créer le programme lors de la création d’un article (notez que cela ne fonctionnera que sur les nouveaux articles et non sur ceux existants). Vous accrochez une fonction à publish_post qui définira la planification:

// 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 ) );    
}

Maintenant, parce que nous avons accroché cela à publish_post , nous pouvons passer l'ID de publication à l'événement planifié et mettre à jour cette publication en fonction de cela (n'oubliez pas de définir le nombre de paramètres du crochet d'action sur "1" pour notre ID ):

// 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);
    }
}

Vous pouvez utiliser une combinaison des deux et parcourir toutes les publications existantes sur l'activation d'un plugin ou d'un thème (ou quelque chose d'autre en fonction du moment, du pourquoi et de la façon dont vous le faites), puis planifier une mise à jour par publication pour toutes les nouvelles publications.

1
Cai

Le hook save_post transmet l'ID de la publication à sa fonction de rappel. Il n'est donc pas nécessaire d'utiliser get_the_ID().

Si vous utilisez wp_insert_post(), une nouvelle publication sera insérée dans la base de données chaque fois que vous enregistrez une publication. Utilisez plutôt 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');

La partie remove_action est importante car wp_update_post déclenche le hook save_post à chaque appel, il est donc possible de créer une boucle infinie.

1
Jack Johansson