
Met de code van vandaag kunnen we in elke post of pagina in WordPress een knop met een shortcode toevoegen die, als we erop klikken, een modaal venster opent waarin we de inhoud kunnen toevoegen die we willen.
Het kan worden gebruikt om een inschrijvingsformulier, een contactformulier, een eenmalige mededeling, een afbeelding, een informatievak of, zoals in mijn geval, een foutmeldingsformulier weer te geven.
Je kunt de werkende shortcode onderaan elk bericht testen.
[error_report_form]
Hoewel het al weken goed werkt op deze blog, moet je onthouden dat dit versie 1.0 is en dat er altijd ruimte is voor verbetering en debugging. Je kunt de CSS loskoppelen om wijzigingen makkelijker te maken en zelfs, als je durft, er een plugin van maken om meer instellingen en configuraties toe te voegen voor snelle en gemakkelijke toegang.
Onder de code vind je een beschrijving van de opties en instructies om het uit te proberen.
Code
/*
* Versión: 1.0
* Última actualización: 13-03-2025 17:54:00
*/
// Shortcode para mostrar el botón y el formulario modal actualizado en jrmora.com
function error_report_form_shortcode() {
// Generar números aleatorios para la operación matemática
$num1 = rand(1, 9);
$num2 = rand(1, 9);
$sum = $num1 + $num2;
// Iniciar sesión si no está iniciada
if (!session_id()) {
session_start();
}
// Guardar la suma en una variable de sesión para validar después
$_SESSION['captcha_sum'] = $sum;
// HTML del botón y el modal
ob_start();
?>
<button id="openErrorModal" style="padding: 10px 20px; background-color: #ffcc00; color: black; border: none; border-radius: 6px; cursor: pointer; font-weight: bold;">
⚠ Comunicar error
</button>
<div id="errorModalOverlay" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 999;">
<div id="errorModal" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 20px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); z-index: 1000; border-radius: 7px; width: 90%; max-width: 500px;">
<span id="closeModalBtn" style="position: absolute; top: 10px; right: 10px; cursor: pointer; font-size: 20px; background-color: black; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; line-height: 30px;">×</span>
<h3 style="font-size: 18px;">Comunicar error (Para errores ortográficos o de malfuncionamiento del sitio)</h3>
<form id="errorForm" method="post">
<input type="hidden" name="action" value="submit_error_report">
<label for="name" style="font-size: 14px;">Nombre:</label>
<input type="text" id="name" name="name" required style="background-color: #f5f5f5; padding: 8px; border: 1px solid #ddd; border-radius: 4px; width: 100%; margin-bottom: 12px;">
<div id="nameError" style="color: red; display: none; font-size: 12px; margin-bottom: 12px;">No se permiten enlaces o dominios en el campo "Nombre".</div>
<label for="message" style="font-size: 14px;">Descripción del error:</label>
<textarea id="message" name="message" required style="background-color: #f5f5f5; padding: 8px; border: 1px solid #ddd; border-radius: 4px; width: 100%; margin-bottom: 12px;"></textarea>
<div id="messageError" style="color: red; display: none; font-size: 12px; margin-bottom: 12px;">No se permiten enlaces o dominios en el campo "Mensaje".</div>
<label for="captcha" style="font-size: 14px;">¿Eres humano? ¿Cuánto es <?php echo $num1; ?> + <?php echo $num2; ?>?</label>
<input type="text" id="captcha" name="captcha" required style="background-color: #f5f5f5; padding: 8px; border: 1px solid #ddd; border-radius: 4px; width: 100%; margin-bottom: 12px;">
<div id="captchaError" style="color: red; display: none; font-size: 12px; margin-bottom: 12px;">El resultado de la suma es incorrecto.</div>
<!-- Opcional: Añadir reCaptcha si se proporcionan las claves -->
<?php if (defined('RECAPTCHA_SITE_KEY') && defined('RECAPTCHA_SECRET_KEY')) : ?>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="<?php echo RECAPTCHA_SITE_KEY; ?>" style="margin-bottom: 12px;"></div>
<?php endif; ?>
<div style="text-align: center;">
<input type="submit" value="Enviar" style="background-color: #bc080e; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; font-weight: bold; display: inline-block;">
</div>
</form>
<div id="successMessage" style="color: green; display: none; margin-top: 10px; font-size: 14px; text-align: center;">Gracias por comunicar el error.</div>
</div>
</div>
<style>
/* Estilos para dispositivos móviles */
@media (max-width: 768px) {
#errorModal {
width: 90% !important; /* Ajusta el ancho del modal al 90% de la pantalla */
max-width: 90% !important; /* Asegura que no exceda el 90% del ancho */
padding: 15px !important; /* Reduce el padding para más espacio */
}
#errorForm input, #errorForm textarea {
font-size: 16px !important; /* Aumenta el tamaño de la fuente para mejor legibilidad */
}
#errorForm label {
font-size: 16px !important; /* Aumenta el tamaño de la fuente de las etiquetas */
}
}
</style>
<script>
// Abrir modal
document.getElementById('openErrorModal').addEventListener('click', function() {
document.getElementById('errorModalOverlay').style.display = 'block';
});
// Cerrar modal al hacer clic en el aspa
document.getElementById('closeModalBtn').addEventListener('click', function() {
document.getElementById('errorModalOverlay').style.display = 'none';
});
// Cerrar modal al hacer clic fuera de él
document.getElementById('errorModalOverlay').addEventListener('click', function(event) {
if (event.target === document.getElementById('errorModalOverlay')) {
document.getElementById('errorModalOverlay').style.display = 'none';
}
});
// Función para validar si hay enlaces o dominios en el texto
function containsUrlOrDomain(text) {
// Expresión regular para detectar enlaces o dominios
const urlPattern = /(http|https|www|\[url|\[link)|(\b\w+\.(com|org|net|io|co|edu|gov|mil|biz|info|xyz|me|tv|us|uk|ca|au|de|fr|es|it|nl|ru|jp|cn|in|br|mx|ar|cl|pe|ve|co\.uk|co\.jp|co\.in|ac\.uk|gov\.uk|edu\.au|com\.au|org\.uk|net\.au)\b)/i;
return urlPattern.test(text);
}
// Manejar el envío del formulario con AJAX
document.getElementById('errorForm').addEventListener('submit', function(e) {
e.preventDefault(); // Evitar envío tradicional del formulario
// Ocultar mensajes de error previos
document.getElementById('nameError').style.display = 'none';
document.getElementById('messageError').style.display = 'none';
document.getElementById('captchaError').style.display = 'none';
// Validar campos
var name = document.getElementById('name').value;
var message = document.getElementById('message').value;
var captcha = document.getElementById('captcha').value;
var hasError = false;
// Validar enlaces o dominios en el nombre
if (containsUrlOrDomain(name)) {
document.getElementById('nameError').style.display = 'block';
hasError = true;
}
// Validar enlaces o dominios en el mensaje
if (containsUrlOrDomain(message)) {
document.getElementById('messageError').style.display = 'block';
hasError = true;
}
// Validar el captcha
if (captcha !== '<?php echo $sum; ?>') {
document.getElementById('captchaError').style.display = 'block';
hasError = true;
}
// Si hay errores, detener el envío
if (hasError) {
return;
}
// Enviar el formulario si no hay errores
var formData = new FormData(this);
fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
method: 'POST',
body: formData
})
.then(response => response.text())
.then(data => {
// Mostrar mensaje de éxito
document.getElementById('successMessage').style.display = 'block';
// Ocultar el formulario
document.getElementById('errorForm').style.display = 'none';
// Esperar 3 segundos y cerrar el modal
setTimeout(function() {
document.getElementById('errorModalOverlay').style.display = 'none';
document.getElementById('successMessage').style.display = 'none';
document.getElementById('errorForm').style.display = 'block'; // Restaurar el formulario
}, 3000);
})
.catch(error => console.error('Error:', error));
});
</script>
<?php
return ob_get_clean();
}
add_shortcode('error_report_form', 'error_report_form_shortcode');
// Manejar el envío del formulario
function handle_error_report_form() {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'submit_error_report') {
// Iniciar sesión si no está iniciada
if (!session_id()) {
session_start();
}
// Validar el captcha
if (!isset($_SESSION['captcha_sum']) || !isset($_POST['captcha']) || $_POST['captcha'] != $_SESSION['captcha_sum']) {
wp_die('Captcha incorrecto. Por favor, intenta de nuevo.');
}
// Validar que no haya enlaces o dominios en los campos
$name = isset($_POST['name']) ? sanitize_text_field($_POST['name']) : '';
$message = isset($_POST['message']) ? sanitize_text_field($_POST['message']) : '';
if (preg_match('/(http|https|www|\[url|\[link)|(\b\w+\.(com|org|net|io|co|edu|gov|mil|biz|info|xyz|me|tv|us|uk|ca|au|de|fr|es|it|nl|ru|jp|cn|in|br|mx|ar|cl|pe|ve|co\.uk|co\.jp|co\.in|ac\.uk|gov\.uk|edu\.au|com\.au|org\.uk|net\.au)\b)/i', $name . $message)) {
wp_die('No se permiten enlaces o dominios en los campos.');
}
// Validar reCaptcha (opcional)
if (defined('RECAPTCHA_SITE_KEY') && defined('RECAPTCHA_SECRET_KEY')) {
if (!isset($_POST['g-recaptcha-response'])) {
wp_die('Por favor, completa el reCaptcha.');
}
$recaptcha_response = $_POST['g-recaptcha-response'];
$recaptcha_secret = RECAPTCHA_SECRET_KEY;
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_data = [
'secret' => $recaptcha_secret,
'response' => $recaptcha_response,
'remoteip' => $_SERVER['REMOTE_ADDR']
];
$recaptcha_options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($recaptcha_data)
]
];
$recaptcha_context = stream_context_create($recaptcha_options);
$recaptcha_result = file_get_contents($recaptcha_url, false, $recaptcha_context);
$recaptcha_json = json_decode($recaptcha_result);
if (!$recaptcha_json->success) {
wp_die('Por favor, completa el reCaptcha correctamente.');
}
}
// Obtener la URL de origen
$url = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'URL desconocida';
// Enviar correo electrónico
$to = get_option('admin_email'); // Correo del administrador
$subject = 'Comunicación de Error desde ' . $url;
$body = "Nombre: $name\n\nMensaje: $message\n\nURL: $url";
$headers = array('Content-Type: text/plain; charset=UTF-8');
if (wp_mail($to, $subject, $body, $headers)) {
echo 'success';
} else {
echo 'Hubo un error al enviar el mensaje.';
}
exit;
}
}
add_action('wp_ajax_submit_error_report', 'handle_error_report_form');
add_action('wp_ajax_nopriv_submit_error_report', 'handle_error_report_form');
// Definir claves de reCaptcha (opcional)
// define('RECAPTCHA_SITE_KEY', 'TU_SITE_KEY');
// define('RECAPTCHA_SECRET_KEY', 'TU_SECRET_KEY');
Functionaliteit van het formulier
- Kortere code:
[error_report_form]
- Geeft een knop weer die een modaal formulier opent voor het melden van fouten.
- Het formulier bevat velden voor naam, bericht en een eenvoudige wiskundige captcha.
- Controleer of er geen koppelingen of domeinen in de velden zijn ingevoerd.
- Stuur een e-mail naar de blogbeheerder met details over de fout.
- Formuliervelden
:Polylang placeholder niet wijzigen
- Validaties
:Polylang plaatshouder niet wijzigen
- Indiening van het formulier
:Polylang plaatshouder niet wijzigen
- Spam preventie
:Polylang placeholder niet wijzigen
Vormstijlen
- Fout melden" knop
:Polylang plaatshouder niet wijzigen
- Modaal (pop-upvenster)
:Polylang plaatshouder niet wijzigen
- Sluitgreep (knop om het modaal te sluiten, de klasse is id="closeModalBtn")
:Polylang plaatshouder niet wijzigen
- Formuliervelden
:Polylang placeholder niet wijzigen
- Verzend" knop
:Polylang plaatshouder niet wijzigen
- Foutmeldingen
:Polylang plaatshouder niet wijzigen
- Succesbericht
:Polylang plaatshouder niet wijzigen
Stijlen aanpassen
- Kleuren wijzigen
:Polylang plaatshouder niet wijzigen
- Lettergrootten wijzigen
:Polylang plaatshouder niet wijzigen
- Randen en afgeronde hoeken wijzigen
:Polylang plaatshouder niet wijzigen
- Spatie wijzigen
:Polylang plaatshouder niet wijzigen
- Wijzig de breedte van de velden
:Polylang placeholder niet wijzigen
Extra opties
- reCaptcha
:Polylang plaatshouder niet wijzigen
- E-mail personalisatie
:Polylang placeholder niet wijzigen
Gebruiksaanwijzing
- Kopieer en plak de code in het bestand functions.php van je thema.
- Gebruik de shortcode op elke pagina of post.
- Pas de stijlen naar wens aan.
- Als je reCaptcha wilt gebruiken, volg dan de instructies in het gedeelte "Extra opties".