web-dev-qa-db-fra.com

add_action hook pour un nouveau message?

publish_post S'exécute lorsqu'un article est publié ou s'il est modifié et si son statut est "publié". Arguments de la fonction d'action: post ID.

- Documentation sur les API de plug-in

J'ai ajouté le hook publish_post à un plugin WordPress en cours d'écriture. La fonction appelée par le hook lui-même est destinée à changer les catégories de plusieurs publications en utilisant la fonction wp_update_post.

Cependant, ce hook ne fonctionne pas car le résultat de l'exécution de wp_update_post est toujours égal à 0. Ma meilleure hypothèse est que l'exécution de wp_update_post entraîne l'exécution d'une autre instance de mon hook car elle republie le message ... ce qui, je pense, entraîne le "... ou s'il est édité et que son statut est" publié "" de la déclaration ci-dessus.

Existe-t-il d'autres actions-hook que je peux utiliser et qui ne seront appelées que lorsque la publication ajoutée est complètement nouvelle et non modifiée?

<?php
 /* 
 Plugin Name: Category Switcher Plugin
 Plugin URI: http://www.example.com
 Description: When a new post is created this plugin will cause the 
 Version: 0.1
 Author: Me
 License: GPL2 
?>
<?php
class categoryShifter {
  function shiftCategories($post_ID) {

    $maxNumPostsFirstTeir = 4;

    $first_teir_cat = "Fresh News Stories 1";
    $second_teir_cat = "Slightly Dated Stories 2";  

    $firephp = FirePHP::getInstance(true);

    $firephp->info('BEGIN: categoryShifter.shiftCategories()');

    $firephp->log($post_ID, 'post_ID: ');
    $firephp->trace('trace to here');    

    $first_teir_id = categoryShifter::getIDForCategory($first_teir_cat, $firephp); 
    $second_teir_id = categoryShifter::getIDForCategory($second_teir_cat, $firephp);

    $firephp->log($first_teir_id, '$first_teir_id');
    $firephp->log($second_teir_id, '$second_teir_id');   

    $qPostArgs = array(
      'numberposts' => 100,
      'order' => 'DESC', 
      'orderby' => 'post_date',
      'post_type' => 'post',
      'post_status' => 'published', 
      'category_name' => $first_teir_cat
    );

    $firstTeirPosts = get_posts($qPostArgs);   
    $firephp->log($firstTeirPosts, 'got posts:');

    $firephp->log(sizeof($firstTeirPosts), 'sizeof');


    // NOTE: This appears to work.
    for($i = sizeof($firstTeirPosts)-1; $i > $maxNumPostsFirstTeir-4; $i--) 
    {
      $newCats = array($second_teir_id);
      $editingId = $firstTeirPosts->ID;
      $result = wp_set_post_categories($editingId, $newCats); /* NOTE: Doesn't work presently... returns an array with the $second_teir_id in it. */
      $firephp->log($result, 'Result'); 
    }



    /*
    $my_post = array();
    $my_post['ID'] = 132;
    $my_post['post_category'] = array($second_teir_id);


    $firephp->log('Before', 'Before'); 
    if(wp_update_post( $my_post ) == 0) {
        $firephp->Error('Fatal Error, Post not updated', 'error');
    }
    $firephp->log('After', 'After');
    */
    return $post_ID;
  }


  function getIDForCategory($cat_name, $logger) {
    $logger->Info("Begin: getIDForCategory()");

    $cats = get_categories();      

    $whichCatId = "";

    foreach($cats as $single_cat) {
      if($single_cat->name == $cat_name) {
       $whichCatId = $single_cat->term_id;
       break;
      }
    }
    $logger->Info("End: getIDForCategory()");
    return (int)$whichCatId;
  }
}

/* Hook Post Creation */
/* add_action('publish_post', array('categoryShifter','shiftCategories')); */
add_action('wp_insert_post', array('categoryShifter', 'shiftCategories'));
?>

Je suis passé au crochet wp_insert_post pour le moment ... mais je ne parviens toujours pas à utiliser la fonction wp_set_post_categories pour changer les catégories des articles.

Je comprends que j’aurai probablement besoin de mettre à jour ce code pour qu’il prenne en compte les catégories existantes de la publication et ne modifie que celles spécifiées par le plug-in, mais pour l’instant ce n’est qu’un alpha.

6
leeand00
add_action('new_to_publish', 'your_function');
add_action('draft_to_publish', 'your_function');
add_action('pending_to_publish', 'your_function');
17
Pippin

La création ciblée d'un nouveau poste est en réalité plus délicate qu'il n'y paraît. Techniquement, il existe plusieurs façons de créer ou de mettre à jour une publication et il y a beaucoup de choses moins évidentes qui sont techniquement également publiées (des révisions par exemple).

WordPress fournit des points d'ancrage dynamiques qui permettent de suivre non seulement la création après publication, mais également ce qu'elle était et ce qu'elle est devenue. Voir Transitions post-statut dans Codex.

5
Rarst

J'ai beaucoup lu le noyau de WordPress et j'ai tout essayé. wp_transition_post_status(), new_to_publish(), new_{post_type}(), wp_insert_post().

Après tout, tous ne sont pas fiables.

wp_transition_post_status() n'est pas fiable car le nouveau statut "publier" est le statut par défaut pour la création de nouveaux messages et la mise à jour de ceux existants. L'ancien statut n'est pas fiable pour définir ce qui est une nouvelle publication et ce qui ne l'est pas car il peut s'agir d'un brouillon, d'un brouillon automatique, d'une publication, etc.

new_to_publish() ne fonctionne pas pour les types de publication personnalisés.

new_{post_type} passe seulement $ post en paramètre, et vous ne pouvez pas savoir s'il s'agit d'un nouveau ou d'une mise à jour d'un existant

wp_insert_post() possède un paramètre $ update qui doit être VRAI si vous mettez à jour des publications existantes et FAUX si vous créez de nouvelles publications, mais il n’est pas fiable car il renvoie VRAI pour les nouvelles publications en raison de la rédaction automatique.

J'ai fini par faire ceci:

/**
*   Do something when a new book is created
*/
function new_book($post_id, $post, $update) {
    if ($post->post_type == 'book' && $post->post_status == 'publish' && empty(get_post_meta( $post_id, 'check_if_run_once' ))) {
        # New Post

        # Do something here...

        # And update the meta so it won't run again
        update_post_meta( $post_id, 'check_if_run_once', true );
    }
}
add_action( 'wp_insert_post', 'new_book', 10, 3 );

Si vous devez mettre à jour vos publications existantes avec la méta "check_if_run_once", vous ne pouvez pas exécuter le code ci-dessus pour les publications existantes créées avant l'ajout de cette fonction:

/**
*   This is a temporary function to update existing posts with the "check_if_run_once" post meta
*   Access your website logged in as admin and add ?debug to the URL.
*/
function temporary_function() {
    if (current_user_can('manage_options')) {
        $posts = get_posts(array(
            'post_type' => 'book'
        ));
        foreach($posts as $post) {
            update_post_meta($post->ID, 'check_if_run_once', true);
        }
    }
}
if (isset($_GET['debug']));
    add_action('init', 'temporary_function');
1
Lucas Bustamante

Mieux vaut expérimenter que suivre la documentation, cela fonctionne pour moi (WP 3.3). Je reçois un appel de hook transition_post_status avec $ new_status défini sur "auto-draft" lorsque vous créez un nouveau message.

function my_post_new($new_status, $old_status=null, $post=null){
    if ($new_status == "auto-draft"){
        // do stuff here
    }
}
add_action('transition_post_status', 'my_post_new');
1
PapaFreud