Panel: fichas por revisar, acciones en bloque, destacar con un clic y borrado de mensajes antiguos
- Escritorio: animales sin foto, sin euskera, sin «Cómo es», sin especie o en proceso desde hace más de N días (configurable). - Listado: acciones en bloque de estado y destacado (en los dos idiomas) y estrella clicable. - Se guarda la fecha del último cambio de estado. - Borrado diario de mensajes del formulario más antiguos que N meses (12 por defecto). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,3 +12,4 @@ require_once __DIR__ . '/gure-ametsa/i18n.php';
|
||||
require_once __DIR__ . '/gure-ametsa/animals.php';
|
||||
require_once __DIR__ . '/gure-ametsa/forms.php';
|
||||
require_once __DIR__ . '/gure-ametsa/api.php';
|
||||
require_once __DIR__ . '/gure-ametsa/admin.php';
|
||||
|
||||
201
wp-content/mu-plugins/gure-ametsa/admin.php
Normal file
201
wp-content/mu-plugins/gure-ametsa/admin.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
/**
|
||||
* Herramientas del panel: fichas por revisar, acciones en bloque, destacar con un clic
|
||||
* y borrado automático de mensajes antiguos.
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Fecha del último cambio de estado (para saber cuánto lleva «en proceso»)
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
$ga_status_changed = function ( $meta_id, $post_id, $meta_key ) {
|
||||
if ( '_ga_estado' === $meta_key ) {
|
||||
update_post_meta( $post_id, '_ga_estado_desde', current_time( 'Y-m-d' ) );
|
||||
}
|
||||
};
|
||||
add_action( 'added_post_meta', $ga_status_changed, 10, 3 );
|
||||
add_action( 'updated_post_meta', $ga_status_changed, 10, 3 );
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Escritorio: fichas por revisar
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Animales (versión en castellano) con algo pendiente, agrupados por problema. */
|
||||
function ga_review_issues() {
|
||||
$animals = get_posts( array(
|
||||
'post_type' => 'animal',
|
||||
'post_status' => array( 'publish', 'draft', 'pending' ),
|
||||
'numberposts' => -1,
|
||||
'lang' => function_exists( 'pll_default_language' ) ? pll_default_language() : '',
|
||||
) );
|
||||
$days = max( 1, (int) ga_setting( 'adopcion', 'review_days', 30 ) );
|
||||
$issues = array(
|
||||
'photo' => array( 'Sin foto principal', array() ),
|
||||
'eu' => array( 'Sin versión en euskera', array() ),
|
||||
'text' => array( 'Sin texto «Cómo es» (castellano o euskera)', array() ),
|
||||
'species' => array( 'Sin especie (perro o gato)', array() ),
|
||||
'process' => array( sprintf( 'En proceso desde hace más de %d días', $days ), array() ),
|
||||
);
|
||||
foreach ( $animals as $animal ) {
|
||||
if ( 'adoptado' === ga_status( $animal->ID ) ) {
|
||||
continue;
|
||||
}
|
||||
$eu = function_exists( 'pll_get_post' ) ? pll_get_post( $animal->ID, 'eu' ) : 0;
|
||||
if ( ! has_post_thumbnail( $animal ) ) {
|
||||
$issues['photo'][1][] = $animal;
|
||||
}
|
||||
if ( function_exists( 'pll_get_post' ) && ! $eu ) {
|
||||
$issues['eu'][1][] = $animal;
|
||||
}
|
||||
if ( '' === ga_get( $animal->ID, 'caracter' ) || ( $eu && '' === ga_get( $eu, 'caracter' ) ) ) {
|
||||
$issues['text'][1][] = $animal;
|
||||
}
|
||||
if ( ! has_term( '', 'especie', $animal ) ) {
|
||||
$issues['species'][1][] = $animal;
|
||||
}
|
||||
$since = ga_get( $animal->ID, 'estado_desde' );
|
||||
if ( 'proceso' === ga_status( $animal->ID ) && $since && strtotime( $since ) < strtotime( "-$days days" ) ) {
|
||||
$issues['process'][1][] = $animal;
|
||||
}
|
||||
}
|
||||
return array_filter( $issues, fn( $i ) => ! empty( $i[1] ) );
|
||||
}
|
||||
|
||||
add_action( 'wp_dashboard_setup', function () {
|
||||
if ( ! current_user_can( 'edit_posts' ) ) {
|
||||
return;
|
||||
}
|
||||
wp_add_dashboard_widget( 'ga_review', 'Bilagun · Fichas por revisar', function () {
|
||||
$issues = ga_review_issues();
|
||||
if ( ! $issues ) {
|
||||
echo '<p>✓ Todas las fichas están completas.</p>';
|
||||
}
|
||||
foreach ( $issues as [ $title, $animals ] ) {
|
||||
printf( '<h4 style="margin:14px 0 6px">%s <span class="count">(%d)</span></h4><ul style="margin:0 0 0 1em;list-style:disc">', esc_html( $title ), count( $animals ) );
|
||||
foreach ( array_slice( $animals, 0, 8 ) as $animal ) {
|
||||
printf( '<li><a href="%s">%s</a></li>', esc_url( get_edit_post_link( $animal ) ), esc_html( get_the_title( $animal ) ) );
|
||||
}
|
||||
if ( count( $animals ) > 8 ) {
|
||||
echo '<li>…</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
$messages = (int) wp_count_posts( 'ga_mensaje' )->private;
|
||||
printf(
|
||||
'<p style="margin-top:16px;border-top:1px solid #eee;padding-top:10px"><a class="button" href="%s">Añadir animal</a> <a class="button" href="%s">Mensajes (%d)</a></p>',
|
||||
esc_url( admin_url( 'post-new.php?post_type=animal' ) ),
|
||||
esc_url( admin_url( 'edit.php?post_type=ga_mensaje' ) ),
|
||||
$messages
|
||||
);
|
||||
} );
|
||||
// Arriba del todo.
|
||||
global $wp_meta_boxes;
|
||||
$widget = $wp_meta_boxes['dashboard']['normal']['core']['ga_review'] ?? null;
|
||||
if ( $widget ) {
|
||||
unset( $wp_meta_boxes['dashboard']['normal']['core']['ga_review'] );
|
||||
$wp_meta_boxes['dashboard']['normal']['high']['ga_review'] = $widget;
|
||||
}
|
||||
} );
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Listado de animales: acciones en bloque y destacar con un clic
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
function ga_bulk_actions() {
|
||||
return array(
|
||||
'ga_disponible' => array( 'Estado: Disponible', 'estado', 'disponible' ),
|
||||
'ga_proceso' => array( 'Estado: En proceso', 'estado', 'proceso' ),
|
||||
'ga_adoptado' => array( 'Estado: Adoptado', 'estado', 'adoptado' ),
|
||||
'ga_destacar' => array( 'Destacar en portada', 'destacado', '1' ),
|
||||
'ga_no_destacar' => array( 'Quitar de destacados', 'destacado', '' ),
|
||||
);
|
||||
}
|
||||
|
||||
add_filter( 'bulk_actions-edit-animal', function ( $actions ) {
|
||||
foreach ( ga_bulk_actions() as $key => [ $label ] ) {
|
||||
$actions[ $key ] = $label;
|
||||
}
|
||||
return $actions;
|
||||
} );
|
||||
|
||||
add_filter( 'handle_bulk_actions-edit-animal', function ( $redirect, $action, $ids ) {
|
||||
$actions = ga_bulk_actions();
|
||||
if ( ! isset( $actions[ $action ] ) ) {
|
||||
return $redirect;
|
||||
}
|
||||
[ , $field, $value ] = $actions[ $action ];
|
||||
$done = 0;
|
||||
foreach ( $ids as $id ) {
|
||||
if ( current_user_can( 'edit_post', $id ) ) {
|
||||
ga_update_meta_all_languages( $id, "_ga_$field", $value );
|
||||
++$done;
|
||||
}
|
||||
}
|
||||
return add_query_arg( 'ga_bulk', $done, $redirect );
|
||||
}, 10, 3 );
|
||||
|
||||
add_action( 'admin_notices', function () {
|
||||
if ( isset( $_GET['ga_bulk'] ) && 'edit-animal' === ( get_current_screen()->id ?? '' ) ) {
|
||||
printf( '<div class="notice notice-success is-dismissible"><p>%d animales actualizados (también su versión en el otro idioma).</p></div>', absint( $_GET['ga_bulk'] ) );
|
||||
}
|
||||
} );
|
||||
|
||||
/* Estrella clicable en la columna «★» */
|
||||
add_action( 'manage_animal_posts_custom_column', function ( $col, $post_id ) {
|
||||
if ( 'ga_destacado' !== $col || ! current_user_can( 'edit_post', $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
$on = (bool) ga_get( $post_id, 'destacado' );
|
||||
$url = wp_nonce_url( admin_url( 'admin-post.php?action=ga_toggle_featured&post=' . $post_id ), 'ga_toggle_featured_' . $post_id );
|
||||
printf(
|
||||
'<a href="%s" title="%s" style="font-size:18px;text-decoration:none;color:%s">%s</a>',
|
||||
esc_url( $url ),
|
||||
esc_attr( $on ? 'Quitar de destacados' : 'Destacar en portada' ),
|
||||
$on ? '#bd8537' : '#c3c4c7',
|
||||
$on ? '★' : '☆'
|
||||
);
|
||||
}, 20, 2 );
|
||||
|
||||
add_action( 'admin_post_ga_toggle_featured', function () {
|
||||
$id = absint( $_GET['post'] ?? 0 );
|
||||
check_admin_referer( 'ga_toggle_featured_' . $id );
|
||||
if ( ! current_user_can( 'edit_post', $id ) ) {
|
||||
wp_die( 'Sin permiso.' );
|
||||
}
|
||||
ga_update_meta_all_languages( $id, '_ga_destacado', ga_get( $id, 'destacado' ) ? '' : '1' );
|
||||
wp_safe_redirect( wp_get_referer() ?: admin_url( 'edit.php?post_type=animal' ) );
|
||||
exit;
|
||||
} );
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Protección de datos: borrado automático de mensajes antiguos
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
add_action( 'init', function () {
|
||||
if ( ! wp_next_scheduled( 'ga_purge_messages' ) ) {
|
||||
wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'ga_purge_messages' );
|
||||
}
|
||||
} );
|
||||
|
||||
add_action( 'ga_purge_messages', 'ga_purge_messages' );
|
||||
|
||||
/** Borra los mensajes del formulario más antiguos que el plazo configurado (0 = nunca). */
|
||||
function ga_purge_messages() {
|
||||
$months = (int) ga_setting( 'adopcion', 'retention_months', 12 );
|
||||
if ( $months <= 0 ) {
|
||||
return 0;
|
||||
}
|
||||
$old = get_posts( array(
|
||||
'post_type' => 'ga_mensaje',
|
||||
'post_status' => 'any',
|
||||
'numberposts' => 200,
|
||||
'fields' => 'ids',
|
||||
'date_query' => array( array( 'before' => "$months months ago" ) ),
|
||||
) );
|
||||
foreach ( $old as $id ) {
|
||||
wp_delete_post( $id, true );
|
||||
}
|
||||
return count( $old );
|
||||
}
|
||||
@@ -382,8 +382,6 @@ add_action( 'manage_animal_posts_custom_column', function ( $col, $post_id ) {
|
||||
echo get_the_post_thumbnail( $post_id, array( 60, 60 ) );
|
||||
} elseif ( 'ga_estado' === $col ) {
|
||||
echo esc_html( ga_label( $post_id, 'estado' ) );
|
||||
} elseif ( 'ga_destacado' === $col ) {
|
||||
echo ga_get( $post_id, 'destacado' ) ? '★' : '';
|
||||
}
|
||||
}, 10, 2 );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user