
오늘의 코드를 사용하면 워드프레스의 글이나 페이지에 단축 코드가 있는 버튼을 추가하여 클릭하면 원하는 콘텐츠를 추가할 수 있는 모달 창을 열 수 있습니다.
구독 양식, 문의 양식, 일회성 알림, 이미지, 정보 상자 또는 제 경우처럼 오류 알림 양식을 표시하는 데 사용할 수 있습니다.
모든 글 하단에서 작동하는 단축 코드를 테스트할 수 있습니다.
[error_report_form]
이 블로그에서 몇 주 동안 제대로 작동하고 있지만 1.0 버전이며 항상 개선과 디버깅의 여지가 있다는 점을 기억하세요. CSS를 분리하여 더 쉽게 변경할 수 있으며, 원한다면 플러그인으로 전환하여 더 많은 설정과 구성을 추가하여 빠르고 쉽게 액세스할 수도 있습니다.
코드 아래에서 옵션에 대한 설명과 사용 방법에 대한 지침을 확인할 수 있습니다.
코드
/*
* 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');
양식의 기능
- 쇼트코드:
[error_report_form]
- 오류 신고를 위한 모달 양식을 여는 버튼을 표시합니다.
- 이 양식에는 이름, 메시지 및 간단한 수학 캡차 입력란이 포함되어 있습니다.
- 필드에 링크나 도메인이 입력되지 않았는지 확인합니다.
- 블로그 관리자에게 오류에 대한 자세한 내용을 담은 이메일을 보냅니다.
- 양식 필드
:폴리랑 플레이스홀더는 수정하지 않습니다.
- 유효성
검사: 폴리랑 플레이스홀더는 수정하지 않습니다.
- 양식 제출
: 폴리랑 플레이스홀더는 수정하지 않습니다.
- 스팸 방지
: 폴리랑 플레이스홀더는 수정하지 않습니다.
양식 스타일
- 오류 신고" 버튼
:폴리랑 플레이스홀더는 수정하지 않습니다.
- 모달(팝업 창)
: 폴리랑 플레이스홀더는 수정하지 않습니다.
- 닫기 핸들(모달을 닫는 버튼의 클래스는 id="closeModalBtn")
:폴리랑 플레이스홀더는 수정하지 않습니다.
- 양식 필드
:폴리랑 플레이스홀더는 수정하지 않습니다.
- 보내기" 버튼
:폴리랑 자리 표시자는 수정하지 않습니다.
- 오류 메시지
:폴리랑 플레이스홀더가 수정되지 않습니다.
- 성공 메시지
:폴리랑 자리 표시자를 수정하지 않습니다.
스타일 수정 방법
- 색상 수정
: 폴리랑 플레이스홀더는 수정하지 않습니다.
- 글꼴 크기 수정
: 폴리랑 플레이스홀더는 수정하지 않습니다.
- 테두리 및 둥근 모서리 수정
: 폴리랑 플레이스홀더는 수정하지 않습니다.
- 간격 수정
: 폴리랑 플레이스홀더는 수정하지 않습니다.
- 필드 너비 수정
: 폴리랑 플레이스홀더는 수정하지 않습니다.
추가 옵션
- 재캡차
:폴리랑 자리 표시자는 수정하지 않습니다.
- 이메일 개인화
: 폴리랑 자리 표시자는 수정하지 않습니다.
사용 지침
- 코드를 복사하여 테마의 functions.php 파일에 붙여넣습니다.
- 페이지 또는 글에서 쇼트코드를 사용합니다.
- 필요에 따라 스타일을 사용자 지정하세요.
- 재캡차를 사용하려면 '추가 옵션' 섹션의 지침을 따르세요.