Manipular categoria pós-hora

4

Depois de ler várias postagens relacionadas à manipulação de categorias de postagens com um determinado tempo, eu queria criar um plug-in que manipulasse postagens após uma data. Minha referência original é de seis anos atrás: " Plugin para alterar a categoria de um post com base na sua data de publicação? " mas referenciei vários posts relacionados à manipulação:

No entanto, não está removendo a categoria e adicionando a nova:

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

Existe uma razão pela qual wp_remove_object_terms() não funciona? Eu usei isso depois de ler Remover categoria específica de uma postagem .

Então, minhas perguntas são:

  • Estou removendo a categoria corretamente?
  • Estou atualizando a categoria corretamente?
  • Existe um gancho melhor para manipular postagens em um plug-in?
  • Haveria algum problema de desempenho se isso fosse implementado em um site com milhares de postagens?

EDITAR:

A resposta abaixo eu tentei implementar no function.php do meu tema, mas ainda não funciona. Estou usando um tema padrão com o Teste WP . Antes da função, certifico-me de criar as categorias com:

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

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

Eu tentei manipular a resposta fornecida com:

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

EDITAR:

Depois de conversar com algumas pessoas, acho que não ficou claro para que serve o objetivo pretendido. Eu estou olhando para modificar as mensagens sem realmente entrar nelas com algo como um evento diário. Depois de discutir esse assunto mais adiante, tomei conhecimento de wp_schedule_event() que vou testar e editar .

    
por DᴀʀᴛʜVᴀᴅᴇʀ 08.06.2017 / 17:18

2 respostas

1

Sua função atual funciona muito bem, mas está ligada a um gancho post update, então você precisa realmente editar / atualizar um post para ele rodar. Se você quiser que as postagens sejam modificadas automaticamente após o tempo especificado, será necessário configurar um evento programado. Posso pensar em duas maneiras de configurar sua agenda ...

1. Um evento recorrente que verifica todas mensagens (relevantes)

Podemos usar wp_schedule_event() para executar em um gancho em intervalos especificados:

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

Os parâmetros para wp_schedule_event() são (em ordem); quando o primeiro evento deve ser executado (podemos apenas passar time() para executá-lo a partir de agora), com que frequência eles devem ser executados (um de cada "horário", "twicedaily" ou "diário") e o hook para executar. Você também pode passar alguns argumentos, mas não precisamos disso.

Também usamos wp_next_scheduled() para verificar se o evento ainda não foi agendado.

Em seguida, precisamos da função que é executada nesse gancho. Podemos usar isso para percorrer todas as postagens com a categoria que você deseja substituir e atualizá-las com a nova categoria:

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

Você menciona performance, e isso faz um loop através de todas postagens com a categoria, então talvez não seja a melhor opção ...

2. Um único evento agendado por postagem

Você pode fazer isso com wp_schedule_single_event() e criar a programação na pós-criação (observe que isso só funcionará em posts novos e não existentes). Você conecta uma função a publish_post que definirá a programação:

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

Agora, porque colocamos isso em publish_post , podemos passar a ID do post para o evento agendado e atualizar post baseado nisso (lembre-se de definir o número de parâmetros no gancho de ação como "1" para nosso 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);
    }
}

Você pode usar uma combinação dos dois e percorrer todas as postagens existentes no plug-in ou na ativação do tema (ou outra coisa, dependendo de quando e por quê), e agendar uma atualização por postagem para todas as novas postagens .

    
por Cai 20.06.2017 / 17:05
1

O save_post hook passa o ID da postagem para sua função de retorno de chamada, portanto, não é necessário usar get_the_ID() .

Se você usar wp_insert_post() , uma nova postagem será inserida no banco de dados toda vez que você salvar uma postagem. Em vez disso, use 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');

A parte remove_action é importante, pois wp_update_post aciona save_post hook toda vez que é chamado, portanto é possível criar um loop infinito.

    
por Jack Johansson 13.06.2017 / 22:32