prefix . NIFTY_CW_TABLE;
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE {$table_name} (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
nombre VARCHAR(190) NOT NULL,
empresa VARCHAR(190) NOT NULL,
email VARCHAR(190) NOT NULL,
mensaje TEXT NULL,
ip VARCHAR(60) NULL,
leido TINYINT(1) NOT NULL DEFAULT 0,
fecha DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) {$charset_collate};";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta( $sql );
}
/* ---------------------------------------------------------------------
* 2) Endpoint AJAX: recibe el envío del formulario (visitantes + logueados)
* ------------------------------------------------------------------- */
add_action( 'wp_ajax_nifty_contact_submit', 'nifty_cw_handle_submit' );
add_action( 'wp_ajax_nopriv_nifty_contact_submit', 'nifty_cw_handle_submit' );
function nifty_cw_handle_submit() {
// No usamos el "die" automático para poder devolver siempre JSON prolijo al front.
if ( ! check_ajax_referer( 'nifty_contact_form', 'nifty_contact_nonce', false ) ) {
wp_send_json_error( array( 'message' => 'Tu sesión expiró, recargá la página e intentá de nuevo.' ) );
return;
}
// Honeypot anti-spam: si este campo oculto viene con valor, es un bot.
// Respondemos "éxito" igual para no delatarle al bot que fue detectado.
if ( ! empty( $_POST['nifty_hp'] ) ) {
wp_send_json_success( array( 'message' => 'Listo — recibimos tus datos. Te contactamos a la brevedad.' ) );
return;
}
$nombre = isset( $_POST['nombre'] ) ? sanitize_text_field( wp_unslash( $_POST['nombre'] ) ) : '';
$empresa = isset( $_POST['empresa'] ) ? sanitize_text_field( wp_unslash( $_POST['empresa'] ) ) : '';
$email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
$mensaje = isset( $_POST['mensaje'] ) ? sanitize_textarea_field( wp_unslash( $_POST['mensaje'] ) ) : '';
if ( empty( $nombre ) || empty( $empresa ) || empty( $email ) || ! is_email( $email ) ) {
wp_send_json_error( array( 'message' => 'Revisá los datos: nombre, empresa y un email válido son obligatorios.' ) );
return;
}
global $wpdb;
$table = $wpdb->prefix . NIFTY_CW_TABLE;
$inserted = $wpdb->insert(
$table,
array(
'nombre' => $nombre,
'empresa' => $empresa,
'email' => $email,
'mensaje' => $mensaje,
'ip' => isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( $_SERVER['REMOTE_ADDR'] ) : '',
'leido' => 0,
'fecha' => current_time( 'mysql' ),
),
array( '%s', '%s', '%s', '%s', '%s', '%d', '%s' )
);
if ( false === $inserted ) {
wp_send_json_error( array( 'message' => 'No pudimos guardar tu mensaje. Probá de nuevo en un momento.' ) );
return;
}
nifty_cw_send_team_notification( $nombre, $empresa, $email, $mensaje );
nifty_cw_send_user_confirmation( $nombre, $email );
wp_send_json_success( array( 'message' => '¡Listo! Recibimos tus datos, te contactamos a la brevedad.' ) );
}
/* ---------------------------------------------------------------------
* 3) Emails
* ------------------------------------------------------------------- */
function nifty_cw_mail_headers() {
$domain = preg_replace( '#^https?://(www\.)?#', '', get_site_url() );
$domain = preg_replace( '#/.*$#', '', $domain );
return array(
'Content-Type: text/html; charset=UTF-8',
'From: Nifty Agency
',
);
}
function nifty_cw_send_team_notification( $nombre, $empresa, $email, $mensaje ) {
$subject = sprintf( 'Nuevo contacto web: %s (%s)', $nombre, $empresa );
$admin_url = admin_url( 'admin.php?page=nifty-web-contacts' );
$body = '';
$body .= '
';
$body .= '
Nifty · nuevo contacto web
';
$body .= '
';
$body .= '
Nuevo formulario completado
';
$body .= '
';
$body .= '| Nombre | ' . esc_html( $nombre ) . ' |
';
$body .= '| Empresa | ' . esc_html( $empresa ) . ' |
';
$body .= '| Email | ' . esc_html( $email ) . ' |
';
$body .= '| Mensaje | ' . nl2br( esc_html( $mensaje ) ) . ' |
';
$body .= '
';
$body .= '
Ver en el listado de contactos →
';
$body .= '
';
wp_mail( NIFTY_CW_TEAM_EMAILS, $subject, $body, nifty_cw_mail_headers() );
}
function nifty_cw_send_user_confirmation( $nombre, $email ) {
$subject = '¡Gracias por escribirnos, ' . $nombre . '! — Nifty Agency';
$site_name = get_bloginfo( 'name' ) ? get_bloginfo( 'name' ) : 'Nifty Agency';
$body = '';
$body .= '
';
$body .= '
';
$body .= '
n
';
$body .= '
Nifty
';
$body .= '
';
$body .= '
';
$body .= '
¡Hola ' . esc_html( $nombre ) . '! 👋
';
$body .= '
Gracias por escribirnos. Ya recibimos tus datos y en breve alguien de nuestro equipo se va a poner en contacto con vos para coordinar una primera reunión de diagnóstico, sin costo y sin compromiso.
';
$body .= '
';
$body .= '
Mientras tanto, esto es lo que sigue:
';
$body .= '
✓ Revisamos tu mensaje y tu rubro
';
$body .= '
✓ Te contactamos para coordinar una reunión
';
$body .= '
✓ Te llevamos un primer diagnóstico de tu situación actual
';
$body .= '
';
$body .= '
Si tenés algo urgente, podés responder directamente a este correo.
';
$body .= '
';
$body .= '
';
$body .= '
' . esc_html( $site_name ) . ' · Este es un correo automático de confirmación.
';
$body .= '
';
$body .= '
';
wp_mail( $email, $subject, $body, nifty_cw_mail_headers() );
}
/* ---------------------------------------------------------------------
* 4) Menú de administración: Listado de Contactos Web
* ------------------------------------------------------------------- */
add_action( 'admin_menu', 'nifty_cw_admin_menu' );
function nifty_cw_admin_menu() {
add_menu_page(
'Listado de Contactos Web',
'Listado de Contactos Web',
'manage_options',
'nifty-web-contacts',
'nifty_cw_render_admin_page',
'dashicons-email-alt',
26
);
}
function nifty_cw_render_admin_page() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
global $wpdb;
$table = $wpdb->prefix . NIFTY_CW_TABLE;
// Marcar un contacto como leído.
if ( isset( $_GET['nifty_cw_mark_read'], $_GET['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'nifty_cw_mark_read' ) ) {
$wpdb->update( $table, array( 'leido' => 1 ), array( 'id' => absint( $_GET['nifty_cw_mark_read'] ) ) );
}
$per_page = 20;
$paged = isset( $_GET['paged'] ) ? max( 1, absint( $_GET['paged'] ) ) : 1;
$offset = ( $paged - 1 ) * $per_page;
$total = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$table}" );
$rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} ORDER BY fecha DESC LIMIT %d OFFSET %d", $per_page, $offset ) );
echo 'Listado de Contactos Web
';
echo '
Contactos recibidos desde el formulario de la Home (' . intval( $total ) . ' en total).
';
echo '
';
echo '| Fecha | Nombre | Empresa | Email | Mensaje | Estado |
';
if ( $rows ) {
foreach ( $rows as $row ) {
$mark_url = wp_nonce_url( admin_url( 'admin.php?page=nifty-web-contacts&nifty_cw_mark_read=' . $row->id ), 'nifty_cw_mark_read' );
echo '';
echo '| ' . esc_html( date_i18n( 'd/m/Y H:i', strtotime( $row->fecha ) ) ) . ' | ';
echo '' . esc_html( $row->nombre ) . ' | ';
echo '' . esc_html( $row->empresa ) . ' | ';
echo '' . esc_html( $row->email ) . ' | ';
echo '' . esc_html( wp_trim_words( $row->mensaje, 14 ) ) . ' | ';
echo '' . ( $row->leido ? 'Leído' : 'Nuevo — marcar leído' ) . ' | ';
echo '
';
}
} else {
echo '| Todavía no hay contactos. |
';
}
echo '
';
$total_pages = (int) ceil( $total / $per_page );
if ( $total_pages > 1 ) {
echo '
';
for ( $i = 1; $i <= $total_pages; $i++ ) {
$url = add_query_arg(
array(
'page' => 'nifty-web-contacts',
'paged' => $i,
),
admin_url( 'admin.php' )
);
$style = $i === $paged ? 'font-weight:700;' : '';
echo '
' . intval( $i ) . '';
}
echo '
';
}
echo '
';
}
/* ---------------------------------------------------------------------
* 5) Helpers para usar desde la plantilla del front (nifty-home.php)
* ------------------------------------------------------------------- */
function nifty_cw_nonce_field() {
wp_nonce_field( 'nifty_contact_form', 'nifty_contact_nonce' );
}
function nifty_cw_ajax_url() {
return esc_url( admin_url( 'admin-ajax.php' ) );
}