Publier Globinours 1.0.0-rc.3
This commit is contained in:
parent
ea8c24d622
commit
9a2b4068da
325 changed files with 38230 additions and 20 deletions
272
app/Controllers/PublicSiteController.php
Normal file
272
app/Controllers/PublicSiteController.php
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
final class PublicSiteController
|
||||
{
|
||||
public static function usesRoot(): bool
|
||||
{
|
||||
return AppSettings::get('public_site_routing') === 'root';
|
||||
}
|
||||
public static function handles(string $path): bool
|
||||
{
|
||||
if ($path === '/site' || str_starts_with($path, '/site/')) {
|
||||
return true;
|
||||
}
|
||||
return self::usesRoot() &&
|
||||
in_array(
|
||||
$path,
|
||||
[
|
||||
'/',
|
||||
'/animaux',
|
||||
'/adoption',
|
||||
'/presentation',
|
||||
'/dons',
|
||||
'/contact',
|
||||
'/mentions-legales',
|
||||
'/confidentialite',
|
||||
'/logo-association',
|
||||
],
|
||||
true,
|
||||
);
|
||||
}
|
||||
public static function url(string $page = 'home', array $query = []): string
|
||||
{
|
||||
$root = self::usesRoot();
|
||||
$path = match ($page) {
|
||||
'home' => $root ? '/' : '/site',
|
||||
'animals' => $root ? '/animaux' : '/site/animaux',
|
||||
'animal' => $root ? '/adoption' : '/site/animal',
|
||||
'about' => $root ? '/presentation' : '/site/presentation',
|
||||
'donation' => $root ? '/dons' : '/site/dons',
|
||||
'contact' => $root ? '/contact' : '/site/contact',
|
||||
'legal' => $root ? '/mentions-legales' : '/site/mentions-legales',
|
||||
'privacy' => $root ? '/confidentialite' : '/site/confidentialite',
|
||||
'logo' => $root ? '/logo-association' : '/site/logo',
|
||||
default => $root ? '/' : '/site',
|
||||
};
|
||||
return $path . ($query ? '?' . http_build_query($query) : '');
|
||||
}
|
||||
public static function dispatch(string $path): void
|
||||
{
|
||||
$path = self::normalize($path);
|
||||
if (AppSettings::get('public_site_enabled') !== '1') {
|
||||
http_response_code(404);
|
||||
self::render('public_site_unavailable.php', ['title' => t('public_site.unavailable')]);
|
||||
return;
|
||||
}
|
||||
if ($path === '/site/logo') {
|
||||
self::logo();
|
||||
return;
|
||||
}
|
||||
match ($path) {
|
||||
'/site', '/site/' => self::home(),
|
||||
'/site/animaux' => self::animals(),
|
||||
'/site/animal' => self::animal(),
|
||||
'/site/dons' => self::donation(),
|
||||
'/site/contact' => self::contact(),
|
||||
'/site/presentation' => self::about(),
|
||||
'/site/mentions-legales' => self::legal(),
|
||||
'/site/confidentialite' => self::privacy(),
|
||||
default => self::notFound(),
|
||||
};
|
||||
}
|
||||
private static function normalize(string $path): string
|
||||
{
|
||||
return match ($path) {
|
||||
'/' => '/site',
|
||||
'/animaux' => '/site/animaux',
|
||||
'/adoption' => '/site/animal',
|
||||
'/presentation' => '/site/presentation',
|
||||
'/dons' => '/site/dons',
|
||||
'/contact' => '/site/contact',
|
||||
'/mentions-legales' => '/site/mentions-legales',
|
||||
'/confidentialite' => '/site/confidentialite',
|
||||
'/logo-association' => '/site/logo',
|
||||
default => $path,
|
||||
};
|
||||
}
|
||||
private static function home(): void
|
||||
{
|
||||
$db = DB::pdo();
|
||||
$animals = self::animalQuery('', 8);
|
||||
$counts = $db
|
||||
->query(
|
||||
"SELECT species,COUNT(*) count FROM animals WHERE website_published=1 AND adoption_availability='available' AND archived_at IS NULL AND deleted_at IS NULL AND status NOT IN ('adopte','decede') GROUP BY species ORDER BY species",
|
||||
)
|
||||
->fetchAll(PDO::FETCH_ASSOC);
|
||||
self::render('public_site_home.php', [
|
||||
'title' => AppSettings::get('public_site_home_title'),
|
||||
'animals' => $animals,
|
||||
'speciesCounts' => $counts,
|
||||
]);
|
||||
}
|
||||
private static function animals(): void
|
||||
{
|
||||
$species = SpeciesService::normalize((string) ($_GET['espece'] ?? ''));
|
||||
if ($species !== '' && !SpeciesService::exists($species, false)) {
|
||||
$species = '';
|
||||
}
|
||||
self::render('public_site_animals.php', [
|
||||
'title' => t('public_site.animals'),
|
||||
'animals' => self::animalQuery($species, 200),
|
||||
'selectedSpecies' => $species,
|
||||
'publicSpecies' => self::species(),
|
||||
]);
|
||||
}
|
||||
private static function animal(): void
|
||||
{
|
||||
$id = (int) ($_GET['id'] ?? 0);
|
||||
$s = DB::pdo()->prepare(
|
||||
"SELECT a.*,s.name species_name,s.icon species_icon,(SELECT filename FROM animal_photos p WHERE p.animal_id=a.id AND p.is_public=1 ORDER BY p.is_primary DESC,p.id DESC LIMIT 1) primary_photo FROM animals a LEFT JOIN ref_species s ON s.code=a.species WHERE a.id=? AND a.website_published=1 AND a.adoption_availability='available' AND a.archived_at IS NULL AND a.deleted_at IS NULL AND a.status NOT IN ('adopte','decede')",
|
||||
);
|
||||
$s->execute([$id]);
|
||||
$animal = $s->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$animal) {
|
||||
self::notFound();
|
||||
return;
|
||||
}
|
||||
$p = DB::pdo()->prepare(
|
||||
'SELECT filename,caption FROM animal_photos WHERE animal_id=? AND is_public=1 ORDER BY is_primary DESC,id DESC',
|
||||
);
|
||||
$p->execute([$id]);
|
||||
self::render('public_site_animal.php', [
|
||||
'title' => $animal['name'],
|
||||
'animal' => $animal,
|
||||
'photos' => $p->fetchAll(PDO::FETCH_ASSOC),
|
||||
]);
|
||||
}
|
||||
private static function donation(): void
|
||||
{
|
||||
self::render('public_site_text.php', [
|
||||
'title' => AppSettings::get('public_site_donation_title'),
|
||||
'content' => AppSettings::get('public_site_donation_text'),
|
||||
'kind' => 'donation',
|
||||
]);
|
||||
}
|
||||
private static function contact(): void
|
||||
{
|
||||
self::render('public_site_contact.php', ['title' => t('public_site.contact')]);
|
||||
}
|
||||
private static function about(): void
|
||||
{
|
||||
if (AppSettings::get('public_site_about_enabled') !== '1') {
|
||||
self::notFound();
|
||||
return;
|
||||
}
|
||||
self::render('public_site_text.php', [
|
||||
'title' => AppSettings::get('public_site_about_title'),
|
||||
'content' => AppSettings::get('public_site_about_text'),
|
||||
'kind' => 'about',
|
||||
]);
|
||||
}
|
||||
private static function legal(): void
|
||||
{
|
||||
self::render('public_site_text.php', [
|
||||
'title' => t('public_site.legal'),
|
||||
'content' => self::legalText(),
|
||||
'kind' => 'legal',
|
||||
]);
|
||||
}
|
||||
private static function privacy(): void
|
||||
{
|
||||
self::render('public_site_text.php', [
|
||||
'title' => t('public_site.privacy'),
|
||||
'content' => self::privacyText(),
|
||||
'kind' => 'privacy',
|
||||
]);
|
||||
}
|
||||
public static function legalText(?array $settings = null): string
|
||||
{
|
||||
$settings ??= AppSettings::all();
|
||||
$custom = trim((string) ($settings['public_site_legal_text'] ?? ''));
|
||||
if ($custom !== '') {
|
||||
return $custom;
|
||||
}
|
||||
$address =
|
||||
implode(
|
||||
', ',
|
||||
array_filter([
|
||||
$settings['association_address'] ?? '',
|
||||
trim(($settings['association_postal_code'] ?? '') . ' ' . ($settings['association_city'] ?? '')),
|
||||
]),
|
||||
) ?:
|
||||
t('public_site.to_complete');
|
||||
return t('public_site.default_legal', [
|
||||
'association' => $settings['association_name'] ?: t('public_site.to_complete'),
|
||||
'address' => $address,
|
||||
'email' => $settings['association_email'] ?: t('public_site.to_complete'),
|
||||
'rna' => $settings['association_rna'] ?: t('public_site.to_complete'),
|
||||
'siret' => $settings['association_siret'] ?: t('public_site.to_complete'),
|
||||
]);
|
||||
}
|
||||
public static function privacyText(?array $settings = null): string
|
||||
{
|
||||
$settings ??= AppSettings::all();
|
||||
$custom = trim((string) ($settings['public_site_privacy_text'] ?? ''));
|
||||
if ($custom !== '') {
|
||||
return $custom;
|
||||
}
|
||||
$address =
|
||||
implode(
|
||||
', ',
|
||||
array_filter([
|
||||
$settings['association_address'] ?? '',
|
||||
trim(($settings['association_postal_code'] ?? '') . ' ' . ($settings['association_city'] ?? '')),
|
||||
]),
|
||||
) ?:
|
||||
t('public_site.to_complete');
|
||||
return t('public_site.default_privacy', [
|
||||
'association' => $settings['association_name'] ?: t('public_site.to_complete'),
|
||||
'address' => $address,
|
||||
'email' => $settings['association_email'] ?: t('public_site.to_complete'),
|
||||
]);
|
||||
}
|
||||
private static function logo(): void
|
||||
{
|
||||
$path = AssociationBrand::path();
|
||||
if (!$path) {
|
||||
http_response_code(404);
|
||||
return;
|
||||
}
|
||||
$mime = new finfo(FILEINFO_MIME_TYPE)->file($path) ?: 'application/octet-stream';
|
||||
header('Content-Type: ' . $mime);
|
||||
header('Content-Length: ' . filesize($path));
|
||||
header('Cache-Control: public,max-age=3600');
|
||||
readfile($path);
|
||||
}
|
||||
private static function animalQuery(string $species, int $limit): array
|
||||
{
|
||||
$sql =
|
||||
"SELECT a.id,a.name,a.species,a.sex,a.birth_date,a.birth_is_estimated,a.birth_estimated_months,a.breed,a.color,a.sterilization_status,a.compatibility_dogs,a.compatibility_cats,a.compatibility_children,a.house_trained,a.website_description,s.name species_name,s.icon species_icon,(SELECT filename FROM animal_photos p WHERE p.animal_id=a.id AND p.is_public=1 ORDER BY p.is_primary DESC,p.id DESC LIMIT 1) primary_photo FROM animals a LEFT JOIN ref_species s ON s.code=a.species WHERE a.website_published=1 AND a.adoption_availability='available' AND a.archived_at IS NULL AND a.deleted_at IS NULL AND a.status NOT IN ('adopte','decede')";
|
||||
$params = [];
|
||||
if ($species !== '') {
|
||||
$sql .= ' AND a.species=:species';
|
||||
$params[':species'] = $species;
|
||||
}
|
||||
$sql .= ' ORDER BY a.updated_at DESC,a.name COLLATE NOCASE LIMIT ' . max(1, min(500, $limit));
|
||||
$s = DB::pdo()->prepare($sql);
|
||||
$s->execute($params);
|
||||
return $s->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
private static function species(): array
|
||||
{
|
||||
return DB::pdo()
|
||||
->query(
|
||||
"SELECT s.code,s.name,s.icon,COUNT(a.id) count FROM ref_species s JOIN animals a ON a.species=s.code AND a.website_published=1 AND a.adoption_availability='available' AND a.archived_at IS NULL AND a.deleted_at IS NULL AND a.status NOT IN ('adopte','decede') GROUP BY s.id ORDER BY s.sort_order,s.name COLLATE NOCASE",
|
||||
)
|
||||
->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
private static function render(string $view, array $vars = []): void
|
||||
{
|
||||
extract($vars, EXTR_SKIP);
|
||||
$settings = AppSettings::all();
|
||||
$publicSpecies = self::species();
|
||||
require dirname(__DIR__) . '/Views/public_site_layout.php';
|
||||
}
|
||||
private static function notFound(): void
|
||||
{
|
||||
http_response_code(404);
|
||||
self::render('public_site_unavailable.php', ['title' => t('public_site.not_found')]);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue