Eliminar todos los posts de un tipo de post personalizado de manera eficiente
Estoy buscando una forma segura y rápida de eliminar todos los posts de un tipo de post personalizado. Usar get_posts()
y wp_delete_post()
para cada post devuelto no funciona; no es lo suficientemente rápido debido a la gran cantidad de consultas a la base de datos involucradas (error de timeout).
Preferiblemente, busco ejecutar una única consulta a la base de datos que elimine todos los posts que son de un tipo de post personalizado. ¿Alguna sugerencia?

Puedes eliminar todas las publicaciones mediante $wpdb
DELETE FROM wp_posts WHERE post_type='post_type';
DELETE FROM wp_postmeta WHERE post_id NOT IN (SELECT id FROM wp_posts);
DELETE FROM wp_term_relationships WHERE object_id NOT IN (SELECT id FROM wp_posts)
o usa esta consulta reemplazando {{your CPT}} con tu Tipo de Publicación Personalizado
DELETE a,b,c
FROM wp_posts a
LEFT JOIN wp_term_relationships b
ON (a.ID = b.object_id)
LEFT JOIN wp_postmeta c
ON (a.ID = c.post_id)
WHERE a.post_type = '{{your CPT}}';

esto probablemente funcionaría bien, pero no olvides los conteos de términos en una de las tablas de términos. WordPress debería tener una función para actualizar esto.

los usuarios también tienen conteos de publicaciones en la pantalla de usuarios, no estoy seguro si estos datos se guardan previamente o se calculan al cargar la página.

@JoelM La columna de conteo existe en la tabla de la base de datos wp_term_taxonomy
. Parece que la función que buscas para actualizar el conteo es wp_update_term_count($terms, $taxonomy, false)
o wp_update_term_count_now($terms, $taxonomy)
definida en wp-includes/taxonomy.php
.

Esto ahora puede realizarse con la CLI de WordPress utilizando el comando wp post delete. Una vez que la CLI está instalada, el siguiente comando en la terminal (mientras te encuentras en el directorio raíz de tu sitio) eliminará todas las entradas del tipo mycustomtype
:
wp post delete $(wp post list --post_type='mycustomtype' --format=ids)
Sin SQL directo (*horror*), sin preocuparte por tiempos de espera, y es rápido. Por ejemplo, acabo de eliminar ~2500 entradas en menos de dos minutos.
Para omitir la Papelera y eliminarlas completamente usa --force

Esto funcionó para mí para eliminar ~12k publicaciones. Lo manejó sin problemas. Usa la bandera --force
si quieres omitir la "papelera" y eliminarlos permanentemente.

Puedes eliminar todas las entradas de un tipo de contenido personalizado (custom post type) de varias formas, pero aquí te mostraré cómo hacerlo sin usar consultas SQL. En este ejemplo, nuestro tipo de contenido es producto (product).
$allposts = get_posts( array('post_type'=>'producto','numberposts'=>-1) );
foreach ($allposts as $eachpost) {
wp_delete_post( $eachpost->ID, true );
}

Lee nuevamente la OP: "Usar get_posts()
y wp_delete_post()
para cada publicación devuelta no funciona; no es lo suficientemente rápido debido a la gran cantidad de consultas a la base de datos involucradas (error de tiempo de espera)."
Estás usando las dos funciones que él no quiere usar.

Tienes toda la razón. Pero solo para estar seguros y también eliminar con términos, comentarios y metadatos con recuento en términos. Es el método perfecto. Tal vez podríamos usar cron para ello.

Si has prefijado tu tipo de post CPT y tus taxonomías CPT con algo como 'abc_mi_tipo_post_personalizado' y 'abc_mi_taxonomia', entonces es trivial eliminar todo de la base de datos con dos consultas:
DELETE a,b
FROM $wpdb->posts a
LEFT JOIN $wpdb->postmeta b ON a.ID = b.post_id
WHERE a.post_type LIKE 'abc_%';
DELETE a,b,c
FROM $wpdb->term_taxonomy a
LEFT JOIN $wpdb->term_relationships b ON a.term_taxonomy_id = b.term_taxonomy_id
LEFT JOIN $wpdb->terms c ON a.term_id = c.term_id
WHERE a.taxonomy LIKE 'abc_%'
