196 lines
5.8 KiB
PHP
196 lines
5.8 KiB
PHP
<?php
|
|
/**
|
|
* Intercepte les erreurs de validation Pods lors du save d'un post admin :
|
|
* - Empêche wp_die() (qui publiait quand même le post sans les champs Pods)
|
|
* - Annule le changement de statut si le post n'était pas encore publié
|
|
* - Redirige vers la page d'édition avec les champs restaurés via transient
|
|
*/
|
|
|
|
// Capture l'ID du post en cours de sauvegarde (avant Pods, qui peut le créer pour les nouveaux posts)
|
|
add_action( 'save_post', function ( $post_id ) {
|
|
if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
|
|
return;
|
|
}
|
|
$GLOBALS['thalim_saving_post_id'] = $post_id;
|
|
}, 1 );
|
|
|
|
// Intercepte wp_die() de Pods pendant un save admin
|
|
add_filter( 'pods_error_die', function ( $die, $error ) {
|
|
if ( ! is_admin() || ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] !== 'editpost' ) {
|
|
return $die;
|
|
}
|
|
|
|
$post_id = $GLOBALS['thalim_saving_post_id'] ?? intval( $_POST['post_ID'] ?? 0 );
|
|
if ( ! $post_id ) {
|
|
return $die;
|
|
}
|
|
|
|
$user_id = get_current_user_id();
|
|
|
|
// Collecter les valeurs Pods soumises
|
|
$restore = [];
|
|
foreach ( $_POST as $key => $val ) {
|
|
if ( str_starts_with( $key, 'pods_meta_' ) ) {
|
|
$restore[ $key ] = is_array( $val ) ? array_map( 'wp_unslash', $val ) : wp_unslash( $val );
|
|
}
|
|
}
|
|
$error_text = is_wp_error( $error ) ? $error->get_error_message() : (string) $error;
|
|
$restore['_msg'] = wp_strip_all_tags( $error_text );
|
|
$restore['_title'] = sanitize_text_field( wp_unslash( $_POST['post_title'] ?? '' ) );
|
|
|
|
set_transient( 'thalim_pods_restore_' . $post_id . '_' . $user_id, $restore, 10 * MINUTE_IN_SECONDS );
|
|
|
|
$GLOBALS['thalim_pods_error_post_id'] = $post_id;
|
|
|
|
return false; // empêche wp_die()
|
|
}, 10, 2 );
|
|
|
|
// Après le save : rediriger vers la page d'édition + annuler le statut si besoin
|
|
add_filter( 'redirect_post_location', function ( $location ) {
|
|
$post_id = $GLOBALS['thalim_pods_error_post_id'] ?? 0;
|
|
if ( ! $post_id ) {
|
|
return $location;
|
|
}
|
|
|
|
// Annuler le changement de statut vers publish si le post n'était pas encore publié
|
|
$original = isset( $_POST['original_post_status'] ) ? sanitize_key( $_POST['original_post_status'] ) : '';
|
|
$post = get_post( $post_id );
|
|
|
|
if (
|
|
$post &&
|
|
in_array( $post->post_status, [ 'publish', 'future', 'pending' ], true ) &&
|
|
! in_array( $original, [ 'publish', 'future', 'pending' ], true )
|
|
) {
|
|
global $wpdb;
|
|
$wpdb->update(
|
|
$wpdb->posts,
|
|
[ 'post_status' => $original ?: 'draft' ],
|
|
[ 'ID' => $post_id ],
|
|
[ '%s' ],
|
|
[ '%d' ]
|
|
);
|
|
clean_post_cache( $post_id );
|
|
}
|
|
|
|
return admin_url( 'post.php?post=' . $post_id . '&action=edit' );
|
|
}, 10 );
|
|
|
|
// Sur la page d'édition (GET) : lire le transient une seule fois → global → supprimer
|
|
add_action( 'current_screen', function ( $screen ) {
|
|
if ( $screen->base !== 'post' ) {
|
|
return;
|
|
}
|
|
$post_id = isset( $_GET['post'] ) ? intval( $_GET['post'] ) : 0;
|
|
if ( ! $post_id ) {
|
|
return;
|
|
}
|
|
|
|
$user_id = get_current_user_id();
|
|
$key = 'thalim_pods_restore_' . $post_id . '_' . $user_id;
|
|
$data = get_transient( $key );
|
|
if ( ! $data ) {
|
|
return;
|
|
}
|
|
|
|
$GLOBALS['thalim_pods_restore'] = [
|
|
'post_id' => $post_id,
|
|
'data' => $data,
|
|
];
|
|
delete_transient( $key );
|
|
} );
|
|
|
|
// Injecter les valeurs dans get_post_meta → Pods DFV les embarque dans son JSON React
|
|
add_filter( 'get_post_metadata', function ( $value, $object_id, $meta_key, $single ) {
|
|
$restore = $GLOBALS['thalim_pods_restore'] ?? null;
|
|
if ( ! $restore || $restore['post_id'] !== (int) $object_id ) {
|
|
return $value;
|
|
}
|
|
|
|
$pods_key = 'pods_meta_' . $meta_key;
|
|
if ( ! isset( $restore['data'][ $pods_key ] ) ) {
|
|
return $value;
|
|
}
|
|
|
|
$val = $restore['data'][ $pods_key ];
|
|
return $single ? $val : [ $val ];
|
|
}, 10, 4 );
|
|
|
|
// Restauration JS : titre + champs Pods select/pick via PodsDFV (même pattern que les modales)
|
|
add_action( 'admin_footer', function () {
|
|
$restore = $GLOBALS['thalim_pods_restore'] ?? null;
|
|
if ( ! $restore ) {
|
|
return;
|
|
}
|
|
|
|
$screen = get_current_screen();
|
|
if ( ! $screen || $screen->base !== 'post' ) {
|
|
return;
|
|
}
|
|
|
|
$post_id = intval( $restore['post_id'] );
|
|
$title = $restore['data']['_title'] ?? '';
|
|
|
|
// Construire le map fieldName => value pour les champs Pods
|
|
$fields = [];
|
|
foreach ( $restore['data'] as $key => $val ) {
|
|
if ( str_starts_with( $key, 'pods_meta_' ) ) {
|
|
$fields[ substr( $key, 10 ) ] = $val;
|
|
}
|
|
}
|
|
|
|
?>
|
|
<script>
|
|
(function ($) {
|
|
var postId = <?php echo $post_id; ?>;
|
|
var fields = <?php echo wp_json_encode( $fields ); ?>;
|
|
var title = <?php echo wp_json_encode( $title ); ?>;
|
|
|
|
function doRestore() {
|
|
// Titre WordPress (non géré par get_post_metadata)
|
|
var $titleInput = $('#title');
|
|
if ($titleInput.length && !$titleInput.val() && title) {
|
|
$titleInput.val(title).trigger('input');
|
|
}
|
|
|
|
// Champs Pods : DOM direct + PodsDFV pour les selects/picks
|
|
Object.keys(fields).forEach(function (fieldName) {
|
|
var value = fields[fieldName];
|
|
var $el = $('[name="pods_meta_' + fieldName + '"]');
|
|
if ($el.length) {
|
|
$el.val(value).trigger('change');
|
|
}
|
|
if (window.PodsDFV && postId) {
|
|
try {
|
|
window.PodsDFV.setFieldValue('post', postId, fieldName, value, 0);
|
|
} catch (e) {}
|
|
}
|
|
});
|
|
}
|
|
|
|
$(window).on('load', function () {
|
|
setTimeout(doRestore, 300);
|
|
});
|
|
}(jQuery));
|
|
</script>
|
|
<?php
|
|
} );
|
|
|
|
// Afficher le message d'erreur en admin notice
|
|
add_action( 'admin_notices', function () {
|
|
$restore = $GLOBALS['thalim_pods_restore'] ?? null;
|
|
if ( ! $restore ) {
|
|
return;
|
|
}
|
|
|
|
$screen = get_current_screen();
|
|
if ( ! $screen || $screen->base !== 'post' ) {
|
|
return;
|
|
}
|
|
|
|
$msg = esc_html( $restore['data']['_msg'] ?? '' );
|
|
if ( $msg ) {
|
|
echo '<div class="notice notice-error is-dismissible"><p>' . $msg . '</p></div>';
|
|
}
|
|
echo '<div class="notice notice-info is-dismissible"><p>Votre contenu a été restauré. Vérifiez les champs obligatoires avant de republier.</p></div>';
|
|
} );
|