Acțiunea add_action pentru articole complet noi în WordPress

1 feb. 2011, 07:47:33
Vizualizări: 43.1K
Voturi: 22

publish_post rulează când un articol este publicat sau când este editat și statusul său este "published". Argumentele funcției de acțiune: ID-ul articolului.

-Documentația API-ului pentru Plugin-uri

Am adăugat hook-ul publish_post într-un plugin WordPress pe care îl dezvolt. Funcția apelată de hook este menită să modifice categoriile mai multor articole folosind funcția wp_update_post.

Totuși, acest hook nu funcționează deoarece rezultatul returnat de wp_update_post este întotdeauna 0. Cea mai bună presupunere a mea este că rularea wp_update_post cauzează o altă instanță a hook-ului meu să ruleze pentru că republicată articolul... ceea ce cred că aduce în discuție partea "...sau dacă este editat și statusul său este "published"" din afirmația de mai sus.

Există vreun alt action-hook pe care îl pot folosi care va fi apelat doar când articolul adăugat este complet nou și nu editat?

<?php
 /* 
 Plugin Name: Plugin pentru Schimbarea Categoriilor
 Plugin URI: http://www.example.com
 Description: Când este creat un articol nou, acest plugin va cauza 
 Version: 0.1
 Author: Eu
 License: GPL2 
?>
<?php
class categoryShifter {
  function shiftCategories($post_ID) {

    $maxNumPostsFirstTeir = 4;

    $first_teir_cat = "Știri Proaspete 1";
    $second_teir_cat = "Știri Ușor Depășite 2";  

    $firephp = FirePHP::getInstance(true);

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

    $firephp->log($post_ID, 'post_ID: ');
    $firephp->trace('urmărire până aici');    

    $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, 'articole obținute:');

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


    // NOTĂ: Pare să funcționeze.
    for($i = sizeof($firstTeirPosts)-1; $i > $maxNumPostsFirstTeir-4; $i--) 
    {
      $newCats = array($second_teir_id);
      $editingId = $firstTeirPosts->ID;
      $result = wp_set_post_categories($editingId, $newCats); /* NOTĂ: Nu funcționează momentan... returnează un array cu $second_teir_id în el. */
      $firephp->log($result, 'Rezultat'); 
    }



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


    $firephp->log('Înainte', 'Înainte'); 
    if(wp_update_post( $my_post ) == 0) {
        $firephp->Error('Eroare Fatală, Articolul nu a fost actualizat', 'eroare');
    }
    $firephp->log('După', 'După');
    */
    return $post_ID;
  }


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

    $cats = get_categories();      

    $whichCatId = "";

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

/* Hook pentru Crearea Articolului */
/* add_action('publish_post', array('categoryShifter','shiftCategories')); */
add_action('wp_insert_post', array('categoryShifter', 'shiftCategories'));
?>

Am trecut la folosirea hook-ului wp_insert_post pentru moment... dar tot nu pot face funcția wp_set_post_categories să modifice categoriile articolelor.

Înțeleg că probabil va trebui să actualizez acest cod astfel încât să țină cont de categoriile existente ale articolului și să modifice doar cele specificate de plugin, dar pentru moment este doar o versiune alfa.

4
Comentarii

@leeand00 - Poți posta codul tău ca o actualizare la răspunsul tău, astfel încât să putem vedea mai bine ce trebuie corectat?

MikeSchinkel MikeSchinkel
1 feb. 2011 07:49:24

@Mike Iată actualizarea!

leeand00 leeand00
1 feb. 2011 08:12:22

@MikeSchinkel Uneori asta se întâmplă doar pentru că nu am avut încă ocazia să testez răspunsurile și nu am vrut să marchez unul care nu este un răspuns bun... dar voi reveni și voi vedea ce pot face!

leeand00 leeand00
1 feb. 2011 18:28:44

@MikeSchinkel Bine, le-am curățat și am selectat cele mai bune răspunsuri, îmi pare rău pentru asta, nu mi-am dat seama cât de neglijat am acest StackExchange anume.

leeand00 leeand00
1 feb. 2011 18:34:37
Toate răspunsurile la întrebare 6
4
22
add_action('new_to_publish', 'your_function');
add_action('draft_to_publish', 'your_function');
add_action('pending_to_publish', 'your_function');
1 feb. 2011 08:50:56
Comentarii

Cum rămâne cu acțiunea wp_insert_post? http://core.trac.wordpress.org/browser/tags/3.3.1/wp-includes/post.php#L2656

soulseekah soulseekah
23 mar. 2012 11:56:58

Dar acestea se vor executa din nou dacă, de exemplu, statusul este schimbat din publicat înapoi la draft și apoi din nou la publicat?

brandonjp brandonjp
27 iul. 2019 19:07:05

@soulseekah Hook-ul wp_insert_post va fi apelat din nou la editarea și salvarea unui articol existent. Testat pe WordPress 5.9. Știu că comentariul tău este din 2012, dar în caz că cineva este curios despre asta.

vee vee
1 feb. 2022 08:32:59

@vee, probabil se creează draft-uri la fiecare salvare.

soulseekah soulseekah
2 feb. 2022 10:43:11
2
22

Am citit în detaliu nucleul WordPress și am încercat tot. wp_transition_post_status(), new_to_publish(), new_{post_type}(), wp_insert_post().

Toate acestea sunt, în final, nesigure.

wp_transition_post_status() nu este sigură deoarece noul status "publish" este statusul implicit atât pentru crearea de postări noi, cât și pentru actualizarea celor existente. Statusul vechi nu este sigur pentru a defini ce este o postare nouă și ce nu, deoarece poate fi draft, auto-draft, publish, etc.

new_to_publish() nu funcționează pentru tipuri de postări personalizate.

new_{post_type} trece doar $post ca parametru și nu poți ști dacă este nou sau actualizează unul existent

wp_insert_post() are un parametru $update care ar trebui să fie TRUE dacă actualizează postări existente și FALSE dacă creează postări noi, dar este nesigur deoarece returnează TRUE pentru postări noi din cauza auto-draft.

Soluție: Utilizarea unei meta pentru postări

Am ajuns să folosesc o meta personalizată pentru postări pe care am numit-o check_if_run_once care va executa o anumită logică doar o singură dată:

/**
*   Faceți ceva când este creată o nouă carte
*/
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')) ) {
        # Postare nouă

        # Faceți ceva aici...

        # Și actualizați meta astfel încât să nu mai ruleze din nou
        update_post_meta( $post_id, 'check_if_run_once', true );
    }
}
add_action( 'wp_insert_post', 'new_book', 10, 3 );

Opțional, dacă trebuie să vă actualizați postările existente cu meta-ul "check_if_run_once", astfel încât să nu ruleze codul de mai sus pentru postările existente create înainte de a adăuga acea funcție, puteți face:

/**
*   Aceasta este o funcție temporară pentru actualizarea postărilor existente cu meta-ul "check_if_run_once"
*   Accesați site-ul dvs. conectat ca administrator și adăugați ?debug la URL.
*/
function temporary_function() {
    if (current_user_can('manage_options')) {
        $posts = get_posts(array(
            'post_type' => 'book',
            'posts_per_page' => -1, // S-ar putea să fie nevoie să paginați acest lucru în funcție de câte postări aveți
            'fields' => 'ids'
        ));
        foreach($posts as $post_id) {
            update_post_meta($post_id, 'check_if_run_once', true);
        }
    }
}
if (isset($_GET['debug'])) {
    add_action('init', 'temporary_function');
}
30 iul. 2018 03:50:24
Comentarii

De ce nu are mai multe voturi pozitive și de ce nu este răspunsul acceptat. Răspunsul acceptat nu explică lucrurile și nu ține cont de faptul că oamenii tind să folosească asta pentru CPT etc..

Bram Hammer Bram Hammer
8 iul. 2021 21:00:47

Mulțumesc frumos, serios. Ce răspuns grozav!

Marco Floriano Marco Floriano
27 feb. 2024 16:16:09
0

Direcționarea precisă a creării unui articol nou este de fapt mai complicată decât pare. Din punct de vedere tehnic, există multiple modalități prin care un articol poate fi creat sau actualizat și există multe aspecte care nu sunt atât de evidente, dar care sunt din punct de vedere tehnic tot articole (de exemplu, reviziile).

WordPress oferă cârlige dinamice care urmăresc nu doar crearea articolului, ci și ce a fost și ce a devenit. Consultă Tranzițiile stării articolului în Codex.

1 feb. 2011 08:51:01
4

Mai mult prin experimentare decât urmărind documentația, această soluție funcționează pentru mine (WP 3.3). Primesc un apel al hook-ului transition_post_status cu $new_status setat la "auto-draft" când creezi un articol nou.

function my_post_new($new_status, $old_status=null, $post=null){
    if ($new_status == "auto-draft"){
        // faci operațiuni aici
    }
}
add_action('transition_post_status', 'my_post_new');
23 mar. 2012 11:38:50
Comentarii

Acest lucru se va declanșa de fiecare dată când un draft automat este salvat, adică cam la fiecare minut în timpul editării.

soulseekah soulseekah
23 mar. 2012 11:54:27

Bun punct. În cazul meu aceasta nu este o problemă, dar ar putea fi pentru alții, în funcție de ceea ce faci.

PapaFreud PapaFreud
23 mar. 2012 12:50:24

am vrut să votez pozitiv, dar încă nu pot. așa că felicitările merg aici, @PapaFreud. apropo, acum acest lucru este documentat la http://codex.wordpress.org/Post_Status_Transitions. din nou, mulțumesc omule

Ana Ban Ana Ban
22 mai 2012 15:30:02

@soulseekah Punct interesant pe care l-ai ridicat, am testat acest lucru și auto-draft este atribuit ca $new_status al unui articol la crearea sa (adică Adăugare Nouă), o singură dată. De îndată ce primul procedeu AUTOSAVE se declanșează după 1 minut, valoarea $new_status este actualizată la draft. $old_status rămâne NULL până când articolul este salvat manual sau publicat. Deci, tehnic, acest lucru ar funcționa și nu s-ar declanșa de fiecare dată când editorul salvează automat munca ta. Ca măsură suplimentară, poți verifica dacă $old_status este NULL pentru a confirma -> if ($new_status == "auto-draft" && $old_status === NULL)

Adam Adam
22 mai 2013 16:57:23
0

Am descoperit că cea mai bună opțiune este să verific starea postului atunci când este apelat wp_insert_post.

Când un post nou este creat, starea inițială este auto-draft.

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

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

Acest error_log se va executa doar o singură dată.

5 feb. 2020 11:49:20
2

Cea mai curată și sigură metodă de a gestiona acest lucru pentru un tip de postare cunoscut este să folosești hook-ul {$new_status}_{$post->post_type} care oferă vechiul status și îl compară cu "publish".

De exemplu, dacă dorești să declanșezi o acțiune atunci când o nouă "pagină" este creată, ai folosi:

add_action( 'publish_page', function( int $post_id, \WP_Post $post, string $old_status ) {
    if ( 'publish' === $old_status ) {
        // Nimic de văzut aici.
        return;
    }
    // Logica de afaceri se pune aici.
}, 10, 3 );
18 feb. 2023 00:46:36
Comentarii

Nu, acest lucru se va declanșa de fiecare dată când o pagină trece de la orice stare la 'publicată', deci se va declanșa de mult mai multe ori decât doar la prima creare.

Christophvh Christophvh
31 mar. 2023 16:42:18

De ce pagina ta ajunge în starea "publicată" de mai multe ori? Odată ce o pagină este publicată, aceasta este live și starea nu se schimbă de obicei decât dacă o muți în "gunoi" pentru a o elimina de pe site.

Mat Lipe Mat Lipe
1 apr. 2023 17:59:21