web-dev-qa-db-de.com

add_action Hook für komplett neuen Post?

publish_post Wird ausgeführt, wenn ein Beitrag veröffentlicht oder bearbeitet wird und sein Status "veröffentlicht" lautet. Argumente für Aktionsfunktionen: Beitrags-ID.

- Plugin API Dokumentation

Ich habe den Publish_post-Hook zu einem WordPress-Plugin hinzugefügt, das ich schreibe. Die vom Hook selbst aufgerufene Funktion soll die Kategorien mehrerer Posts mit der Funktion wp_update_post ändern.

Dieser Hook funktioniert jedoch nicht, da das Ergebnis der Ausführung von wp_update_post immer 0 ist. Ich vermute, dass die Ausführung von wp_update_post eine weitere Instanz meines Hooks zur Ausführung bringt, da der Post erneut veröffentlicht wird ... was meines Erachtens das zur Folge hat "... oder wenn es bearbeitet wurde und sein Status" veröffentlicht "ist" der obigen Anweisung.

Gibt es einen anderen Action-Hook, den ich verwenden kann und der nur aufgerufen wird, wenn der hinzugefügte Beitrag komplett neu und nicht bearbeitet ist?

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

Ich habe vorerst auf die Verwendung des Hooks "wp_insert_post" umgestellt. Mit der Funktion "wp_set_post_categories" kann ich die Kategorien der Posts jedoch nicht ändern.

Ich verstehe, dass ich diesen Code wahrscheinlich aktualisieren muss, damit er die vorhandenen Kategorien des Posts berücksichtigt und nur die vom Plugin angegebenen ändert, aber im Moment ist es wirklich nur ein 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

Die zielgenaue Erstellung neuer Posts ist tatsächlich schwieriger als es scheint. Technisch gibt es mehrere Möglichkeiten, wie Posts erstellt oder aktualisiert werden können, und es gibt viele nicht so offensichtliche Dinge, die auch technisch relevant sind (zum Beispiel Revisionen).

WordPress bietet dynamische Hooks, die nicht nur die Post-Erstellung verfolgen, sondern auch, was es war und was es wurde. Siehe Nach Statusübergängen im Codex.

5
Rarst

Ich habe den WordPresss-Kern ausführlich gelesen und alles ausprobiert. wp_transition_post_status(), new_to_publish(), new_{post_type}(), wp_insert_post().

All dies ist schließlich unzuverlässig.

wp_transition_post_status() ist nicht zuverlässig, da der neue Status "Publizieren" der Standardstatus sowohl für das Erstellen neuer als auch für das Aktualisieren vorhandener Beiträge ist. Der alte Status ist nicht zuverlässig, um zu definieren, was ein neuer Beitrag ist und was nicht, da er Entwurf, automatischer Entwurf, Veröffentlichung usw. sein kann.

new_to_publish() funktioniert nicht für benutzerdefinierte Beitragstypen.

new_{post_type} übergibt nur $ post als Parameter, und Sie können nicht wissen, ob es neu ist oder ob ein vorhandener aktualisiert wird

wp_insert_post() hat einen $ update-Parameter, der TRUE sein sollte, wenn vorhandene Posts aktualisiert werden, und FALSE, wenn neue Posts erstellt werden. Er ist jedoch unzuverlässig, da er aufgrund des automatischen Entwurfs TRUE für neue Posts zurückgibt.

Am Ende tat ich Folgendes:

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

Optional können Sie Folgendes tun, wenn Sie Ihre vorhandenen Posts mit dem Meta "check_if_run_once" aktualisieren müssen, damit der obige Code nicht für vorhandene Posts ausgeführt wird, die vor dem Hinzufügen dieser Funktion erstellt wurden:

/**
*   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

Dies ist für mich sinnvoller als das Befolgen der Dokumentation (WP 3.3). Ich erhalte einen Transition_post_status-Hook-Aufruf, bei dem $ new_status auf "Auto-Draft" gesetzt ist, wenn Sie einen neuen Beitrag erstellen.

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