# İletişim bilgisi ve telefon yardımcıları
> **Kaynak:** `Core/Support/Bridges/Helpers/Library/FormatHelper.php` · `Core/Support/Bridges/Helpers/Global/project_helpers.php`
> **Ölçüt:** `docs/google-arama/json-ld-hedef-semalari.md` (telefon ülke kodlu, görünür metinle birebir), `docs/yasal/gizlilik-politikasi-ve-iletisim-sayfalari.md`.
## 1. Telefon: tek yardımcı, üç çıktı
Telefon DB'de ham rakam olarak durur (`contact-phone`, `contact-landline`). **Hiçbir çıktı ham numarayı basmaz**; görüntü, `tel:` bağlantısı, JSON-LD ve WhatsApp bağlantısı şu üç yardımcıdan gelir (görünümde global fonksiyon, kodda `FormatHelper` statik yöntemi):
| Global | `FormatHelper` | Çıktı (`05335675060` için) | Nerede kullanılır |
|---|---|---|---|
| `format_phone($n)` | `formatPhone()` | `0 533 567 50 60` | Ekranda görünen metin (footer, iletişim, yasal sayfa) |
| `phone_e164($n)` | `phoneE164()` | `+905335675060` | `tel:` bağlantısı, JSON-LD `telephone` |
| `whatsapp_url($n)` | `whatsappUrl()` | `https://wa.me/905335675060` | WhatsApp düğmesi. WhatsApp'ın ayrı numarası/ayarı yoktur: bağlantı ana telefondan (`contact-phone`) üretilir |
Kabul edilen Türkiye girdileri: `02423225060`, `2423225060`, `902423225060`, `+90 242 322 50 60`, `0090 242 322 50 60`. Sabit hat ve cep aynı biçimdir (`0 242 322 50 60`). Türkiye numarası olmayan değer: `format_phone` olduğu gibi (kırpılmış) döner, `phone_e164` yalnız `+` ile başlayan 8-15 haneli uluslararası numarayı kabul eder, aksi `null`; `whatsapp_url` aynı kuralla `null` döner. Ülke kodu tahmin edilmez; boş girdi boş çıktı verir.
```php
{{ format_phone($phone) }}
WhatsApp
```
İstemci tarafındaki giriş maskesi (`rbnFormatPhone`, `data-format="phone"`, `type="tel"`) aynı biçimi (`0 XXX XXX XX XX`) yazar; tek görüntü biçimi vardır.
## 2. İletişim bilgisi tek kaynak: `contact_info()`
Footer, iletişim sayfası, ödeme ve landing görünümleri ile JSON-LD aynı diziyi okur (`ContactService::info()`, `service('contact')`; ayarlar `company-*`, `contact-*`, `social`). Ziyaretçinin okuduğu metin ile yapısal veri bu yüzden ayrışamaz. Boş/eksik ayar boş değerdir; ne basılacağına (harita, form, saat bloğu, kart düzeni) sayfa görünümü karar verir. İletişim sayfasının TASARIMI projenin işidir; framework yalnız veriyi ve şemayı verir.
| Anahtar | Kaynak ayar | Değer |
|---|---|---|
| `legal_name` | `company-legal-name` | unvan |
| `name` | `company-name` | marka / görünen ad |
| `address`, `locality`, `region`, `postal_code` | `contact-adress`, `contact-locality`, `contact-region`, `contact-postal-code` | metin |
| `phone`, `phone_e164` | `contact-phone` | `0 533 567 50 60`, `+905335675060` (`null`: geçersiz) |
| `landline`, `landline_e164` | `contact-landline` | `0 242 322 50 60`, `+902423225060` |
| `whatsapp`, `whatsapp_url` | `contact-phone` | ana telefon; `https://wa.me/905335675060` |
| `email` | `contact-email` | metin |
| `website` | ayar DEĞİL | sitenin kendi adresi (`url()`) |
| `tax_office` | `company-tax-office` | metin |
| `hours`, `hours_schedule`, `open_status` | `contact-hours` (haftalık program) | **anahtarlar yalnız saat varsa vardır.** `hours` programdan üretilen görünen metin, `hours_schedule` program, `open_status` açık/kapalı durumu ve kalan süre: [Calisma-Saatleri](Calisma-Saatleri.md) |
| `map_location` | `company-map-location` | `enlem,boylam` |
| `socials` | `social` grubu | `base.project` `getSocialLinks()['socialLinks']` çıktısı, tam platform kayıtlarıyla (`key`, `title`, `url`, `color`, `bi_icon`, `fa_icon`, `ri_icon`; kaynak `social_media_platforms.json`). `ContactService` kendi sosyal listesini ya da etiketini TUTMAZ |
| `owner_name`, `trade_name`, `tax_number`, `mersis_number`, `trade_registry_number`, `kep_address` | `company-owner-name` (gerçek kişinin sitesinde sahip adı), `company-trade-name`, `company-tax-number`, `company-mersis-number`, `company-trade-registry-number`, `company-kep-address` | **anahtar yalnız doluysa vardır** (şahıs firmasında yoktur) |
| `establishment_year`, `experience_years` | `company-establishment-year` | kuruluş yılı; `experience_years` = bu yıl − kuruluş yılı (hesaplanır). **Yalnız doluysa vardır** |
| `service_areas` | `company-service-areas` | hizmet bölgeleri listesi (ayarda her satıra bir bölge). **Yalnız doluysa vardır** |
| `google_maps_url`, `google_review_url` | `company-google-maps-url`, `company-google-review-url` | Google Haritalar / yorum yazma bağlantısı. **Yalnız doluysa vardır** |
| `rating_score`, `rating_count` | `company-rating-score`, `company-rating-count` | Google puanı ve yorum sayısı; **yalnız Google senkronu yazar** (bkz. §3). Yoksa anahtar yoktur: sabit/yedek puan YOKTUR. Görünürde gösterilebilir; JSON-LD'ye YAZILMAZ (self-serving `aggregateRating` politika riski) |
```php
$c = contact_info();
// {{ $c['phone'] }}
// @if(isset($c['hours'])) ... @endif
// @if(isset($c['tax_number'])) ... @endif
```
### Görünüme giden `contact` (payload sözleşmesi)
Frontend denetleyicisi (`FrontendBaseController::afterBoot`), `FrontendProvider` ve `SeoResolver` görünüme `$contact` olarak **`contact_info()` dizisinin kendisini** verir: tablodaki anahtarlar, aynı adlarla, hazır/biçimli değerlerle. Ham ayar anahtarı (`contact-phone`, `contact-adress`…) görünüme gitmez; telefon biçimlendirme yalnız `ContactService::info()` içinde (`FormatHelper`) yapılır. Görünüm hazır değeri basar:
```php
// {{ $contact['phone'] }}
// @if(!empty($contact['whatsapp_url'])) WhatsApp @endif
// {{ $contact['legal_name'] }} · {{ $contact['address'] }}
```
Görünümde `format_phone()` / `phone_e164()` / `whatsapp_url()` çağrısı, `?? '#'` yedeği ya da `$contact['contact-phone']` okuması olmaz. Telefon yoksa `phone` boş metin, `phone_e164` / `whatsapp_url` `null` olur: bağlantıyı basan blok `@if(!empty(...))` içinde durur. `$company` ve `$social` değişkenleri ham ayar grubu olarak kalır (şirket adı/logosu, sosyal ayarlar); iletişim ve kimlik verisi için tek yol `$contact`'tır. Kapı: `G-iletisim-10`, `-10b`.
### ContactPage JSON-LD
Sayfa denetleyicisi `->schema('contact', ['name' => 'İletişim'])` der; çıktı `ContactPage` + `BreadcrumbList`. `ContactPage.mainEntity` organizasyon düğümünü (`@id`) gösterir; organizasyon düğümü (`SchemaResolver::company()`) telefonu (`phone_e164`), e-postayı, adresi (+ ilçe, il, posta kodu), koordinatı, sosyal bağlantıları ve `legalName`'i `contact_info()`'dan alır. Görünümde de aynı dizi basıldığından telefon ve adres görünür metinle birebir aynıdır (docs `json-ld-hedef-semalari.md` madde 3). Kapı: `G-iletisim-05`.
## 3. Google işletme profili senkronu (`google:sync`)
Çalışma saati, koordinat ve Google puanı projeye özel bir kod gerektirmez: framework haftalık bir zamanlanmış görevle Google'dan okur ve **proje DB ayarlarına yazar**; sayfalar yalnız DB'yi okur. **Sayfa isteğinde Google'a gidilmez**; Google yanıt vermezse DB'deki son değer durur (önbellek, sabit yedek değer, "canlı mı" işareti yoktur).
| | |
|---|---|
| Katılım şartı | Projenin `z_settings_api` tablosunda `GOOGLE_API_KEY` dolu **ve** şirket ayarı `company-google-place-id` (işletme kimliği, gizli değil, panelden girilir) dolu. İkisinden biri yoksa görev o proje için hiçbir şey yapmaz, hata da vermez (marka siteleri ve işletme olmayan siteler böyle dışarıda kalır). |
| Google'ın yazdığı alanlar | `contact-hours` (Google `regularOpeningHours.periods` listesi, [Calisma-Saatleri](Calisma-Saatleri.md) haftalık programına çevrilerek yazılır; görünen metin programdan üretilir), `company-map-location` (`enlem,boylam`), `company-rating-score`, `company-rating-count`. Aynı alan elle de girilmişse Google bağlı projede **senkron yazar** (tek yazan). |
| Google'ın YAZMADIĞI | Adres (yasal adres elle girilir, `contact-adress`), telefon. Google'ın yanıtında olmayan alan yazılmaz (puan yoksa puan satırı eklenmez). |
| Zamanlama | Master `cron_jobs` tablosunda **tek satır**: `SystemTask`, `task_key=google_sync`; varsayılan haftalık (Pazartesi 04:00), `params.days` / `params.hours` ile ayarlanır. Görev tüm aktif projeleri tek çalışmada dolaşır (ana proje bağlamından). |
| Elle tetikleme | `php rbn google:sync --project= [--apply]` — `--apply` yoksa Google okunur, plan basılır, hiçbir şey yazılmaz. |
| Referer | Anahtarın HTTP referer kısıtı için isteğe projenin alan adı (`https:///`) eklenir. |
API anahtarı `ApiKeysRegistry::MAP['google']['api_key']` (`GOOGLE_API_KEY`) üzerinden çözülür; settings_api'ye başka ad eklenmez. Kod: `GoogleService::syncBusinessProfile()` (tek yazıcı), `GoogleSyncJob`, `GoogleHandlers`.
## 4. Ayar tablosunda boş satır yok
Ayar tablosuna (`z_settings`) **yalnız kullanılan, DOLU değerli satır** yazılır. `rbn legal:install` ve diğer kurulum yolları (`setupAdsense`) şablondan boş değerli satır eklemez; `rbn settings:set` boş değeri reddeder (ayarı kaldırmanın yolu `settings:unset`). Panel tanımı olan alanlar `SettingsConfig` içinde durur; satır, değer girilince oluşur. Google'a ait ayarlar (`company-google-place-id`, `company-google-maps-url`, `company-google-review-url`, `company-rating-*`, `company-map-location`, `contact-hours`) Google'sız sitede (marka sitesi) satır olarak bulunmaz. Yasal sayfadaki şirket satırları (dolu olan yazılır, boş olanın etiketi de yazılmaz; satışlı sitede unvan/adres/telefon/e-posta zorunlu): [Yasal-Sayfa-Motoru](Yasal-Sayfa-Motoru.md) §2. Kapı: `g_ayar_bos_satir.php` (`G-ayar-01..06`).
## 5. Kapılar
`E:\AgentSpace\.agentspace\araclar\fw-regresyon\birim\g_iletisim_bilgisi.php`: `G-iletisim-01` telefon yardımcıları · `-02` ham numara basan/ikinci biçimlendirme yapan kod yok · `-03` WhatsApp ayarı yok · `-04` `contact_info()` sözleşmesi · `-05` ContactPage = görünen metin · `-06` şablon satır biçimi + boş satır kuralı · `-07` satışlı sitede zorunlu alanlar · `-08` `legal:install` ayar satırı eklemez · `-09` pilot yasal sayfalar · `-10` görünüme giden `contact` yalnız `contact_info()` kaynağından, ham ayar anahtarı yok. Her biri `-neg` örnekle kırmızıya döner.
`g_google_senkron.php`: `G-google-01` anahtar/yer kimliği yoksa senkron atlanır (`-01b` Places çağrısından önce) · `-02` saat: Google periods → program → metin (`-02b` temsil edilemeyen periyot = bos) · `-03` yazılan alanlar yalnız saat/konum/puan, adres asla · `-04` sayfa isteğinde Google çağrısı yok (`-04b` önbellek yolu yok) · `-05` sabit puan/`rating_is_live` yok · `-06` projede genel servis dosyası ve referansı yok · `-07` hizmet bölgeleri kodda sabit değil · `-08` marka sitesinde `contact-hours` ve saat satırı yok · `-09` işletme sitesinde saat/puan DB'den · `-10` `ContactService`'te ikinci sosyal liste/okuma yok, `socials` = `getSocialLinks()` kayıtları.
Çalışma saatleri kapıları (`g_calisma_saati.php`, `G-saat-01..17`): [Calisma-Saatleri §8](Calisma-Saatleri.md).