add_action hook für komplett neuen post?

11

publish_post Wird ausgeführt, wenn ein Beitrag veröffentlicht wird oder wenn er bearbeitet wird und sein Status "veröffentlicht" ist. Aktionsfunktionsargumente: Post-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 beim Ausführen von wp_update_post immer 0 ist. Ich gehe davon aus, dass das Ausführen von wp_update_post dazu führt, dass eine andere Instanz meines Hooks ausgeführt wird, weil der Beitrag erneut veröffentlicht wird ... was meiner Meinung nach das " bewirkt . ..oder wenn es bearbeitet wird und sein Status "veröffentlicht" " der obigen Aussage ist.

Gibt es einen anderen Action-Hook, den ich verwenden kann, der nur aufgerufen wird, wenn der hinzugefügte Beitrag völlig 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 ... aber ich kann die Funktion wp_set_post_categories immer noch nicht zum Ändern der Kategorien der Posts verwenden.

Ich verstehe, dass ich diesen Code wahrscheinlich aktualisieren muss, damit er die vorhandenen Kategorien des Beitrags berücksichtigt und nur die vom Plugin angegebenen ändert, aber im Moment ist es wirklich nur ein Alpha.

leeand00
quelle
1
@ leeand00 - Können Sie Ihren Code als Aktualisierung Ihrer Antwort veröffentlichen, damit wir besser erkennen können, was korrigiert werden muss?
MikeSchinkel
@ Mike Hier ist das Update!
leeand00
@MikeSchinkel Manchmal, nur weil ich noch keine Gelegenheit hatte, die Antworten auszuprobieren, und ich wollte keine markieren, die keine gute Antwort ist ... aber ich gehe zurück und sehe, was ich tun kann !
leeand00
@MikeSchinkel Okay, ich habe sie aufgeräumt und die besten Antworten ausgewählt. Tut mir leid, ich habe nicht bemerkt, wie ich diesen speziellen StackExchange vernachlässigt habe.
leeand00

Antworten:

17
add_action('new_to_publish', 'your_function');
add_action('draft_to_publish', 'your_function');
add_action('pending_to_publish', 'your_function');
Pippin
quelle
2
Wie wäre es mit der wp_insert_postAktion? core.trac.wordpress.org/browser/tags/3.3.1/wp-includes/…
soulseekah
Aber werden diese erneut ausgeführt, wenn beispielsweise der Status von "Zurück" in "Entwurf" und dann wieder in "Veröffentlicht" geändert wird?
Brandonjp
6

Die gezielte Erstellung neuer Posts ist tatsächlich schwieriger als es scheint. Technisch gesehen gibt es mehrere Möglichkeiten, wie Posts erstellt oder aktualisiert werden können, und es gibt viele nicht so offensichtliche Dinge, die auch technisch Posts sind (z. B. Überarbeitungen).

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

Selten
quelle
4

Ich habe den WordPress-Kern ausgiebig 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 "Veröffentlichen" der Standardstatus sowohl zum Erstellen neuer als auch zum Aktualisieren vorhandener Beiträge ist. Der alte Status ist nicht zuverlässig, um zu definieren, was ein neuer Beitrag ist und was nicht, da es sich um einen Entwurf, einen automatischen Entwurf, eine Veröffentlichung usw. handeln 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 einen vorhandenen aktualisiert

wp_insert_post() haben 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 habe ich das gemacht:

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

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

/**
*   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');
}
Lucas Bustamante
quelle
1

Das funktioniert mehr mit Experimenten als mit dem Befolgen der Dokumente. Dies funktioniert für mich (WP 3.3). Ich erhalte einen Hook-Aufruf für Transition_post_status, 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');
PapaFreud
quelle
1
Dies wird jedes Mal ausgelöst, wenn ein automatischer Entwurf gespeichert wird, dh jede Minute oder so beim Bearbeiten.
Soulseekah
Guter Punkt. In meinem Fall ist dies kein Problem, aber es könnte für andere sein, je nachdem, was Sie getan haben.
PapaFreud
Ich wollte upvoten, aber ich kann noch nicht. Also Requisiten gehen hier, @PapaFreud. Übrigens ist dies jetzt unter codex.wordpress.org/Post_Status_Transitions dokumentiert .
Ana Ban
1
@soulseekah Interessanter Punkt, den Sie angesprochen haben, ich habe dies getestet und auto-draftwird $new_statusbei seiner Erstellung (dh Neu hinzufügen ) nur einmal als Beitrag zugewiesen . Sobald der erste AUTOSAVEVorgang nach 1 Minute $new_statusausgelöst wird , wird der Wert auf aktualisiert draft. Das $old_statusist noch so lange, NULLbis der Beitrag manuell gespeichert oder veröffentlicht wird. Technisch gesehen würde dies also funktionieren und nicht jedes Mal ausgelöst werden, wenn der Editor Ihre Arbeit automatisch speichert. Als zusätzliche Maßnahme könnten Sie , um sicherzustellen , zu prüfen, ob die $old_statusist NULLzu überprüfen ->if ($new_status == "auto-draft" && $old_status === NULL)
Adam
0

Ich fand die beste Option, den Post-Status zu überprüfen, wenn er wp_insert_postaufgerufen wird.

Wenn ein neuer Beitrag erstellt wird, lautet der Ausgangsstatus auto-draft.

if (!function_exists('benyonsFunction')) {
    function benyonsFunction($postId, $post) {
        if ($post->post_status == "auto-draft") {
            error_log('NEW POST!!!');
        }
    }
}

add_action('wp_insert_post', 'benyonsFunction', 10, 2);

Dieses error_log wird immer nur einmal ausgelöst.

Tom Benyon
quelle