Version stable, aprelic, connexion CFRS et autres corrections
This commit is contained in:
1 parent
865de8a976
commit
e9d0010451
62 files changed
+17483
-7256
No files matched your search
@@ -910,3 +910,34 @@ a {
|
||||
border-color: #e03c3f;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.menu-item-form {
|
||||
padding: 0 !important;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.menu-logout-form {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.menu-logout-btn {
|
||||
all: unset;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 12px 16px;
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.menu-logout-btn:hover {
|
||||
background: #f3f4f6;
|
||||
}
|
||||
|
||||
.menu-logout-btn:focus-visible {
|
||||
outline: 2px solid #94a3b8;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
// Évite la boucle quand router.php inclut la page
|
||||
if (defined('ROUTED_PRETTY')) return;
|
||||
|
||||
// Mapping vilain -> joli
|
||||
$UGLY_TO_PRETTY = [
|
||||
//racine
|
||||
'/index.php' => '/',
|
||||
'/result_search.php' => '/recherche',
|
||||
'/detail_public.php' => '/specialistes',
|
||||
'/connexion.php' => '/login',
|
||||
'/choix_inscr.php' => '/choix-inscription',
|
||||
'/inscription_client.php' => '/inscription-client',
|
||||
'/inscription_praticien.php' => '/inscription-praticien',
|
||||
'/mdp_oublie.php' => '/mot-de-passe-oublie',
|
||||
'/avis_public.php' => '/avis',
|
||||
//dossier client
|
||||
'/public/client/informations.php' => '/profil',
|
||||
'/public/client/modifier.php' => '/modifier-profil',
|
||||
'/public/client/compte.php' => '/mon-compte',
|
||||
'/public/client/list_praticien.php' => '/trouver-specialistes',
|
||||
'/public/client/mes_favori.php' => '/mes-preferences',
|
||||
'/public/client/detail_praticien.php' => '/specialiste',
|
||||
'/public/client/avis.php' => '/donner-avis',
|
||||
'/public/client/reserver_rdv.php' => '/reservation',
|
||||
'/public/client/mes_rendez_vous.php' => '/mes-rendez-vous',
|
||||
|
||||
//Dossier praticien
|
||||
'/public/praticien/informations.php' => '/profil-pro',
|
||||
'/public/praticien/modifier.php' => '/modifier-profil-pro',
|
||||
'/public/praticien/compte.php' => '/mon-compte-pro',
|
||||
'/public/praticien/disponibilites.php' => '/mes-creneaux',
|
||||
'/public/praticien/disponibilites_date.php' => '/mes-creneaux-date',
|
||||
'/public/praticien/rendez_vous.php' => '/mes-consultations',
|
||||
'/public/praticien/rendez_vous_du_jour.php' => '/consultations-du-jour',
|
||||
'/public/praticien/agenda.php' => '/agenda',
|
||||
'/public/praticien/synchronisation.php' => '/connecter-agenda',
|
||||
'/public/praticien/resiliation.php' => '/abonnement',
|
||||
'/public/praticien/factures.php' => '/mes-factures',
|
||||
|
||||
//Dossier messages
|
||||
|
||||
];
|
||||
|
||||
// Debug : ajouter ?_noredir=1 pour désactiver la redirection
|
||||
if (!empty($_GET['_noredir'])) return;
|
||||
|
||||
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ?? '/';
|
||||
|
||||
if (isset($UGLY_TO_PRETTY[$path])) {
|
||||
$target = $UGLY_TO_PRETTY[$path];
|
||||
$qs = $_SERVER['QUERY_STRING'] ? ('?' . $_SERVER['QUERY_STRING']) : '';
|
||||
header('Location: ' . $target . $qs, true, 301);
|
||||
exit;
|
||||
}
|
||||
+82
-22
@@ -1,29 +1,30 @@
|
||||
<?php
|
||||
// Évite la boucle quand router.php inclut la page
|
||||
if (defined('ROUTED_PRETTY')) return;
|
||||
if (defined('ROUTED_PRETTY')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mapping vilain -> joli
|
||||
$UGLY_TO_PRETTY = [
|
||||
//racine
|
||||
'/index.php' => '/',
|
||||
'/result_search.php' => '/recherche',
|
||||
'/detail_public.php' => '/specialistes',
|
||||
'/connexion.php' => '/login',
|
||||
'/choix_inscr.php' => '/choix-inscription',
|
||||
'/inscription_client.php' => '/inscription-client',
|
||||
'/inscription_praticien.php' => '/inscription-praticien',
|
||||
'/mdp_oublie.php' => '/mot-de-passe-oublie',
|
||||
'/avis_public.php' => '/avis',
|
||||
'/index.php' => '/',
|
||||
'/detail_public.php' => '/specialistes',
|
||||
'/connexion.php' => '/login',
|
||||
'/choix_inscr.php' => '/choix-inscription',
|
||||
'/inscription_client.php' => '/inscription-client',
|
||||
'/inscription_praticien.php' => '/inscription-praticien',
|
||||
'/mdp_oublie.php' => '/mot-de-passe-oublie',
|
||||
'/avis_public.php' => '/avis',
|
||||
//dossier client
|
||||
'/public/client/informations.php' => '/profil',
|
||||
'/public/client/modifier.php' => '/modifier-profil',
|
||||
'/public/client/compte.php' => '/mon-compte',
|
||||
'/public/client/list_praticien.php' => '/trouver-specialistes',
|
||||
'/public/client/mes_favori.php' => '/mes-preferences',
|
||||
'/public/client/detail_praticien.php' => '/specialiste',
|
||||
'/public/client/avis.php' => '/donner-avis',
|
||||
'/public/client/reserver_rdv.php' => '/reservation',
|
||||
'/public/client/mes_rendez_vous.php' => '/mes-rendez-vous',
|
||||
'/public/client/informations.php' => '/profil',
|
||||
'/public/client/modifier.php' => '/modifier-profil',
|
||||
'/public/client/compte.php' => '/mon-compte',
|
||||
'/public/client/list_praticien.php' => '/trouver-specialistes',
|
||||
'/public/client/mes_favori.php' => '/mes-preferences',
|
||||
'/public/client/detail_praticien.php' => '/specialiste',
|
||||
'/public/client/avis.php' => '/donner-avis',
|
||||
'/public/client/reserver_rdv.php' => '/reservation',
|
||||
'/public/client/mes_rendez_vous.php' => '/mes-rendez-vous',
|
||||
|
||||
//Dossier praticien
|
||||
'/public/praticien/informations.php' => '/profil-pro',
|
||||
@@ -37,15 +38,74 @@ $UGLY_TO_PRETTY = [
|
||||
'/public/praticien/synchronisation.php' => '/connecter-agenda',
|
||||
'/public/praticien/resiliation.php' => '/abonnement',
|
||||
'/public/praticien/factures.php' => '/mes-factures',
|
||||
|
||||
|
||||
//Dossier messages
|
||||
|
||||
|
||||
];
|
||||
|
||||
// Debug : ajouter ?_noredir=1 pour désactiver la redirection
|
||||
if (!empty($_GET['_noredir'])) return;
|
||||
if (! empty($_GET['_noredir'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ?? '/';
|
||||
require_once __DIR__ . '/search_helpers.php';
|
||||
|
||||
// Redirection SEO pour result_search.php
|
||||
if ($path === '/result_search.php' || $path === '/recherche') {
|
||||
if (! empty($_GET['ajax'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$specialite = trim((string) ($_GET['specialite'] ?? ''));
|
||||
$ville = trim((string) ($_GET['ville'] ?? ''));
|
||||
|
||||
if ($specialite !== '' || $ville !== '') {
|
||||
$target = '/recherche';
|
||||
|
||||
$specSlug = '';
|
||||
if ($specialite === '__OTHERS__') {
|
||||
$specSlug = 'autres-specialistes';
|
||||
} elseif ($specialite !== '') {
|
||||
$specSlug = seo_spec_slug_from_input($specialite) ?? '';
|
||||
}
|
||||
|
||||
if ($specSlug !== '') {
|
||||
$target .= '/' . rawurlencode($specSlug);
|
||||
}
|
||||
|
||||
$citySlug = '';
|
||||
if ($ville !== '') {
|
||||
$citySlug = seo_city_slug_from_input($ville);
|
||||
}
|
||||
|
||||
if ($citySlug !== '') {
|
||||
if ($specSlug === '') {
|
||||
// si ville seule, on garde la query string pour éviter une structure bancale
|
||||
$target = '/recherche/?' . http_build_query([
|
||||
'specialite' => $specialite,
|
||||
'ville' => $ville,
|
||||
]);
|
||||
header('Location: ' . $target, true, 301);
|
||||
exit;
|
||||
}
|
||||
|
||||
$target .= '/' . rawurlencode($citySlug);
|
||||
}
|
||||
|
||||
$target .= '/';
|
||||
|
||||
$extra = $_GET;
|
||||
unset($extra['specialite'], $extra['ville']);
|
||||
|
||||
if (! empty($extra)) {
|
||||
$target .= '?' . http_build_query($extra);
|
||||
}
|
||||
|
||||
header('Location: ' . $target, true, 301);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($UGLY_TO_PRETTY[$path])) {
|
||||
$target = $UGLY_TO_PRETTY[$path];
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
function has_cyrillic(string $s): bool {
|
||||
return (bool) preg_match('/\p{Cyrillic}/u', $s);
|
||||
}
|
||||
|
||||
function norm_key(string $s): string {
|
||||
$s = mb_strtolower(trim($s), 'UTF-8');
|
||||
$s = str_replace(['ё'], ['е'], $s); // homogénéiser RU
|
||||
$s = preg_replace('/[\'"’\-\s]+/u', '', $s); // enlève tirets, espaces, quotes
|
||||
return $s;
|
||||
}
|
||||
|
||||
// Translittération simple RU -> latin (fallback si intl n’est pas dispo)
|
||||
function translit_ru_to_lat(string $s): string {
|
||||
if (class_exists('Transliterator')) {
|
||||
// "Russian-Latin/BGN" produit Parizh (Париж) -> "parizh"
|
||||
$t = \Transliterator::create('Russian-Latin/BGN; Lower();');
|
||||
if ($t) return $t->transliterate($s);
|
||||
}
|
||||
$map = [
|
||||
'а'=>'a','б'=>'b','в'=>'v','г'=>'g','д'=>'d','е'=>'e','ё'=>'e','ж'=>'zh','з'=>'z','и'=>'i','й'=>'i','к'=>'k',
|
||||
'л'=>'l','м'=>'m','н'=>'n','о'=>'o','п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'kh','ц'=>'ts',
|
||||
'ч'=>'ch','ш'=>'sh','щ'=>'shch','ъ'=>'','ы'=>'y','ь'=>'','э'=>'e','ю'=>'yu','я'=>'ya',
|
||||
];
|
||||
$s = mb_strtolower($s, 'UTF-8');
|
||||
return strtr($s, $map);
|
||||
}
|
||||
|
||||
// Retourne une liste de candidats latins (pour LIKE) à partir d’une saisie q
|
||||
function city_query_candidates(string $q): array {
|
||||
$q = trim($q);
|
||||
if ($q === '') return [];
|
||||
|
||||
$cands = [];
|
||||
$cands[] = mb_strtolower($q, 'UTF-8'); // saisie brute (si déjà latine)
|
||||
|
||||
// charger alias RU -> latin
|
||||
$aliases = @include __DIR__ . '/city_aliases_ru.php';
|
||||
if (!is_array($aliases)) $aliases = [];
|
||||
|
||||
if (has_cyrillic($q)) {
|
||||
// 1) correspondance par préfixe dans les alias (ПАР → Paris)
|
||||
$key = norm_key($q);
|
||||
foreach ($aliases as $ru => $lat) {
|
||||
if (strpos(norm_key($ru), $key) === 0) {
|
||||
$cands[] = $lat;
|
||||
}
|
||||
}
|
||||
// 2) translittération simple (Париж -> parizh)
|
||||
$cands[] = translit_ru_to_lat($q);
|
||||
}
|
||||
|
||||
// Normalisation légère des candidats (minuscules, accents retirés si possible)
|
||||
$res = [];
|
||||
foreach (array_unique($cands) as $c) {
|
||||
$lc = mb_strtolower($c, 'UTF-8');
|
||||
// enlever accents (si intl transliterator dispo)
|
||||
if (class_exists('Transliterator')) {
|
||||
$t = \Transliterator::create('Any-Latin; Latin-ASCII;');
|
||||
if ($t) $lc = $t->transliterate($lc);
|
||||
}
|
||||
$res[] = $lc;
|
||||
}
|
||||
return array_values(array_unique($res));
|
||||
}
|
||||
+396
-56
@@ -1,65 +1,405 @@
|
||||
<?php
|
||||
function has_cyrillic(string $s): bool {
|
||||
return (bool) preg_match('/\p{Cyrillic}/u', $s);
|
||||
|
||||
function has_cyrillic(string $s): bool
|
||||
{
|
||||
return (bool) preg_match('/\p{Cyrillic}/u', $s);
|
||||
}
|
||||
|
||||
function norm_key(string $s): string {
|
||||
$s = mb_strtolower(trim($s), 'UTF-8');
|
||||
$s = str_replace(['ё'], ['е'], $s); // homogénéiser RU
|
||||
$s = preg_replace('/[\'"’\-\s]+/u', '', $s); // enlève tirets, espaces, quotes
|
||||
return $s;
|
||||
function norm_key(string $s): string
|
||||
{
|
||||
$s = mb_strtolower(trim($s), 'UTF-8');
|
||||
$s = str_replace(['ё'], ['е'], $s);
|
||||
$s = preg_replace('/[\'"’\-\s]+/u', '', $s);
|
||||
return $s;
|
||||
}
|
||||
|
||||
// Translittération simple RU -> latin (fallback si intl n’est pas dispo)
|
||||
function translit_ru_to_lat(string $s): string {
|
||||
if (class_exists('Transliterator')) {
|
||||
// "Russian-Latin/BGN" produit Parizh (Париж) -> "parizh"
|
||||
$t = \Transliterator::create('Russian-Latin/BGN; Lower();');
|
||||
if ($t) return $t->transliterate($s);
|
||||
}
|
||||
$map = [
|
||||
'а'=>'a','б'=>'b','в'=>'v','г'=>'g','д'=>'d','е'=>'e','ё'=>'e','ж'=>'zh','з'=>'z','и'=>'i','й'=>'i','к'=>'k',
|
||||
'л'=>'l','м'=>'m','н'=>'n','о'=>'o','п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'kh','ц'=>'ts',
|
||||
'ч'=>'ch','ш'=>'sh','щ'=>'shch','ъ'=>'','ы'=>'y','ь'=>'','э'=>'e','ю'=>'yu','я'=>'ya',
|
||||
];
|
||||
$s = mb_strtolower($s, 'UTF-8');
|
||||
return strtr($s, $map);
|
||||
}
|
||||
|
||||
// Retourne une liste de candidats latins (pour LIKE) à partir d’une saisie q
|
||||
function city_query_candidates(string $q): array {
|
||||
$q = trim($q);
|
||||
if ($q === '') return [];
|
||||
|
||||
$cands = [];
|
||||
$cands[] = mb_strtolower($q, 'UTF-8'); // saisie brute (si déjà latine)
|
||||
|
||||
// charger alias RU -> latin
|
||||
$aliases = @include __DIR__ . '/city_aliases_ru.php';
|
||||
if (!is_array($aliases)) $aliases = [];
|
||||
|
||||
if (has_cyrillic($q)) {
|
||||
// 1) correspondance par préfixe dans les alias (ПАР → Paris)
|
||||
$key = norm_key($q);
|
||||
foreach ($aliases as $ru => $lat) {
|
||||
if (strpos(norm_key($ru), $key) === 0) {
|
||||
$cands[] = $lat;
|
||||
}
|
||||
}
|
||||
// 2) translittération simple (Париж -> parizh)
|
||||
$cands[] = translit_ru_to_lat($q);
|
||||
}
|
||||
|
||||
// Normalisation légère des candidats (minuscules, accents retirés si possible)
|
||||
$res = [];
|
||||
foreach (array_unique($cands) as $c) {
|
||||
$lc = mb_strtolower($c, 'UTF-8');
|
||||
// enlever accents (si intl transliterator dispo)
|
||||
function translit_ru_to_lat(string $s): string
|
||||
{
|
||||
if (class_exists('Transliterator')) {
|
||||
$t = \Transliterator::create('Any-Latin; Latin-ASCII;');
|
||||
if ($t) $lc = $t->transliterate($lc);
|
||||
$t = \Transliterator::create('Russian-Latin/BGN; Lower();');
|
||||
if ($t) {
|
||||
return $t->transliterate($s);
|
||||
}
|
||||
}
|
||||
$res[] = $lc;
|
||||
}
|
||||
return array_values(array_unique($res));
|
||||
|
||||
$map = [
|
||||
'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd',
|
||||
'е' => 'e', 'ё' => 'e', 'ж' => 'zh', 'з' => 'z', 'и' => 'i',
|
||||
'й' => 'i', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n',
|
||||
'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't',
|
||||
'у' => 'u', 'ф' => 'f', 'х' => 'kh', 'ц' => 'ts', 'ч' => 'ch',
|
||||
'ш' => 'sh', 'щ' => 'shch', 'ъ' => '', 'ы' => 'y', 'ь' => '',
|
||||
'э' => 'e', 'ю' => 'yu', 'я' => 'ya',
|
||||
];
|
||||
|
||||
$s = mb_strtolower($s, 'UTF-8');
|
||||
return strtr($s, $map);
|
||||
}
|
||||
|
||||
// Retourne une liste de candidats latins (pour LIKE) à partir d’une saisie ville
|
||||
function city_query_candidates(string $q): array
|
||||
{
|
||||
$q = trim($q);
|
||||
if ($q === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
$aliases = @include __DIR__ . '/city_aliases_ru.php';
|
||||
if (! is_array($aliases)) {
|
||||
$aliases = [];
|
||||
}
|
||||
|
||||
$cands = [];
|
||||
$qLower = mb_strtolower($q, 'UTF-8');
|
||||
|
||||
// Toujours garder la saisie brute
|
||||
$cands[] = $qLower;
|
||||
|
||||
// Version ASCII/latin normalisée
|
||||
$qAscii = $qLower;
|
||||
if (class_exists('Transliterator')) {
|
||||
$t = \Transliterator::create('Any-Latin; Latin-ASCII; Lower();');
|
||||
if ($t) {
|
||||
$qAscii = $t->transliterate($qAscii);
|
||||
}
|
||||
}
|
||||
$cands[] = $qAscii;
|
||||
|
||||
// Si saisie en cyrillique : on ajoute les villes latines correspondantes
|
||||
if (has_cyrillic($q)) {
|
||||
$key = norm_key($q);
|
||||
|
||||
foreach ($aliases as $ru => $lat) {
|
||||
if (strpos(norm_key($ru), $key) === 0) {
|
||||
$cands[] = mb_strtolower($lat, 'UTF-8');
|
||||
$cands[] = mb_strtolower($ru, 'UTF-8');
|
||||
}
|
||||
}
|
||||
|
||||
$cands[] = translit_ru_to_lat($q);
|
||||
}
|
||||
|
||||
// Si saisie en latin : on cherche aussi les correspondances RU depuis les aliases
|
||||
foreach ($aliases as $ru => $lat) {
|
||||
$latLower = mb_strtolower($lat, 'UTF-8');
|
||||
|
||||
$latAscii = $latLower;
|
||||
if (class_exists('Transliterator')) {
|
||||
$t = \Transliterator::create('Any-Latin; Latin-ASCII; Lower();');
|
||||
if ($t) {
|
||||
$latAscii = $t->transliterate($latAscii);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
strpos($latLower, $qLower) === 0 ||
|
||||
strpos($latAscii, $qAscii) === 0
|
||||
) {
|
||||
$cands[] = mb_strtolower($ru, 'UTF-8');
|
||||
$cands[] = $latLower;
|
||||
}
|
||||
}
|
||||
|
||||
$res = [];
|
||||
foreach (array_unique($cands) as $c) {
|
||||
$res[] = mb_strtolower(trim($c), 'UTF-8');
|
||||
}
|
||||
|
||||
return array_values(array_unique(array_filter($res)));
|
||||
}
|
||||
|
||||
function seo_slug(string $s): string
|
||||
{
|
||||
$s = trim(mb_strtolower($s, 'UTF-8'));
|
||||
|
||||
if ($s === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (has_cyrillic($s)) {
|
||||
$aliases = @include __DIR__ . '/city_aliases_ru.php';
|
||||
if (is_array($aliases)) {
|
||||
foreach ($aliases as $ru => $lat) {
|
||||
if (norm_key($ru) === norm_key($s)) {
|
||||
$s = $lat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_cyrillic($s)) {
|
||||
$s = translit_ru_to_lat($s);
|
||||
}
|
||||
}
|
||||
|
||||
if (class_exists('Transliterator')) {
|
||||
$t = \Transliterator::create('Any-Latin; Latin-ASCII; Lower();');
|
||||
if ($t) {
|
||||
$s = $t->transliterate($s);
|
||||
}
|
||||
}
|
||||
|
||||
$s = str_replace(['œ', 'æ'], ['oe', 'ae'], $s);
|
||||
$s = preg_replace('/[^\p{L}\p{N}]+/u', '-', $s);
|
||||
$s = trim($s, '-');
|
||||
$s = preg_replace('/-+/u', '-', $s);
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
function seo_unslug(string $s): string
|
||||
{
|
||||
$s = trim(mb_strtolower($s, 'UTF-8'));
|
||||
$s = str_replace('-', ' ', $s);
|
||||
$s = preg_replace('/\s+/u', ' ', $s);
|
||||
return trim($s);
|
||||
}
|
||||
|
||||
function seo_spec_map(): array
|
||||
{
|
||||
return [
|
||||
'psychologue' => [
|
||||
'db' => 'психолог',
|
||||
'search' => [
|
||||
'ru' => 'психолог',
|
||||
'fr' => 'psychologue',
|
||||
'en' => 'psychologist',
|
||||
],
|
||||
'inputs' => ['psychologue', 'psychologues', 'психолог', 'психологи'],
|
||||
],
|
||||
|
||||
'manager' => [
|
||||
'db' => 'менеджер',
|
||||
'search' => [
|
||||
'ru' => 'менеджер',
|
||||
'fr' => 'manager',
|
||||
'en' => 'manager',
|
||||
],
|
||||
'inputs' => ['it manager', 'it-manager', 'manager it', 'responsable it', 'it-менеджер', 'ит менеджер'],
|
||||
],
|
||||
|
||||
'construction' => [
|
||||
'db' => 'строитель',
|
||||
'search' => [
|
||||
'ru' => 'строитель',
|
||||
'fr' => 'construction',
|
||||
'en' => 'construction',
|
||||
],
|
||||
'inputs' => [
|
||||
'строительная компания',
|
||||
'строительная фирма',
|
||||
'строительство',
|
||||
'construction',
|
||||
'entreprise de construction',
|
||||
'bâtiment',
|
||||
'btp',
|
||||
],
|
||||
],
|
||||
|
||||
'pompes-funebres' => [
|
||||
'db' => 'похоронное',
|
||||
'search' => [
|
||||
'ru' => 'похоронное',
|
||||
'fr' => 'pompes funebres',
|
||||
'en' => 'funeral services',
|
||||
],
|
||||
'inputs' => [
|
||||
'похоронное агентство',
|
||||
'похоронное бюро',
|
||||
'ритуальные услуги',
|
||||
'ритуальное агентство',
|
||||
'pompes funebres',
|
||||
'pompes-funebres',
|
||||
'services funeraires',
|
||||
'funerailles',
|
||||
],
|
||||
],
|
||||
|
||||
'avocat' => [
|
||||
'db' => 'адвокат',
|
||||
'search' => [
|
||||
'ru' => 'адвокат',
|
||||
'fr' => 'avocat',
|
||||
'en' => 'lawyer',
|
||||
],
|
||||
'inputs' => ['avocat', 'avocats', 'адвокат', 'адвокаты'],
|
||||
],
|
||||
|
||||
'medecin' => [
|
||||
'db' => 'врач',
|
||||
'search' => [
|
||||
'ru' => 'врач',
|
||||
'fr' => 'medecin',
|
||||
'en' => 'doctor',
|
||||
],
|
||||
'inputs' => ['medecin', 'medecins', 'médecin', 'médecins', 'врач', 'врачи', 'Врач - стоматолог', 'врач-стоматолог'],
|
||||
],
|
||||
|
||||
'consultant' => [
|
||||
'db' => 'консультант',
|
||||
'search' => [
|
||||
'ru' => 'консультант',
|
||||
'fr' => 'consultant',
|
||||
'en' => 'consultant',
|
||||
],
|
||||
'inputs' => ['consultant', 'consultants', 'консультант', 'консультанты', 'Консультант'],
|
||||
],
|
||||
|
||||
'professeur' => [
|
||||
'db' => 'преподаватель',
|
||||
'search' => [
|
||||
'ru' => 'преподаватель',
|
||||
'fr' => 'professeur',
|
||||
'en' => 'teacher',
|
||||
],
|
||||
'inputs' => ['professeur', 'professeurs', 'pedagogue', 'pedagogues', 'преподаватель', 'преподаватели', 'педагог', 'педагоги'],
|
||||
],
|
||||
|
||||
'comptable' => [
|
||||
'db' => 'бухгалтер',
|
||||
'search' => [
|
||||
'ru' => 'бухгалтер',
|
||||
'fr' => 'comptable',
|
||||
'en' => 'accountant',
|
||||
],
|
||||
'inputs' => ['comptable', 'comptables', 'бухгалтер', 'бухгалтеры'],
|
||||
],
|
||||
|
||||
'traducteur' => [
|
||||
'db' => 'переводчик',
|
||||
'search' => [
|
||||
'ru' => 'переводчик',
|
||||
'fr' => 'traducteur',
|
||||
'en' => 'translator',
|
||||
],
|
||||
'inputs' => ['traducteur', 'traducteurs', 'переводчик', 'переводчики'],
|
||||
],
|
||||
|
||||
'notaire' => [
|
||||
'db' => 'нотариус',
|
||||
'search' => [
|
||||
'ru' => 'нотариус',
|
||||
'fr' => 'notaire',
|
||||
'en' => 'notary',
|
||||
],
|
||||
'inputs' => ['notaire', 'notaires', 'нотариус', 'нотариусы'],
|
||||
],
|
||||
|
||||
'guide' => [
|
||||
'db' => 'гид',
|
||||
'search' => [
|
||||
'ru' => 'гид',
|
||||
'fr' => 'guide',
|
||||
'en' => 'guide',
|
||||
],
|
||||
'inputs' => ['guide', 'guides', 'гид', 'гиды'],
|
||||
],
|
||||
|
||||
'agent-immobilier' => [
|
||||
'db' => 'риелтор',
|
||||
'search' => [
|
||||
'ru' => 'риелтор',
|
||||
'fr' => 'agent immobilier',
|
||||
'en' => 'real estate agent',
|
||||
],
|
||||
'inputs' => [
|
||||
'Agent immobilier',
|
||||
'agent immobilier',
|
||||
'agent-immobilier',
|
||||
'agents immobiliers',
|
||||
'agents-immobiliers',
|
||||
'риелтор',
|
||||
'риелторы',
|
||||
],
|
||||
],
|
||||
|
||||
'autres-specialistes' => [
|
||||
'db' => '__OTHERS__',
|
||||
'inputs' => ['autres specialistes', 'autres-specialistes', 'другие', 'другие специалисты'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
function seo_spec_slug_from_input(string $input): ?string
|
||||
{
|
||||
$inputSlug = seo_slug($input);
|
||||
|
||||
foreach (seo_spec_map() as $slug => $cfg) {
|
||||
foreach (($cfg['inputs'] ?? []) as $candidate) {
|
||||
if ($inputSlug === seo_slug((string) $candidate)) {
|
||||
return $slug;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function seo_spec_db_from_slug(string $slug): ?string
|
||||
{
|
||||
$slug = seo_slug($slug);
|
||||
$map = seo_spec_map();
|
||||
|
||||
return $map[$slug]['db'] ?? null;
|
||||
}
|
||||
|
||||
function seo_city_slug_from_input(string $input): string
|
||||
{
|
||||
$input = trim($input);
|
||||
if ($input === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$aliases = @include __DIR__ . '/city_aliases_ru.php';
|
||||
if (! is_array($aliases)) {
|
||||
$aliases = [];
|
||||
}
|
||||
|
||||
$key = norm_key($input);
|
||||
|
||||
foreach ($aliases as $ru => $lat) {
|
||||
if (norm_key($ru) === $key) {
|
||||
return seo_slug((string) $lat);
|
||||
}
|
||||
}
|
||||
|
||||
return seo_slug($input);
|
||||
}
|
||||
|
||||
function seo_spec_slug_from_key(string $key): ?string
|
||||
{
|
||||
$map = [
|
||||
'avocats' => 'avocat',
|
||||
'consultants' => 'consultant',
|
||||
'vrachi' => 'medecin',
|
||||
'psychologues' => 'psychologue',
|
||||
'repetitori' => 'professeur',
|
||||
'finance' => 'comptable',
|
||||
'perevod' => 'traducteur',
|
||||
'notarius' => 'notaire',
|
||||
'gid' => 'guide',
|
||||
'rieltori' => 'agent-immobilier',
|
||||
'drugie' => 'autres-specialistes',
|
||||
];
|
||||
|
||||
return $map[$key] ?? null;
|
||||
}
|
||||
function seo_spec_search_value_from_slug(string $slug, string $lang): ?string
|
||||
{
|
||||
$slug = seo_slug($slug);
|
||||
$lang = mb_strtolower(trim($lang), 'UTF-8');
|
||||
|
||||
$map = seo_spec_map();
|
||||
if (! isset($map[$slug])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$cfg = $map[$slug];
|
||||
|
||||
if (isset($cfg['search'][$lang]) && trim((string) $cfg['search'][$lang]) !== '') {
|
||||
return trim((string) $cfg['search'][$lang]);
|
||||
}
|
||||
|
||||
return $cfg['db'] ?? null;
|
||||
}
|
||||
+24
-25
@@ -1,30 +1,29 @@
|
||||
<?php
|
||||
// Map des clés de traduction -> valeur canonique (singulier) pour la BDD
|
||||
return [
|
||||
'ru' => [
|
||||
'avocats' => 'адвокат',
|
||||
'consultants' => 'консультант',
|
||||
'vrachi' => 'врач',
|
||||
'psychologues' => 'психолог',
|
||||
'repetitori' => 'преподаватель',
|
||||
'finance' => 'бухгалтер', // ajuste si besoin
|
||||
'perevod' => 'переводчик',
|
||||
'notarius' => 'нотариус',
|
||||
'gid' => 'гид',
|
||||
'rieltori' => 'риелтор',
|
||||
|
||||
'ru' => [
|
||||
'avocats' => 'адвокат',
|
||||
'consultants' => 'консультант',
|
||||
'vrachi' => 'врач',
|
||||
'psychologues' => 'психолог',
|
||||
'repetitori' => 'преподаватель',
|
||||
'finance' => 'бухгалтер', // ajuste si besoin
|
||||
'perevod' => 'переводчик',
|
||||
'notarius' => 'нотариус',
|
||||
'gid' => 'гид',
|
||||
'rieltori' => 'риелтор',
|
||||
|
||||
],
|
||||
'fr' => [
|
||||
'avocats' => 'адвокат',
|
||||
'consultants' => 'консультант',
|
||||
'vrachi' => 'врач', // clé existante "vrachi" côté traductions
|
||||
'psychologues' => 'психолог',
|
||||
'repetitori' => 'преподаватель', // ou "Répetiteur" selon ta BDD
|
||||
'finance' => 'бухгалтер', // ajuste si besoin
|
||||
'perevod' => 'переводчик',
|
||||
'notarius' => 'нотариус',
|
||||
'gid' => 'гид',
|
||||
'rieltori' => 'риелтор',
|
||||
],
|
||||
],
|
||||
'fr' => [
|
||||
'avocats' => 'адвокат',
|
||||
'consultants' => 'консультант',
|
||||
'vrachi' => 'врач', // clé existante "vrachi" côté traductions
|
||||
'psychologues' => 'психолог',
|
||||
'repetitori' => 'преподаватель', // ou "Répetiteur" selon ta BDD
|
||||
'finance' => 'бухгалтер', // ajuste si besoin
|
||||
'perevod' => 'переводчик',
|
||||
'notarius' => 'нотариус',
|
||||
'gid' => 'гид',
|
||||
'rieltori' => 'риелтор',
|
||||
],
|
||||
];
|
||||
Reference in new issue
Block a user