table_name = $wpdb->prefix . 'afa_verificame'; // 1. Intento estándar de crear tabla en el admin if ( is_admin() ) { add_action('admin_init', array($this, 'create_or_update_table')); } // 2. Registro del Shortcode [verificame] add_shortcode('verificame', array($this, 'shortcode_callback')); // 3. Carga de Assets (CSS/FA) solo si es necesario add_action('wp_enqueue_scripts', array($this, 'enqueue_assets')); // 4. Inyección de JS en el footer add_action('wp_footer', array($this, 'print_js')); } /** * Carga estilos y librerías externas condicionalmente. */ public function enqueue_assets() { if ( is_admin() ) return; global $post; // Cargar solo si el post contiene el shortcode if ( is_a($post, 'WP_Post') && has_shortcode($post->post_content, 'verificame') ) { // Font Awesome 6.5 wp_enqueue_style( 'font-awesome-6', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css', array(), '6.5.1' ); // CSS Inline personalizado $custom_css = $this->get_inline_css(); wp_add_inline_style('font-awesome-6', $custom_css); } } /** * Retorna el CSS completo para el módulo. */ private function get_inline_css() { return ' /* =========================================== AID FOR AIDS – VERIFÍCAME CONTRATISTAS =========================================== */ .afa-validacion-shell { padding: 40px 15px; background: #f4f7fb; } .afa-validacion-wrapper { max-width: 960px; margin: 0 auto; background: #ffffff; border-radius: 24px; box-shadow: 0 18px 45px rgba(0, 45, 90, 0.18); overflow: hidden; font-family: "Raleway", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } /* Encabezado */ .afa-validacion-header { background: linear-gradient(135deg, #003666, #0082cf); padding: 24px 30px; color: #ffffff; display: flex; align-items: center; gap: 16px; } .afa-validacion-titles h2 { margin: 0; font-size: 26px; font-weight: 700; letter-spacing: 0.03em; } .afa-validacion-titles p { margin: 4px 0 0; font-size: 13px; opacity: 0.9; } /* Cuerpo */ .afa-validacion-body { padding: 26px 28px 30px; } .afa-grid { display: grid; gap: 24px; transition: all 0.3s ease; } .afa-grid.admin-open { grid-template-columns: 1fr 1.3fr; } .afa-grid.admin-closed { grid-template-columns: 1fr; position: relative; } @media (max-width: 900px) { .afa-grid.admin-open { grid-template-columns: 1fr; } } /* Toggle Admin */ .afa-admin-toggle { display: flex; justify-content: flex-end; margin-bottom: 12px; } .afa-admin-toggle-btn { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; border-radius: 999px; padding: 7px 14px; background: #003259; color: #ffffff; border: none; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; transition: background 0.2s; } .afa-admin-toggle-btn:hover { background: #004a85; } /* Animación Panel Admin */ .afa-admin-column { transition: transform .25s ease, opacity .25s ease; } .afa-grid.admin-closed .afa-admin-column { position: absolute; top: 0; right: 0; width: 100%; max-width: 400px; transform: translateX(120%); opacity: 0; pointer-events: none; } /* Tarjetas */ .afa-card { background: #f8fbff; border-radius: 18px; border: 1px solid #e1e9f3; padding: 22px 20px 20px; } .afa-card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .afa-card-header h3 { margin: 0; font-size: 16px; font-weight: 700; color: #003259; text-transform: uppercase; letter-spacing: 0.06em; display: flex; align-items: center; gap: 8px; } .afa-card-header h3 i { color: #0082cf; } .afa-card-header span { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: #8ba5c4; } /* Inputs y Formularios */ .afa-field-group { margin-bottom: 16px; } .afa-label { display: block; font-size: 13px; font-weight: 600; color: #003259; margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.07em; } .afa-input, .afa-select, .afa-file-input { width: 100%; padding: 12px 13px; border-radius: 10px; border: 1px solid #c9d6ea; font-size: 14px; background: #ffffff; box-sizing: border-box; transition: border-color .16s ease, box-shadow .16s ease, transform .07s ease; } .afa-input:focus, .afa-select:focus, .afa-file-input:focus { border-color: #0082cf; box-shadow: 0 0 0 3px rgba(0,130,207,0.1); transform: translateY(-1px); outline: none; } .afa-input[disabled], .afa-select[disabled] { background: #eef2f7; color: #8898aa; cursor: not-allowed; } /* Botones */ .afa-actions { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; } .afa-btn { border: none; border-radius: 999px; padding: 10px 22px; font-size: 14px; font-weight: 700; text-transform: uppercase; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; transition: all .2s ease; text-decoration: none; } .afa-btn i { font-size: 0.9em; } .afa-btn-primary { background: linear-gradient(135deg, #025993, #0082cf); color: #fff; box-shadow: 0 6px 16px rgba(0,90,150,0.35); } .afa-btn-primary:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(0,80,140,0.45); } .afa-btn-secondary { background: #ffffff; border: 1px solid #d5dfef; color: #003259; } .afa-btn-secondary:hover { background: #f7faff; border-color: #b8cadd; } .afa-btn-danger { background: linear-gradient(135deg, #d32f2f, #e53935); color: #ffffff; box-shadow: 0 6px 16px rgba(200,60,60,0.35); } .afa-btn-danger:hover { transform: translateY(-1px); box-shadow: 0 12px 28px rgba(180,40,40,0.45); } .afa-btn-utility { font-size: 12px; padding: 6px 12px; color: #0082cf; background: rgba(0, 130, 207, 0.08); border: none; } .afa-btn-utility:hover { background: rgba(0, 130, 207, 0.15); } /* Alertas */ .afa-alert { margin-top: 12px; padding: 12px 14px; border-radius: 12px; font-size: 14px; font-weight: 600; display: flex; gap: 10px; align-items: center; } .afa-alert-success { background: #e0f7f0; color: #1b5e20; border: 1px solid #8bd7a0; } .afa-alert-error { background: #ffebee; color: #c62828; border: 1px solid #ef9a9a; } /* Tabla de Datos */ .afa-table-wrapper { margin-top: 20px; max-height: 400px; overflow-y: auto; border: 1px solid #e1e9f3; border-radius: 12px; box-shadow: inset 0 2px 4px rgba(0,0,0,0.02); } .afa-data-table { width: 100%; border-collapse: collapse; font-size: 13px; text-align: left; } .afa-data-table thead th { background: #f4f7fb; color: #003259; padding: 12px; position: sticky; top: 0; z-index: 2; font-weight: 700; border-bottom: 2px solid #e1e9f3; white-space: nowrap; } .afa-data-table tbody td { padding: 10px 12px; border-bottom: 1px solid #eee; color: #444; vertical-align: middle; } /* Resultados */ .afa-verif-result { margin-top: 22px; padding: 26px 24px; border-radius: 22px; border: 1px solid #b7e7c7; background: #ffffff; display: flex; gap: 20px; align-items: center; box-shadow: 0 10px 28px rgba(0, 80, 140, 0.08); } .afa-verif-result-success { border-color: #a5d6a7; background: #f1f8e9; } .afa-verif-result-error { border-color: #ef9a9a; background: #ffebee; } .afa-verif-photo { width: 110px; height: 110px; border-radius: 50%; overflow: hidden; background: #ffffff; flex-shrink: 0; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 12px rgba(0,0,0,0.1); } .afa-verif-photo img { width: 100%; height: 100%; object-fit: cover; } .afa-verif-info { line-height:1.5; } .afa-verif-name { font-size: 22px; font-weight: 800; color: #003259; margin-bottom: 4px; display: flex; align-items: center; gap: 8px; } /* Responsive */ @media (max-width: 600px) { .afa-validacion-header { padding: 18px; } .afa-validacion-titles h2 { font-size: 20px; } .afa-validacion-body { padding: 20px 15px; } .afa-verif-result { flex-direction: column; text-align: center; } .afa-verif-name { justify-content: center; } } '; } /** * Imprime el JavaScript necesario para la interactividad del frontend. */ public function print_js() { if ( is_admin() ) return; global $post; if ( is_a($post, 'WP_Post') && has_shortcode($post->post_content, 'verificame') ) { ?> get_var("SHOW TABLES LIKE '{$this->table_name}'"); if ( ! $check_table ) { $this->create_or_update_table(); } // Cargar funciones de usuario si no están disponibles if ( ! function_exists('wp_get_current_user') ) { require_once ABSPATH . 'wp-includes/pluggable.php'; } $es_admin = current_user_can('manage_options'); $consulta = null; $msg_csv = null; $msg_delete = null; $registros = array(); // 1. Procesar Consulta Pública if ( ! empty($_POST['afa_check_nonce']) && wp_verify_nonce($_POST['afa_check_nonce'], 'afa_check_contratista') ) { $consulta = $this->procesar_consulta(); } // 2. Procesar Carga CSV (Solo Admin) if ( $es_admin && ! empty($_POST['afa_csv_nonce']) && wp_verify_nonce($_POST['afa_csv_nonce'], 'afa_csv_upload') ) { $msg_csv = $this->procesar_csv(); } // 3. Procesar Eliminación (Solo Admin) if ( $es_admin && ! empty($_POST['afa_del_nonce']) && wp_verify_nonce($_POST['afa_del_nonce'], 'afa_delete_contratista') ) { $msg_delete = $this->procesar_eliminar(); } $bloquear_form = ($consulta !== null); // 4. Obtener Registros Recientes if ($es_admin) { $registros = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$this->table_name} ORDER BY created_at DESC LIMIT %d", 50 ) ); } $data = array( 'es_admin' => $es_admin, 'consulta' => $consulta, 'msg_csv' => $msg_csv, 'msg_delete' => $msg_delete, 'bloquear_form' => $bloquear_form, 'registros' => $registros, ); return $this->render_view($data); } /* ========================================================= * VISTA (HTML) * ======================================================= */ private function render_view($data) { extract($data); ob_start(); ?>
Usa nuestra herramienta de consulta oficial para confirmar si una persona es un contratista autorizado por nuestra organización.