Estamos acostumbrados a crear formularios de contacto usando el plugin Contact Form 7. Este tipo de formularios solo sirven para enviar correos y no guardan la información que el usuario rellena desde el front-end. Vamos a crear un formulario wordpress mediante código, que permita almacenar datos. Además, por motivos de seguridad, solo los usuarios registrados podrán acceder a él.
Punto de partida
Nuestro formulario permite a los usuarios crear peticiones de trabajo, indicando un título, una descripción, un tipo de petición: Demanda u Oferta, y por último un tema de ayuda. El aspecto del formulario sería el siguiente:

Por otra parte, la información que el usuario facilite debe quedar almacenada en forma de CPT. Con ayuda del plugin CPT UI o a través de código: register_post_type(), creamos un CPT ‘peticiones‘ con dos taxonomías: ‘tipos de peticiones‘ y ‘tipos de ayuda‘. El resultado que se persigue es este:

Ahora que sabemos los campos de nuestro formulario y la información que procesa, pasamos a la acción.
CREAR PLUGIN PARA MOSTRAR FORMULARIO EN FRONT-END
Para empezar creamos una carpeta dentro de la carpeta plugin, que en mi caso se llama ‘formulario-peticion‘. Dentro de esta carpeta, creo un archivo con el mismo nombre que su carpeta contenedora y escribimos nuestro código.
Configuración de la información del plugin
/**
* Plugin Name: Formulario para hacer peticiones
* Plugin URI: http://myhappycoding.com/formulario-peticion
* Description: Este plugin permite a los usuarios registrados enviar peticiones que se almacenan en wordpress y quedan pendientes de aprobación por parte del administrador.
* Version: 1.0
* Author: Alberto Marín
* Author URI: http://www.myhappycoding.com
*/
El código de arriba, permite integrar nuestro plugin en wordpress.

A continuación nuestro código se divide en 4 funciones secuenciales donde cada una llevará a cabo una tarea:
- Presentar el formulario por pantalla
- Validar el envío del formulario cuando el usuario haga click en enviar.
- Guardar la información en el CPT.
- Función responsable de ejecutar las tres funciones anteriores.
De manera resumida, queda así:
/*
Presenta el formulario por pantalla, y recibe 3 parametros, porque hay 2 situaciones para mostrar el formulario: cuando se muestra por primera vez, o como resultado de un envio previo
*/
function registro_form ($titulo, $descripcion, $tema_de_ayuda) {
....
}
/*
Asegura que los datos que se envian no esten vacios o no existan.
*/
function validacion_envio_formulario ($titulo, $descripcion, $usuario, $tema_ayuda){
....
}
/*
Comprueba y asegura el guardado de los datos en el CPT
*/
function completa_solicitud() {
....
}
/*
Ejecuta la lógica de la aplicacion
*/
function ejecuta_todo() {
...
}
A continuación explico cada función con más detalle.
Mostrar el formulario
Para mostrar el formulario, creamos la estructura HTML, y lo imprimimos con un echo.
echo '
<div class="col-12 formulario">
<!-- TOMAMOS LA URL DEL SERVIDOR JUNTO CON LOS DATOS PASADOS POR PARAMETRO, EN CASO DE QUE LOS HAYA -->
<form action="' . $_SERVER['REQUEST_URI'] . '" method="post" >
<div class="form-group">
<label for="titulo-id">Título</label>
<!-- Pasamos el parámetro título: $titulo -->
<input class="form-control" type="text" name="titulo" id="titulo-id" value="'.(isset($_POST['titulo'])?$titulo:null).'">
</div>
<div class="form-group">
<label for="descripcion-id">Descripcion</label>
<!-- Pasamos el parámetro descripcion: $descripcion -->
<input class="form-control" type="text" name="descripcion" id="descripcion-id" value="'.(isset($_POST['descripcion'])?$descripcion:null).'">
</div>
<div class="form-group">
<!-- Pasamos la variable usuario: $user_login -->
<input class="form-control" type="hidden" name="usuario" id="usuario-id" value="'.$user_login.'">
</div>
<div class="form-group">
<label for="tipo_de_peticion-id">Tipo de petición</label>
<select id="tipo_de_peticion-id" name="tipo_de_peticion">
';
//Rellenamos los diferentes tipos de peticiones
foreach ($terms as $term) {
echo '<option value="'.$term->slug.'">'.$term->name.'</option>'; //Mostramos los tipos de peticiones disponibles
}
echo '
</select>
</div>
<div class="form-group">
<!-- Pasamos el parámetro tema de ayuda: $tema_de_ayuda -->
<label for="tema_de_ayuda-id">Tema de ayuda</label>
<input class="form-control" type="text" name="tema_de_ayuda" id="tema_de_ayuda-id" value="'.(isset($_POST['tema_de_ayuda'])?$tema_de_ayuda:null).'">
</div>
<!-- Indicamos en que CPT almacenamos la información e incluimos un campo oculto cpt_nonce_field para asegurar el envío desde esta fuente-->
<input type="hidden" name="cpt" id="post_type_id" value="peticiones" />
'. wp_nonce_field( 'cpt_nonce_action', 'cpt_nonce_field' ).'
<div class="form-group">
<input class="form-control" type="submit" value="Enviar" name="submit"/>
</div>
</form></div>
';
Previo al código anterior necesitamos seleccionar el usuario actual y los términos que hemos definido para los tipos de peticiones. En nuestro caso son dos: Oferta y Demanda.
//Seleccionamos el usuario actual
$current_user = wp_get_current_user();
$user_login=$current_user->user_login;
//Seleccionamos los terminos definidos para los tipos de peticiones
$terms = get_terms(
array(
'taxonomy' => 'tipo_de_peticion',
'hide_empty' => false,
'parent' => 0 )
);
Validar el Formulario
En la validación del formulario, nos creamos una instancia de la clase WP_Error y comprobamos si faltan algunos de los campos del formulario. Esta comprobación se hará al momento del envío, y el momento en que se hace la validación se lleva a cabo más adelante, lo importante ahora es abstraernos y validar los campos.
global $reg_errors;
$reg_errors = new WP_Error;
if (empty($titulo) || empty($descripcion) || empty($tema_de_ayuda)){
$reg_errors->add('field', 'Faltan los campos requeridos');
}
if (empty($usuario)){
$reg_errors->add('field', 'Debe estar registrado');
}
if (!isset($_POST['cpt_nonce_field']) || !wp_verify_nonce($_POST['cpt_nonce_field'],'cpt_nonce_action')){
$reg_errors->add('field', 'Falla la seguridad');
if (is_wp_error($reg_errors)){
foreach ($reg_errors->get_error_messages() as $error) {
echo '<div><strong>ERROR: </strong>'.$error.'</br></div>';
}
}
Comprobación y guardado de datos
Es el momento de realizar la validación y de guardar los datos. Si hemos llegado hasta aquí, es porque el usuario a pinchado en enviar y espera una respuesta ya sea de éxito o fracaso.
En el paso anterior creamos un objeto WP_Error que definimos como global precisamente para usarlo nuevamente. Además definimos el resto de variables que vamos a necesitar, también global
global $reg_errors, $titulo, $descripcion, $usuario, $tipo_de_peticion, $tema_de_ayuda;
Ahora es el momento de validar nuestro formulario a través de la función anterior y si todo es correcto guardamos la información dentro de nuestro CPT.
//Si no hay errores creamos la solicitud
if (count($reg_errors->get_error_messages())<1){
$solicitud = array (
'post_title' => $titulo,
'post_content' => $descripcion,
'usuario' => $usuario,
'post_status'=> 'pending',
'post_type'=>$_POST['cpt']
);
//Creamos el nuevo post
$new_post=wp_insert_post($solicitud, $reg_errors);
//Definimos los términos de su taxonomía a la que pertenece
$taxonomy = 'tipo_de_peticion';
$result=wp_set_object_terms($new_post, $tipo_de_peticion, $taxonomy);
$tags= 'tema_de_ayuda';
$result=wp_set_object_terms($new_post, $tema_de_ayuda, $tags);
//Definimos el usuario al que pertenece
$users = get_field('usuario', $new_post, false);
$user = get_user_by('login',$usuario);
if($user){
$new_user_id_to_add = $user->ID;
}
// add the users ID to the array
$users[] = $new_user_id_to_add;
// update the field
// $selector == the field key of the field to update
update_field('usuario', $users, $new_post);
//Actualizamos resto de campos
update_post_meta( $new_post, 'titulo', $titulo );
update_post_meta( $new_post, 'descripcion', $descripcion );
Ejecutar todo
El siguiente código, comprueba si el usuario ha pulsado el botón enviar del formulario mediante la variable $_POST[‘submit’] y en caso afirmativo valida el envío del formulario y almacena la información.
global $titulo, $descripcion, $usuario, $tipo_de_peticion, $tema_de_ayuda;
if (isset($_POST['submit'])){
validacion_envio_formulario(
$_POST['titulo'],
$_POST['descripcion'],
$_POST['usuario'],
$_POST['tema_de_ayuda']);
$titulo = sanitize_text_field( $_POST['titulo'] );
$descripcion = sanitize_text_field( $_POST['descripcion'] );
$usuario = sanitize_user($_POST['usuario']);
$tipo_de_peticion = sanitize_text_field( $_POST['tipo_de_peticion'] );
$tema_de_ayuda = sanitize_text_field( $_POST['tema_de_ayuda'] );
completa_solicitud(
$titulo,
$descripcion,
$usuario,
$tipo_de_peticion,
$tema_de_ayuda);
}
registro_form ($titulo, $descripcion, $tema_de_ayuda);
CREAR SHORTCODE
Por último, solo queda crear el shortcode que nos permita colocar nuestro formulario en la página que queramos:
// Registrar nuevo shortcode: [cr_custom_solicitud]
add_shortcode( 'cr_custom_solicitud', 'custom_registration_shortcode' );
// Función callback
function custom_registration_shortcode() {
ob_start();
ejecuta_todo();
return ob_get_clean();
}
Y hasta aquí todo por hoy. Espero que os haya gustado esta publicación sobre como crear un formulario wordpress mediante código y si es así me lo podéis indicar a través de los comentarios o de las redes sociales.
Happy coding!!