Manipular la categoría de la publicación una y otra vez

4

Después de leer varias publicaciones sobre la manipulación de la categoría de publicaciones con un tiempo determinado, quería crear un complemento que manipulara las publicaciones después de una fecha. Mi referencia original a la publicación es de hace seis años: " ¿Complemento para cambiar la categoría de una publicación según su fecha de publicación? ", pero he mencionado varias publicaciones relacionadas con la manipulación:

Sin embargo, no está eliminando la categoría y agregando una nueva:

Código:

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

¿Hay alguna razón por la cual wp_remove_object_terms() no funciona? Utilicé esto después de leer Eliminar una categoría específica de una publicación .

Así que mis preguntas son:

  • ¿Estoy eliminando la categoría correctamente?
  • ¿Estoy actualizando la categoría correctamente?
  • ¿Hay un mejor gancho para manipular las publicaciones en un complemento?
  • ¿Habría problemas de rendimiento si esto se implementara en un sitio que tenía varios miles de publicaciones?

EDIT:

La siguiente respuesta que he intentado implementar en la función de mi tema.php pero todavía no funciona. Estoy usando un tema predeterminado con WP Test . Antes de la función, me aseguro de crear las categorías con:

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

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

Intenté manipular la respuesta proporcionada con:

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:

Después de hablar con algunas personas, creo que no estaba claro para qué servía el propósito anterior. Estoy buscando modificar las publicaciones sin realmente entrar en ellas con algo como un evento diario. Después de discutir este tema más a fondo, me informaron sobre wp_schedule_event() que voy a probar y editar. .

    
pregunta DᴀʀᴛʜVᴀᴅᴇʀ 08.06.2017 - 17:18

2 respuestas

1

Su función actual funciona bastante bien, pero está conectada a un enlace de actualización por lo que necesita editar / actualizar una publicación para que se ejecute. Si desea que las publicaciones se modifiquen automáticamente después de la hora especificada, deberá configurar un evento programado. Puedo pensar en dos formas de configurar tu horario ...

1. Un evento recurrente que verifica todas las publicaciones (relevantes)

Podemos usar wp_schedule_event() para ejecutar un gancho a intervalos específicos:

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

Los parámetros para wp_schedule_event() son (en orden); cuando debe ejecutarse el primer evento (solo podemos pasar time() para ejecutarlo desde ahora), con qué frecuencia deben ejecutarse (uno de "por hora", "twicedaily" o "diario") y el gancho para ejecutar. También puedes pasar algunos argumentos, pero no necesitamos eso.

También usamos wp_next_scheduled() para verificar que el evento no haya sido programado.

Entonces necesitamos la función que se ejecuta en ese gancho. Podemos usar eso para recorrer todas las publicaciones con la categoría que desea reemplazar, y luego actualizarlas con la nueva categoría:

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

Mencionas el rendimiento, y esto hace un recorrido por todas publicaciones con la categoría, por lo que quizás no sea la mejor opción ...

2. Un solo evento programado por publicación

Puedes hacerlo con wp_schedule_single_event() y crear la programación en la creación de la publicación (nota que solo funcionará en nuevos puestos y no existentes sin embargo). Engancha una función a publish_post que establecerá la programación:

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

Ahora, debido a que lo conectamos a publish_post , podemos pasar el ID de publicación al evento programado y actualizarlo publicación basada en eso (recuerde establecer el número de parámetros en el enlace de acción en "1" para nuestra 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);
    }
}

Puede usar una combinación de los dos y recorrer todas las publicaciones existentes en el complemento o la activación del tema (o algo más según cuándo, por qué y cómo lo está haciendo), luego programar una actualización por publicación para todas las nuevas publicaciones. .

    
respondido por el Cai 20.06.2017 - 17:05
1

El gancho save_post pasa el ID de la publicación a su función de devolución de llamada, por lo que no es necesario usar get_the_ID() .

Si usa wp_insert_post() , se insertará una nueva publicación en la base de datos cada vez que guarde una publicación. En su lugar, utilice 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 parte remove_action es importante, ya que wp_update_post dispara save_post engancha cada vez que se llama, por lo tanto, es posible crear un bucle infinito.

    
respondido por el Jack Johansson 13.06.2017 - 22:32

Lea otras preguntas en las etiquetas