idk
This commit is contained in:
1 parent
e68d357177
commit
3e3382df57
65 files changed
+1836
-42
No files matched your search
+237
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
// ── Event landing page ──────────────────────────────────────────────────────
|
||||
// Branded, time-limited landing page reached at /evento/<slug> (see .htaccess).
|
||||
// Visible to the public only while the event is live (db_events_active rule);
|
||||
// logged-in staff may preview drafts/scheduled/expired events. Carries an
|
||||
// optional lead-capture form that stores submissions in event_leads.
|
||||
require_once __DIR__ . '/../config/db.php';
|
||||
require_once __DIR__ . '/../config/functions.php';
|
||||
|
||||
// Resolve any SSO session up front (mirrors _open.php) so the is_staff() preview
|
||||
// gate below sees a logged-in admin. _open.php's later call then no-ops.
|
||||
if (empty($_SESSION['user_id']) && identity_is_federated()) {
|
||||
sso_resolve_session($pdo);
|
||||
}
|
||||
|
||||
$slug = preg_replace('/[^a-z0-9\-]/', '', strtolower((string) ($_GET['slug'] ?? '')));
|
||||
$event = $slug !== '' ? db_events_get_by_slug($pdo, $slug) : null;
|
||||
|
||||
// Gate: live for everyone, otherwise only staff (preview).
|
||||
$can_view = $event && (events_is_live($event) || is_staff());
|
||||
|
||||
// ── Lead form submission (PRG) ──────────────────────────────────────────────
|
||||
$lead_errors = [];
|
||||
if ($can_view && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
csrf_check();
|
||||
$back = base_url('evento/' . rawurlencode($event['slug']));
|
||||
|
||||
// Honeypot: a filled "website" field means a bot — silently accept & drop.
|
||||
if (trim((string) ($_POST['website'] ?? '')) !== '') {
|
||||
header('Location: ' . $back . '?ok=1#inscricao');
|
||||
exit;
|
||||
}
|
||||
|
||||
// The exact wording the visitor consents to — stored for GDPR evidence.
|
||||
$consent_text = 'Autorizo o contacto e o tratamento dos meus dados para efeitos desta inscrição, nos termos da Política de Privacidade.';
|
||||
$lead = [
|
||||
'name' => trim((string) ($_POST['lead_name'] ?? '')),
|
||||
'email' => trim((string) ($_POST['lead_email'] ?? '')),
|
||||
'phone' => trim((string) ($_POST['lead_phone'] ?? '')),
|
||||
'message' => trim((string) ($_POST['lead_message'] ?? '')),
|
||||
'consent' => !empty($_POST['lead_consent']) ? 1 : 0,
|
||||
'consent_text' => $consent_text,
|
||||
// First hop of X-Forwarded-For (behind the id.andmore.pt proxy), else peer.
|
||||
'ip' => trim(explode(',', (string) ($_SERVER['HTTP_X_FORWARDED_FOR'] ?? ''))[0]) ?: ($_SERVER['REMOTE_ADDR'] ?? ''),
|
||||
'user_agent' => (string) ($_SERVER['HTTP_USER_AGENT'] ?? ''),
|
||||
];
|
||||
if ($lead['name'] === '') $lead_errors[] = 'Indica o teu nome.';
|
||||
if ($lead['email'] === '' && $lead['phone'] === '') $lead_errors[] = 'Indica um email ou um telefone para te podermos contactar.';
|
||||
if ($lead['email'] !== '' && !filter_var($lead['email'], FILTER_VALIDATE_EMAIL)) $lead_errors[] = 'O email indicado não é válido.';
|
||||
if (!$lead['consent']) $lead_errors[] = 'É necessário aceitar o tratamento dos dados para enviar a inscrição.';
|
||||
|
||||
if (!$lead_errors) {
|
||||
db_event_lead_create($pdo, (int) $event['e_id'], $lead);
|
||||
header('Location: ' . $back . '?ok=1#inscricao');
|
||||
exit;
|
||||
}
|
||||
// fall through and re-render with $lead_errors + the submitted $lead values
|
||||
$lead_old = $lead;
|
||||
}
|
||||
|
||||
// ── Not found / not visible ─────────────────────────────────────────────────
|
||||
if (!$can_view) {
|
||||
http_response_code(404);
|
||||
$current_uri_2 = '';
|
||||
require __DIR__ . '/_open.php';
|
||||
?>
|
||||
<section class="event-notfound" style="padding:160px 0 90px;text-align:center;">
|
||||
<div class="container">
|
||||
<h1 style="font-size:2.4rem;">Evento não encontrado</h1>
|
||||
<p class="text-muted">Este evento pode já ter terminado ou o link estar incorreto.</p>
|
||||
<a href="<?= base_url('/') ?>" class="site-btn mt-3">Voltar ao início</a>
|
||||
</div>
|
||||
</section>
|
||||
<?php
|
||||
echo view('footer');
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Visible: render the landing page ────────────────────────────────────────
|
||||
$is_preview = !events_is_live($event);
|
||||
$hero_url = $event['hero_image'] !== '' ? base_url('uploads/events/' . rawurlencode($event['hero_image'])) : '';
|
||||
$accent = $event['cor'] !== '' ? $event['cor'] : '#C2D500';
|
||||
|
||||
// Human date line for the event window.
|
||||
$date_line = '';
|
||||
if (!empty($event['event_starts_at'])) {
|
||||
$date_line = format_date_pt((string) $event['event_starts_at']);
|
||||
if (!empty($event['event_ends_at'])
|
||||
&& substr((string) $event['event_ends_at'], 0, 10) !== substr((string) $event['event_starts_at'], 0, 10)) {
|
||||
$date_line .= ' – ' . format_date_pt((string) $event['event_ends_at']);
|
||||
}
|
||||
}
|
||||
|
||||
// CTA target: explicit URL, else the on-page form (when shown), else contacts.
|
||||
$cta_label = trim((string) $event['cta_label']);
|
||||
$cta_href = trim((string) $event['cta_url']);
|
||||
if ($cta_href === '') {
|
||||
$cta_href = ((int) $event['show_lead_form'] === 1) ? '#inscricao' : base_url('home/contactos');
|
||||
}
|
||||
|
||||
// ── SEO ─────────────────────────────────────────────────────────────────────
|
||||
// include.php / seo.php honour these globals when set before _open.php runs.
|
||||
$event_url = base_url('evento/' . rawurlencode($event['slug']));
|
||||
$seo_desc = $event['summary'] !== ''
|
||||
? $event['summary']
|
||||
: trim(mb_substr(strip_tags((string) ($event['subtitle'] ?: $event['description'])), 0, 200));
|
||||
|
||||
$current_uri_2 = 'evento';
|
||||
$GLOBALS['_page_meta_override'] = [
|
||||
($event['title'] !== '' ? $event['title'] : 'Evento') . ' | FitMe 3070',
|
||||
$seo_desc,
|
||||
];
|
||||
$GLOBALS['_canonical_override'] = $event_url;
|
||||
$GLOBALS['_og_type_override'] = 'article';
|
||||
if ($hero_url !== '') $GLOBALS['_og_image_override'] = $hero_url;
|
||||
|
||||
// Event structured data (schema.org/Event) for rich link previews / search.
|
||||
$info = site_info($pdo);
|
||||
$ld_event = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'Event',
|
||||
'name' => $event['title'],
|
||||
'description' => $seo_desc !== '' ? $seo_desc : $event['title'],
|
||||
'url' => $event_url,
|
||||
'eventStatus' => 'https://schema.org/EventScheduled',
|
||||
'eventAttendanceMode' => 'https://schema.org/OfflineEventAttendanceMode',
|
||||
];
|
||||
if ($hero_url !== '') $ld_event['image'] = [$hero_url];
|
||||
if (!empty($event['event_starts_at'])) $ld_event['startDate'] = str_replace(' ', 'T', (string) $event['event_starts_at']);
|
||||
if (!empty($event['event_ends_at'])) $ld_event['endDate'] = str_replace(' ', 'T', (string) $event['event_ends_at']);
|
||||
$ld_event['location'] = $event['location'] !== ''
|
||||
? ['@type' => 'Place', 'name' => $event['location']]
|
||||
: ['@type' => 'Place',
|
||||
'name' => ($info['name'] ?? '') !== '' ? $info['name'] : 'FitMe 3070',
|
||||
'address' => $info['adress'] ?? ''];
|
||||
$ld_event['organizer'] = [
|
||||
'@type' => 'Organization',
|
||||
'name' => ($info['name'] ?? '') !== '' ? $info['name'] : 'FitMe 3070',
|
||||
'url' => base_url(),
|
||||
];
|
||||
$GLOBALS['_jsonld_extra'] = $ld_event;
|
||||
|
||||
require __DIR__ . '/_open.php';
|
||||
?>
|
||||
<?php if ($is_preview): ?>
|
||||
<div class="event-preview-bar">Pré-visualização — este evento não está visível ao público (<?= htmlspecialchars(events_status($event)) ?>).</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<section class="event-hero set-bg<?= $hero_url ? '' : ' event-hero--plain' ?>"
|
||||
<?= $hero_url ? 'style="background-image:url(\'' . htmlspecialchars($hero_url, ENT_QUOTES) . '\')"' : '' ?>>
|
||||
<div class="event-hero-overlay"></div>
|
||||
<div class="container">
|
||||
<div class="event-hero-inner">
|
||||
<span class="event-hero-eyebrow" style="color:<?= htmlspecialchars($accent, ENT_QUOTES) ?>">Evento</span>
|
||||
<h1><?= htmlspecialchars($event['title']) ?></h1>
|
||||
<?php if ($event['subtitle'] !== ''): ?><p class="event-hero-sub"><?= htmlspecialchars($event['subtitle']) ?></p><?php endif; ?>
|
||||
<ul class="event-hero-meta">
|
||||
<?php if ($date_line !== ''): ?><li><i class="fas fa-calendar-alt"></i> <?= htmlspecialchars($date_line) ?></li><?php endif; ?>
|
||||
<?php if ($event['location'] !== ''): ?><li><i class="fas fa-map-marker-alt"></i> <?= htmlspecialchars($event['location']) ?></li><?php endif; ?>
|
||||
</ul>
|
||||
<?php if ($cta_label !== ''): ?>
|
||||
<a href="<?= htmlspecialchars($cta_href, ENT_QUOTES) ?>" class="site-btn event-hero-cta"
|
||||
style="background:<?= htmlspecialchars($accent, ENT_QUOTES) ?>"
|
||||
<?= ($cta_href[0] ?? '') === '#' ? 'data-scroll' : '' ?>><?= htmlspecialchars($cta_label) ?></a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php if (trim((string) $event['description']) !== ''): ?>
|
||||
<section class="event-body">
|
||||
<div class="container">
|
||||
<div class="row justify-content-md-center">
|
||||
<div class="col-lg-8">
|
||||
<?php /* description is admin-authored HTML — sanitised allowlist HTML */ ?>
|
||||
<?= clean_richtext($event['description']) ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ((int) $event['show_lead_form'] === 1): ?>
|
||||
<section class="event-leadform" id="inscricao">
|
||||
<div class="container">
|
||||
<div class="row justify-content-md-center">
|
||||
<div class="col-lg-7">
|
||||
<div class="section-title text-center deco">
|
||||
<span class="section-eyebrow">Participa</span>
|
||||
<h2>Inscreve-te</h2>
|
||||
<p class="section-subtitle">Deixa os teus dados e entramos em contacto.</p>
|
||||
</div>
|
||||
|
||||
<?php if (isset($_GET['ok'])): ?>
|
||||
<div class="event-alert event-alert--ok">Inscrição enviada com sucesso. Obrigado!</div>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($lead_errors as $e): ?>
|
||||
<div class="event-alert event-alert--err"><?= htmlspecialchars($e) ?></div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<form method="POST" action="<?= base_url('evento/' . rawurlencode($event['slug'])) ?>#inscricao" class="event-form">
|
||||
<?= csrf_field() ?>
|
||||
<!-- honeypot: must stay empty -->
|
||||
<input type="text" name="website" tabindex="-1" autocomplete="off" class="event-hp" aria-hidden="true">
|
||||
<div class="event-form-grid">
|
||||
<div class="event-field">
|
||||
<label>Nome *</label>
|
||||
<input type="text" name="lead_name" required maxlength="150" value="<?= htmlspecialchars($lead_old['name'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="event-field">
|
||||
<label>Telefone</label>
|
||||
<input type="tel" name="lead_phone" maxlength="40" value="<?= htmlspecialchars($lead_old['phone'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="event-field event-field--full">
|
||||
<label>Email</label>
|
||||
<input type="email" name="lead_email" maxlength="190" value="<?= htmlspecialchars($lead_old['email'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="event-field event-field--full">
|
||||
<label>Mensagem</label>
|
||||
<textarea name="lead_message" rows="3" maxlength="1000"><?= htmlspecialchars($lead_old['message'] ?? '') ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<label class="event-consent">
|
||||
<input type="checkbox" name="lead_consent" value="1" required <?= !empty($lead_old['consent']) ? 'checked' : '' ?>>
|
||||
<span>Autorizo o contacto e o tratamento dos meus dados para esta inscrição, nos termos da <a href="<?= base_url('home/privacidade') ?>" target="_blank" rel="noopener">Política de Privacidade</a>.</span>
|
||||
</label>
|
||||
<div class="text-center mt-3">
|
||||
<button type="submit" class="site-btn" style="background:<?= htmlspecialchars($accent, ENT_QUOTES) ?>">Enviar inscrição</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
echo view('footer');
|
||||
Reference in new issue
Block a user