HEX
Server: Apache
System: Linux vpshost11508.publiccloud.com.br 5.15.179-grsec-vpshost-10.lc.el8.x86_64 #1 SMP Mon Apr 7 12:04:45 -03 2025 x86_64
User: wicomm2 (10002)
PHP: 8.3.0
Disabled: apache_child_terminate,dl,escapeshellarg,escapeshellcmd,exec,link,mail,openlog,passthru,pcntl_alarm,pcntl_exec,pcntl_fork,pcntl_get_last_error,pcntl_getpriority,pcntl_setpriority,pcntl_signal,pcntl_signal_dispatch,pcntl_sigprocmask,pcntl_sigtimedwait,pcntl_sigwaitinfo,pcntl_strerror,pcntl_wait,pcntl_waitpid,pcntl_wexitstatus,pcntl_wifexited,pcntl_wifsignaled,pcntl_wifstopped,pcntl_wstopsig,pcntl_wtermsig,php_check_syntax,php_strip_whitespace,popen,proc_close,proc_open,shell_exec,symlink,system
Upload Files
File: /home/wicomm2/public_html/blackfriday/leads.php
<?php
session_start();

// /leads.php

require_once __DIR__ . '/config/config.php';

// Define ACCESS_TOKEN se ainda não estiver definido
if (!defined('ACCESS_TOKEN')) {
    define('ACCESS_TOKEN', 'sQJM7EUk1KppTMCc8bySbupO8K9HsYAQaRKTsDzTitRpEHxFrZOh6IrFJ6jJVjIL');
}

@date_default_timezone_set(defined('APP_TIMEZONE') ? APP_TIMEZONE : 'America/Sao_Paulo');

/* Escapador simples (caso não exista no seu bootstrap) */
if (!function_exists('esc')) {
  function esc($s) { return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
}

/* Cliente GET da VTEX (caso ainda não tenha sido definido em outro include) */
if (!function_exists('vtex_api_get')) {
    function vtex_api_get(string $path, string $query = ''): array {
        $account   = VTEX_ACCOUNT;
        $env       = VTEX_ENVIRONMENT;
        $appKey    = VTEX_APPKEY;
        $appToken  = VTEX_APPTOKEN;

        $url = "https://{$account}.{$env}.com.br{$path}";
        if ($query !== '') {
            $url .= (str_contains($url, '?') ? '&' : '?') . $query;
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => [
                "X-VTEX-API-AppKey: {$appKey}",
                "X-VTEX-API-AppToken: {$appToken}"
            ],
            CURLOPT_TIMEOUT => 20,
        ]);
        $res = curl_exec($ch);
        $err = curl_error($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($err) {
            return [null, "cURL error: {$err}"];
        }
        if ($status >= 400) {
            return [null, "HTTP {$status}: {$res}"];
        }

        $data = json_decode($res, true);
        if (!is_array($data)) {
            return [null, "Invalid JSON: {$res}"];
        }
        return [$data, null];
    }
}

// ====== AUTH POR TOKEN (form + session) ======
if (!isset($_SESSION['bf_leads_auth']) || $_SESSION['bf_leads_auth'] !== true) {
  $errMsg = '';
  if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    $typed = trim($_POST['access_token'] ?? '');
    if ($typed === ACCESS_TOKEN) {
      $_SESSION['bf_leads_auth'] = true;
      header('Location: leads.php');
      exit;
    } else {
      $errMsg = 'Token inválido. Tente novamente.';
    }
  }
  ?>
  <!doctype html>
  <html lang="pt-br">
    <head>
      <meta charset="utf-8" />
      <meta name="viewport" content="width=device-width,initial-scale=1" />
      <title>Acesso restrito</title>
      <style>
        body{margin:0;background:#0b0d10;color:#e6eef7;font:14px/1.5 ui-sans-serif,system-ui,Segoe UI,Roboto}
        .wrap{max-width:480px;margin:10vh auto;padding:24px}
        .card{background:#12161b;border:1px solid #1f2731;border-radius:12px;padding:24px}
        .muted{color:#8ea0b4}
        form{display:grid;gap:12px;margin-top:12px}
        input[type=password]{width:100%;padding:10px;border-radius:8px;border:1px solid #314056;background:#0f141a;color:#e6eef7}
        .btn{display:inline-block;padding:10px 14px;border-radius:8px;background:#2b5cff;color:#fff;text-decoration:none;border:0;cursor:pointer}
        .err{color:#ffb4b4;margin:8px 0 0}
      </style>
    </head>
    <body>
      <div class="wrap">
        <div class="card">
          <h1 style="margin:0 0 8px">Acesso restrito</h1>
          <p class="muted">Insira o token de acesso para visualizar os leads.</p>
          <?php if ($errMsg): ?><div class="err"><?= esc($errMsg) ?></div><?php endif; ?>
          <form method="post" action="leads.php">
            <label for="access_token" class="muted">Token</label>
            <input type="password" id="access_token" name="access_token" autocomplete="off" autofocus />
            <button class="btn" type="submit">Entrar</button>
          </form>
        </div>
      </div>
    </body>
  </html>
  <?php
  exit;
}

if (isset($_GET['logout'])) {
  $_SESSION['bf_leads_auth'] = false;
  unset($_SESSION['bf_leads_auth']);
  header('Location: leads.php');
  exit;
}

// ====== BUSCA NO MASTER DATA (BF) ======
$pageSize = 20;
$page = max(1, intval($_GET['page'] ?? 1));
$from = ($page - 1) * $pageSize;

/**
 * Primeira tentativa: com created_at no _fields e sort por created_at desc
 */
$fieldsPrimary = 'id,email,site,maturidade,created_at';
$queryPrimary = '_fields=' . rawurlencode($fieldsPrimary)
      . '&_size=' . intval($pageSize)
      . '&_from=' . intval($from)
      . '&_sort=' . rawurlencode('created_at desc');

[$rows, $err] = vtex_api_get('/api/dataentities/' . VTEX_DATA_ENTITY . '/search', $queryPrimary);

/**
 * Fallback automático:
 * Se o erro indicar que o campo não existe, refaz a consulta
 * - sem created_at em _fields
 * - com sort por id desc
 */
if ($err && str_contains($err, 'Field created_at not found')) {
  $fieldsFallback = 'id,email,site,maturidade';
  $queryFallback = '_fields=' . rawurlencode($fieldsFallback)
        . '&_size=' . intval($pageSize)
        . '&_from=' . intval($from)
        . '&_sort=' . rawurlencode('id desc');
  [$rows, $err] = vtex_api_get('/api/dataentities/' . VTEX_DATA_ENTITY . '/search', $queryFallback);
}

// Se ainda assim falhar, tenta sem _fields nem _sort (traz o doc inteiro — 20 itens)
if ($err) {
  $queryLoose = '_size=' . intval($pageSize) . '&_from=' . intval($from);
  [$rows, $err] = vtex_api_get('/api/dataentities/' . VTEX_DATA_ENTITY . '/search', $queryLoose);
}

// Garante array
if (!is_array($rows)) $rows = [];

// ====== HTML (tabela de leads) ======
?>
<!doctype html>
<html lang="pt-br">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>Leads — Master Data (BF)</title>
  <style>
    :root {
      --bg: #0b0d10;
      --card: #12161b;
      --muted: #8ea0b4;
      --text: #e6eef7;
      --line: #1f2731;
      --cta: #2b5cff;
    }
    * { box-sizing: border-box }
    body { margin: 0; background: var(--bg); color: var(--text); font: 14px/1.5 ui-sans-serif, system-ui, Segoe UI, Roboto }
    header { padding: 24px; border-bottom: 1px solid var(--line) }
    main { max-width: 1200px; margin: 0 auto; padding: 24px }
    .muted { color: var(--muted) }
    .table-wrap { background: var(--card); border: 1px solid var(--line); border-radius: 12px; overflow: auto }
    table { width: 100%; border-collapse: collapse; min-width: 800px }
    th, td { padding: 12px 14px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top }
    th { font-weight: 700; color: #cfe3ff; background: #0f141a }
    tr:hover td { background: #0f141a }
    .btn { display: inline-block; padding: 8px 12px; border-radius: 8px; background: var(--cta); color: #fff; text-decoration: none }
    .badge { display: inline-block; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); background: #0f141a }
    .topbar { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin: 0 0 16px }
    code.small { font-size: 12px; color: #a9b8cb }
  </style>
</head>

<body>
  <header>
    <div class="topbar">
      <h1 style="margin:0">Leads — Black Friday (BF)</h1>
      <div class="muted">Conta: <?= VTEX_ACCOUNT ?> • Data Entity: <code class="small"><?= VTEX_DATA_ENTITY ?></code></div>
      <div><a class="btn" href="leads.php?logout=1">Sair</a></div>
    </div>
  </header>
  <main>
    <?php if (!empty($err)): ?>
      <div class="table-wrap" style="padding:16px">
        <div style="color:#ffb4b4"><b>Erro ao carregar:</b> <?= esc($err) ?></div>
      </div>
    <?php endif; ?>

    <div class="table-wrap">
      <table>
        <thead>
          <tr>
            <th style="width:160px">Data</th>
            <th style="width:260px">E-mail</th>
            <th>Loja (site)</th>
            <th style="width:140px">Maturidade</th>
            <th style="width:140px">Ações</th>
          </tr>
        </thead>
        <tbody>
          <?php if (!count($rows)): ?>
            <tr>
              <td colspan="5" class="muted">Nenhum lead encontrado.</td>
            </tr>
          <?php else: ?>
            <?php foreach ($rows as $r):
              $id   = $r['id'] ?? '';
              // tenta achar um campo de data
              $dtRaw = $r['created_at'] ?? ($r['createdAt'] ?? ($r['_creationDate'] ?? ''));
              $fmt = $dtRaw ? @date('d/m/Y H:i', strtotime($dtRaw)) : '—';
              $mail = $r['email'] ?? '—';
              $site = $r['site'] ?? '—';
              $mat  = $r['maturidade'] ?? '—';
              ?>
              <tr>
                <td><?= esc($fmt) ?></td>
                <td><?= esc($mail) ?></td>
                <td><?= esc($site) ?></td>
                <td><span class="badge"><?= esc($mat) ?></span></td>
                <td>
                  <?php if ($id): ?>
                    <a class="btn" href="lead.php?id=<?= esc($id) ?>">Ver detalhes</a>
                  <?php else: ?>
                    <span class="muted">Sem ID</span>
                  <?php endif; ?>
                </td>
              </tr>
            <?php endforeach; ?>
          <?php endif; ?>
        </tbody>
      </table>
    </div>

    <?php
      // Controles de paginação: mostramos "Anterior" se page>1 e "Próxima" se retornou exatamente $pageSize linhas
      $hasPrev = $page > 1;
      $hasNext = count($rows) === $pageSize;
    ?>
    <div style="display:flex;justify-content:space-between;align-items:center;margin:12px 0 8px">
      <div class="muted">Página <?= $page ?></div>
      <div style="display:flex;gap:8px">
        <?php if ($hasPrev): ?>
          <a class="btn" href="leads.php?page=<?= $page-1 ?>">« Anterior</a>
        <?php endif; ?>
        <?php if ($hasNext): ?>
          <a class="btn" href="leads.php?page=<?= $page+1 ?>">Próxima »</a>
        <?php endif; ?>
      </div>
    </div>
  </main>
</body>
</html>