I have a custom post type "Propietario" with several custom fields, and 3 of them: "dni", "email" and "phone" I need unique for all Propietario Post types. This CPT is only accesible throw admin wordpress page.
@vijay-pancholi's answer has made me understand what is the flow when registering new custom fields. And after this I have edited my answer.
I am using object-oriented programming for creating my CPT since it is part of a more complex plugin. The method involved, which stores the fields, is "properties_save_fields_owner". The code is more complex but I have tried to reduce it to show only the code involved for this problem:
<?php
class Propietario {
public function __construct() {
add_action('init', array($this, 'registrar_cpt_propietario'));
add_action('add_meta_boxes', array($this, 'propietarios_meta_box'));
add_action('save_post', array($this, 'inmuebles_guardar_campos_propietario'));
}
/**
* Registration Propietario CPT
*/
public function registrar_cpt_propietario() {
$labels = array(
'name' => 'Propietario',
'singular_name' => 'Propietario',
'menu_name' => 'Propietarios',
'name_admin_bar' => 'Propietario',
'add_new' => 'Añadir Propietario',
...
);
$args = array(
'labels' => $labels,
'public' => false,
...
);
register_post_type('propietario', $args);
}
/**
* Add metabox "Datos del propietario"
*/
public function propietarios_meta_box() {
add_meta_box('propietarios_info',
'Información del Propietario',
array($this, 'mostrar_campos_propietario'),
'propietario',
'normal',
'high' );
}
/**
* Muestra los campos del propietario en el formulario de edición de propietarios.
* @param WP_Post $post El objeto de entrada actual.
*/
public function mostrar_campos_propietario($post) {
$nombre = get_post_meta($post->ID, 'nombre', true);
$apellidos = get_post_meta($post->ID, 'apellidos', true);
$email = get_post_meta($post->ID, 'email', true);
$telefono = get_post_meta($post->ID, 'telefono', true);
$dni = get_post_meta($post->ID, 'dni', true);
?>
<div id="contenedor-propietario">
<table class="form-table">
<tr>
<th><label for="nombre">Nombre*</label></th>
<td><input type="text" name="nombre" id="nombre" value="<?php echo esc_attr($nombre ?? ''); ?>" required></td>
</tr>
...
</table>
</div>
<?php
}
/**
* Saves custom field values when saving an propietario
* @param int $post_id ID of the current propietario
*/
function inmuebles_guardar_campos_propietario($post_id) {
// Check if it's not an autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
// Check if it's the correct post type
if ('propietario' !== get_post_type($post_id)) return;
//Check if there is already an owner with the same DNI, email or telefono
$dni = isset($_POST['dni']) ? sanitize_text_field($_POST['dni']) : '';
$email = isset($_POST['email']) ? sanitize_text_field($_POST['email']) : '';
$telefono = isset($_POST['telefono']) ? sanitize_text_field($_POST['telefono']) : '';
//Check if there is already an owner with the same DNI, email or telefono
if (!empty($dni) || !empty($email) || !empty($telefono)) {
$exists_propietario = get_posts(array(
'post_type' => 'propietario',
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'dni',
'value' => $dni,
'compare' => '='
),
array(
'key' => 'email',
'value' => $email,
'compare' => '='
),
array(
'key' => 'telefono',
'value' => $telefono,
'compare' => '='
),
),
));
} else {
$exists_propietario = array();
}
if (!empty($exists_propietario)) {
wp_die('Ya existe un propietario con el mismo DNI, teléfono o email. <br> <a href="javascript:history.back()">Volver</a>', 'Error', array('response' => 400));
}
// Guardar los metadatos del propietario
if (array_key_exists('nombre', $_POST)) {
update_post_meta($post_id, 'nombre', sanitize_text_field($_POST['nombre']));
}
if (array_key_exists('apellidos', $_POST)) {
update_post_meta($post_id, 'apellidos', sanitize_text_field($_POST['apellidos']));
}
if (array_key_exists('email', $_POST)) {
update_post_meta($post_id, 'email', sanitize_text_field($_POST['email']));
}
if (array_key_exists('telefono', $_POST)) {
update_post_meta($post_id, 'telefono', sanitize_text_field($_POST['telefono']));
}
if (array_key_exists('dni', $_POST)) {
update_post_meta($post_id, 'dni', sanitize_text_field($_POST['dni']));
}
}
}
new Propietario();
After debugging, the main problem is that the method inmuebles_save_fields_propietario
is executed several times. When I try to create a new CPT it runs right when the metabox opens clicking in "add new". That's why I added the line:
if (!empty($id) || !empty($email) || !empty($telephone)) {
And the code is correct, but even if the line is executed:
wp_die('There is already an owner with the same ID, phone number or email. <br> <a href="javascript:history.back()">Back</a>', 'Error', array('response' = > 400));
The method is executed again and for some reason that I don't know the CPT is registered. You register with empty fields, but a new Owner is created.
I have tried adding exit()
after the wp_die, but there is no way I can prevent the method from being executed again, and therefore a new CPT is registered.
How Can I stop registration of CPT when display the error?