Site uzantıları için tek bir sözleşme.
Kimlik, sürümler ve güven
Her eklentinin bir namespace/name tanımlayıcısı, bağımsız bir anlamsal paket sürümü ve tam olarak "1" olan API sürümü vardır. eyivo ad alanı ayrılmıştır. Tür system veya standard, köken ise system, verified veya third_party olur. Bu sürümde yalnızca platformun onayladığı system kökenli paketler kabul edilir. Paketler kendilerine zorunlu durum veya yeni yetenek veremez.
Kurulum ve yapılandırma
Kurulum kayıtları atanmış master’a aittir. Kurma, etkinleştirme, devre dışı bırakma, kaldırma ve yükseltme işlemleri bir site kilidi ve veritabanı işlemi altında çalışır. Bağımlılıklar önce kurulur; eksik paketler, döngüler, çakışmalar ve sürüm düşürmeler reddedilir. Etkin bağımlılıklar ve platformun zorunlu tuttuğu paketler devre dışı bırakılamaz veya kaldırılamaz. Yükseltme kancaları previous_version alır ve ad alanına sahip yapılandırmalarını API üzerinden taşıyabilir. Yapılandırma, bildirilen skaler/nesne şemalarını ve varsayılanları kullanır; bilinmeyen anahtarlar reddedilir. Yaşam döngüsü işleyicileri bir dizi döndürmeli ve harici yan etkilere bağlı olmamalıdır.
Kapsamı net ayarlar.
Her sitenin ve eklentinin, atanmış master veritabanında kendi yapılandırması vardır. Uygulama paneli okuma ve kaydetme işlemlerini WireGuard üzerinden kimliği doğrulanmış Internal API ile yapar; master veritabanı kimlik bilgilerini tutmaz. plugins.eyivo.com adresindeki ortak hizmetler, hizmet durumu için ayrı bir veritabanı kullanır.
Bildirilen alanlar
En fazla 50
Nesne kapsayıcıları ve iç içe özellikler aynı toplamı paylaşır.
Yapılandırmanın tamamı
En fazla 32 KB
Anahtarlar, değerler ve varsayılanlar dahil 32.768 bayt sıkıştırılmış UTF-8 JSON.
İç içe geçme derinliği
En fazla 3 seviye
Üst düzey alanlar birinci seviyeden başlar.
Sunucu, bir paketi kaydederken şemaları doğrular ve her yazmada yapılandırmanın tamamını denetler. Bilinmeyen anahtarlar reddedilir. Panel kontrolleri ve tarayıcı doğrulaması sunucu tarafı denetimin yerini tutmaz.
Şemalar dizeleri, tam sayıları, mantıksal değerleri ve açık özellikleri olan nesneleri destekler. Diziler ve serbest eşlemeler yapılandırma türü değildir. Dize uzunlukları bayt olarak ölçülür. Üst düzey alanlar birinci seviyeden başlar; nesne kapsayıcıları hem alan toplamına hem de iç içe geçme derinliğine sayılır.
Kayıtlar site eklentisi revizyonunu taşır. Eski bir revizyon, daha yeni ayarların üzerine yazmak yerine çakışma döndürür. Yeniden denemeden önce sayfayı yenileyin ve güncel değerleri gözden geçirin. Sitedeki herhangi bir eklentide yapılan değişiklikler bu revizyonu değiştirir; devre dışı bırakma, yeniden etkinleştirme, kaldırma ve yeniden kurma da buna dahildir.
Yapılandırma şeması limitlerini ve kodlama kurallarını görüntüleyin
{
"fields": 50,
"depth": 3,
"bytes": 32768,
"counting": "Every declared property counts, including object containers. Top-level fields are level one. JSON bytes include recursively merged defaults, keys and values, encoded compactly with UTF-8 characters and slashes unescaped.",
"types": [
"string",
"integer",
"boolean",
"object"
],
"policy": "Objects require explicit properties; unknown keys and arrays are rejected. Strings default to 4096 bytes and support min/max up to 32768 bytes. Integer min/max and scalar enum choices are supported. constructor, prototype and __proto__ are reserved keys."
}
Sayfalar sizin. Bileşenler Eyivo’nun.
Bir eklenti; sayfa tanımlarına, yerleşime, yerelleştirilmiş içeriğe, formlara ve bildirilen eylemlere sahiptir. Merkezi uygulama bu tanımları mevcut kullanıcı panelinde güvenilir bileşenlerle işler. Bir eklentiye tıklamak, yapılandırma veya gönderim kutusu gibi bildirilen giriş sayfasını açar.
-
Sayfayı bildirin
Sayfa tanımlarını ve yapılandırma bağlantılarını pakete kaydedin. İsteğe bağlı menü bağlantıları aynı eklentiye ait sayfaları hedefler.
-
Uygulamada işleyin
Uygulama site erişimini denetler ve atanmış master’dan doğrulanmış JSON tanımlarını ve verileri alır. Eklentiye ait PHP veya Blade kodu uygulamaya aktarılmaz ve orada çalıştırılmaz.
-
Master’da çalıştırın
Yetkili eylemler Internal API üzerinden kısıtlı işleyicilere gider. Master; eklenti durumunu, yetenekleri, şemaları ve yapılandırma limitlerini uygular.
Tek seviyeli bir Eklentiler grubu
Uygun bağlantılar, seçili site için doğrudan Eklentiler altında görünür. İç içe alt menüler desteklenmez. Görünür bağlantı olmadığında grup gizli kalır. Devre dışı bırakma veya kaldırma bağlantıları kaldırır ve önceden açık sekmelerden gelen istekler dahil doğrudan sayfa ve eylem erişimini engeller. Yeniden etkinleştirme uygun bağlantıları geri getirir.
Panel bildirimi olmayan paketler ve devre dışı paketler, eklenti listesinden bir bilgi görünümü açar. Devre dışı paketler kayıtlı panel sayfalarını veya eylemlerini sunmaz. İnsan Doğrulaması salt okunur bir paket sayfası sağlar; güvenlik varsayılanları platformun denetiminde kalır.
Site üyeliği ve bildirilen eylemler
Sayfalar ve özel eylemler görüntüleme veya yönetme izni bildirir. Sitenin mevcut üyeleri uygun sayfaları görüntüleyebilir ve salt okunur görüntüleme eylemlerini çalıştırabilir; yönetme için site sahibi rolü gerekir. Uygulama, güvenilir aktörü oturum açmış üyelikten türetir. Yerleşik yapılandırma kaydetme/sıfırlama eylemleri yönetme izni gerektirir; özel işleyiciler bildirilen parametre ve yanıt şemalarını kullanır. Her sayfa yalnızca listelenen eylem kimliklerine izin verir.
Bildirimler yetki vermez
Sayfa yükleme salt okunurdur. Bir sayfa veya menü; sınırsız PHP, veritabanı erişimi, rastgele uygulama rotaları ya da kimliği doğrulanmış panel içinde betik çalıştırma yetkisi veremez. Panel bildirimi olmayan mevcut paketler çalışmaya devam eder. Üçüncü taraf paket kurulumu devre dışı kalır.
Desteklenen bileşenler
Sayfayı bu güvenilir bileşenlerle oluşturun. Alanlar bildirilen yapılandırmaya veya eylem girdilerine bağlanır; önizlemeler düz metin gösterir ve tablolar salt okunurdur. Ham HTML, rastgele betikler, ifadeler ve koşullu işleme desteklenmez.
stackgridcardtextalertfieldbuttonpreviewtablesubmission-listsubmission-detail
Sürümlü Panel API sözleşmesini ve limitlerini görüntüleyin
{
"api": "2",
"execution": "Plugins own JSON page definitions and restricted master-side handlers. App receives validated localized JSON only; plugin PHP, Blade, JavaScript, CSS, raw HTML and handler paths are not transferred or executed in the panel.",
"capabilities": [
"panel.render",
"panel.action",
"site.settings.read",
"site.settings.write"
],
"components": [
"stack",
"grid",
"card",
"text",
"alert",
"field",
"button",
"preview",
"table",
"submission-list",
"submission-detail"
],
"controls": [
"text",
"textarea",
"number",
"checkbox",
"select"
],
"action_types": [
"configuration.save",
"configuration.reset",
"handler"
],
"permissions": {
"view": [
"owner",
"viewer"
],
"manage": [
"owner"
]
},
"limits": {
"pages": 10,
"menu_links": 10,
"menu_depth": 1,
"actions": 20,
"action_input_bytes": 32768,
"components_per_page": 100,
"component_depth": 8,
"page_file_bytes": 65536,
"response_bytes": 262144,
"table_columns": 10,
"table_rows": 100
},
"configuration": "Configuration.save receives a complete configuration object as input; configuration.reset accepts empty input. Both require manage permission and site.settings.write. All panel actions require panel.action. Custom handlers declare view (read-only even for owners) or manage permission; their input/response use declared bounded schemas. Page loaders are read-only.",
"concurrency": "Every action requires the page revision. The master compares site.plugin_revision under the existing site row lock; stale saves return HTTP 409. Deactivation or uninstall blocks pages/actions and removes derived menus.",
"localization": "Definitions use locale maps with a required en fallback. The master localizes text before sending JSON to app. Field labels and input guidance are required.",
"supported_versions": [
"1",
"2"
],
"submissions": {
"version": "2",
"declaration": "submission-list declares form_type and detail_page; submission-detail declares the same form_type and list_page. Every registered form type requires mutually linked viewable pages and a flat sidebar menu entry to its list.",
"execution": "The host resolves current site/plugin ownership and supplies paginated summaries or a stored historical detail snapshot. App constructs all navigation and action URLs. Package PHP never reaches app.",
"contexts": "Page loaders receive authenticated actor and validated query/record context. Plugin operations cannot override the current site or plugin. Creating records requires an out-of-band host-issued FormProcessingContext unavailable to interpreted package code.",
"state": "Reading, archive and workflow state are independent. Record mutations require the current record_revision; configuration still uses plugin_revision. Viewing never marks a submission read. Viewers may read; existing owner/manage permissions govern mutations."
}
}
Formlar ve kayıt geçmişi
Forms API 1 yedi onaylı işleyici sağlar. Temalar düzen ve stili; eklentiler şema, doğrulama ve iş akışını yönetir. Kayıt, insan doğrulaması ve bildirimleri platform yürütür.
| Sistem eklentisi | Form türü |
|---|---|
eyivo/contact | İletişim contact |
eyivo/quote-request | Teklif talebi quote_request |
eyivo/product-inquiry | Ürün sorusu product_inquiry |
eyivo/appointment-request | Randevu talebi appointment |
eyivo/course-application | Kurs başvurusu course_application |
eyivo/reservation-request | Rezervasyon talebi reservation |
eyivo/property-inquiry | Emlak sorusu property_inquiry |
Bir form, birden çok yerleşim
Kurulum her site/eklenti/tür için kalıcı bir varsayılan UUID oluşturur. Yerleşimi yeniden kullanmak kimliği korur; adlandırılmış yeni form ayrı UUID alır. Tema değişikliği ve yeniden kurulum geçmişi korur. Tema taşınabilir takma adlar kullanır; müşteri UUID yazmadan kayıtlı formu seçer.
{
"plugins": ["eyivo/contact", "eyivo/quote-request"],
"forms": {
"contact": {"plugin":"eyivo/contact","type":"contact","schema_version":1,"instance":"default"},
"quote": {"plugin":"eyivo/quote-request","type":"quote_request","schema_version":1,"instance":"default"}
}
}
İletişim şablonunda forms.contact, iletişim bölümlerinde component.form kullanın. form_preset yerine form_binding kullanın. Sağlanan alanları, yönlendirmeleri, action, CSRF, imzalı form_context ve verification_html değerlerini gösterin. Yalnızca bildirilen sunum değişiklikleri ve izinli ek alanlar geçerlidir; zorunlu doğrulama zayıflatılamaz.
forms.contact · component.form · form_binding · form.fields · form.action · form.csrf_token · form.context · form.verification_html
İki gelen kutusu, tek kayıt
Ortak gelen kutusu ile eklentinin liste/detay sayfaları aynı kayıtları gösterir. Form paketleri Panel API 2 submission-list/submission-detail bileşenlerini ve tek düzey menü bağlantısını gerektirir. Panel API 1 desteklenir. Görüntülemek okundu yapmaz; okuma/arşiv/iş akışı ayrıdır ve değişiklikler record_revision kullanır. Devre dışı eklentinin menüleri kaybolur; ortak kutu geçmişi korur.
{"components":[{"type":"submission-list","form_type":"contact","detail_page":"submission"}]}
{"components":[{"type":"submission-detail","form_type":"contact","list_page":"submissions"}]}
Müşteri verileri ve izinler
Form kayıtları sitenin içerik veritabanında tutulur ve diğer içerikle aynı max_db_bytes paket hakkını kullanır. Ayrı kayıt sayısı veya saklama kotası yoktur. Yapılandırma master veritabanında 50 alan, 32 KB ve üç düzey sınırını korur. Üyeler görüntüler; değişiklikler sahip/yönetim izni gerektirir. Eklenti doğrudan veritabanına erişmez; PHP/Blade uygulamaya aktarılmaz.
Doğrulanmış kayıt ve bildirim
Platform imzalı bağlamı, cevapları ve insan doğrulamasını denetler; kayıt, kullanım ve bildirim işini birlikte kaydeder. Aynı deneme ve içerik 24 saat içinde çoğalmadan geri alınabilir. SMTP sonra çalışır ve yeniden deneyebilir; e-posta hatası kaydı silmez. Form alıcısı belirtilmezse şirket e-postası kullanılır; iki adres de geçerli değilse kayıt e-posta olmadan saklanır.
Tüm yerleşik temalar bu sözleşmeyi kullanır. Eski contact POST istekleri 410 döndürür; iletişim sayfası GET bağlantıları çalışır. Randevu ve rezervasyon talepleri kesin rezervasyon oluşturmaz. Üçüncü taraf işleyiciler, dosya yükleme ve keyfi dış adresler kapsam dışıdır.
POST /__eyivo/forms/{UUID}/submissionsGET /__eyivo/forms/{UUID}/challenge
Temalar ve form yerleşimi
Temalar onaylı bağımlılıkları ve taşınabilir form takma adlarını theme.json içinde bildirir. Bir bağlama plugin, type, schema_version ve instance değerlerini belirtir; kurulum bunu kalıcı bir site formu UUID’sine çözümler. İletişim şablonları forms.contact, potansiyel müşteri bileşenleri ise form_binding ile component.form kullanır. Sağlanan alanları, action değerini, CSRF belirtecini, imzalı form_context değerini ve verification_html çıktısını işleyin. Yalnızca bildirilen sunum değişikliklerini veya izin verilen ek alanları kullanın; zorunlu eklenti doğrulaması zayıflatılamaz. Eyivo ile gelen tüm temalar bu sözleşmeyi kullanır. Harici eylemler ve kullanımdan kaldırılan iletişim POST isteği desteklenen gönderim yolları değildir.
{"component_type":"eyivo:lead_form","data":{"form_binding":"contact"}}
Forms API 1
{
"api": "1",
"approval": "Only configured, approved Eyivo system form packages may declare forms; they require Human Verification and mandatory Panel API 2 submission pages.",
"schema": "forms.types maps stable identifiers to schema_version, localized label, fields, extensions, workflow and a restricted processor file. Fields declare scalar type, compatible control, required flag, localized label and guidance; strings require explicit max. No PHP, SQL, validation expressions or unknown fields are accepted.",
"field_types": [
"string",
"integer",
"boolean"
],
"controls": [
"text",
"textarea",
"email",
"tel",
"url",
"date",
"datetime-local",
"select",
"number",
"checkbox"
],
"presentation_extensions": [
"label",
"placeholder",
"help",
"order"
],
"storage": "The host owns site content storage. Plugin packages receive no credentials, database connection, SQL or unrestricted internal services. Site ownership is injected; schema snapshots remain readable without installed plugin code.",
"quotas": "Submission data consumes the existing package database allowance. Configuration limits of 50 fields / 32768 bytes / three levels do not cap form fields or accumulated submissions. Existing runtime, request and pagination bounds are technical transport protections.",
"identity": "Each site/plugin/type has a retained default form UUID created during authorized setup. Themes resolve portable aliases; rendering does not create instances. Additional named instances receive their own UUID. Theme changes and plugin reinstall preserve history.",
"transport": {
"encoding": "Escaped JSON byte counts match the restricted plugin interpreter; these technical ceilings do not limit accumulated form or submission counts.",
"schema_bytes": 49152,
"schema_accounting": "Definition plus one additional workflow copy, reserving the repeated workflow information on detail responses.",
"answers_bytes": 49152,
"source_bytes": 4096,
"processor_context_bytes": 114688,
"maximum_api_page": 25,
"instances_summary": [
"id",
"plugin_id",
"form_type",
"name",
"schema_version_id",
"record_revision",
"is_default"
]
}
}
Eklenti manifest örneği
{
"id": "eyivo/human-verification",
"name": "Human Verification",
"version": "1.1.0",
"api": "1",
"type": "system",
"origin": "system",
"required": true,
"capabilities": [
"form.inject",
"form.validate",
"frontend.assets",
"public.endpoint",
"verification.challenge",
"verification.verify",
"panel.render"
],
"panel": {
"api": "1",
"entry": "settings",
"pages": {
"settings": {
"title": {
"en": "Human Verification",
"id": "Verifikasi Manusia",
"tr": "\u0130nsan Do\u011frulama",
"de": "Menschliche Verifizierung",
"es": "Verificaci\u00f3n humana",
"fr": "V\u00e9rification humaine",
"pt": "Verifica\u00e7\u00e3o humana",
"it": "Verifica umana",
"ar": "\u0627\u0644\u062a\u062d\u0642\u0642 \u0627\u0644\u0628\u0634\u0631\u064a"
},
"permission": "view",
"view": "panel/settings.json",
"actions": []
}
},
"menu": [],
"actions": []
},
"dependencies": {
"plugins": []
},
"conflicts": [],
"configuration": [],
"defaults": [],
"hooks": {
"form.before_submit": "render.php",
"form.validate": "validate.php"
},
"render_hook": "form.before_submit",
"required_validators": [
"contact"
],
"lifecycle": [],
"assets": [
{
"path": "assets/verification.css",
"type": "style"
},
{
"path": "assets/verification.js",
"type": "script"
}
],
"endpoints": {
"challenge": {
"method": "GET",
"handler": "challenge.php",
"parameters": {
"form_id": {
"type": "string",
"required": true,
"enum": [
"contact"
]
},
"locale": {
"type": "string",
"max": 10
}
},
"response": {
"token": {
"type": "string",
"max": 4096
},
"image": {
"type": "string",
"max": 65536
},
"expires_in": {
"type": "integer"
}
}
}
}
}
Sistem eklentisi · eyivo/contact · Forms API 1 / Panel API 2
{
"id": "eyivo/contact",
"name": "Contact",
"version": "1.0.0",
"api": "1",
"type": "system",
"origin": "system",
"required": false,
"capabilities": [
"forms.submissions.create",
"forms.submissions.read",
"forms.submissions.manage",
"forms.instances.read",
"forms.instances.manage",
"panel.render",
"panel.action"
],
"dependencies": {
"plugins": [
"eyivo/human-verification"
]
},
"conflicts": [],
"configuration": [],
"defaults": [],
"hooks": [],
"required_validators": [],
"lifecycle": [],
"assets": [],
"endpoints": [],
"forms": {
"api": "1",
"types": {
"contact": {
"schema_version": 1,
"label": {
"en": "Contact",
"id": "Kontak",
"tr": "İletişim",
"de": "Kontakt",
"es": "Contacto",
"fr": "Contact",
"pt": "Contato",
"it": "Contatti",
"ar": "التواصل",
"ru": "Контакт",
"nl": "Contact",
"pl": "Kontakt",
"ja": "お問い合わせ",
"ko": "문의",
"zh": "联系"
},
"fields": {
"name": {
"type": "string",
"control": "text",
"required": true,
"label": {
"en": "Name",
"id": "Nama",
"tr": "Ad",
"de": "Name",
"es": "Nombre",
"fr": "Nom",
"pt": "Nome",
"it": "Nome",
"ar": "الاسم",
"ru": "Имя",
"nl": "Naam",
"pl": "Imię i nazwisko",
"ja": "氏名",
"ko": "이름",
"zh": "姓名"
},
"max": 255,
"placeholder": {
"en": "Your full name",
"id": "Nama lengkap Anda",
"tr": "Adınız ve soyadınız",
"de": "Ihr vollständiger Name",
"es": "Tu nombre completo",
"fr": "Votre nom complet",
"pt": "Seu nome completo",
"it": "Il tuo nome completo",
"ar": "اسمك الكامل",
"ru": "Ваше полное имя",
"nl": "Uw volledige naam",
"pl": "Twoje imię i nazwisko",
"ja": "氏名を入力してください",
"ko": "성명을 입력하세요",
"zh": "请输入您的姓名"
},
"autocomplete": "name"
},
"email": {
"type": "string",
"control": "email",
"required": true,
"label": {
"en": "Email",
"id": "Email",
"tr": "E-posta",
"de": "E-Mail",
"es": "Correo electrónico",
"fr": "E-mail",
"pt": "E-mail",
"it": "Email",
"ar": "البريد الإلكتروني",
"ru": "Электронная почта",
"nl": "E-mail",
"pl": "E-mail",
"ja": "メールアドレス",
"ko": "이메일",
"zh": "电子邮箱"
},
"max": 254,
"placeholder": {
"en": "Your email address",
"id": "Alamat email Anda",
"tr": "E-posta adresiniz",
"de": "Ihre E-Mail-Adresse",
"es": "Tu dirección de correo",
"fr": "Votre adresse e-mail",
"pt": "Seu endereço de e-mail",
"it": "Il tuo indirizzo email",
"ar": "عنوان بريدك الإلكتروني",
"ru": "Ваш адрес электронной почты",
"nl": "Uw e-mailadres",
"pl": "Twój adres e-mail",
"ja": "メールアドレスを入力してください",
"ko": "이메일 주소를 입력하세요",
"zh": "请输入您的电子邮箱地址"
},
"autocomplete": "email"
},
"phone": {
"type": "string",
"control": "tel",
"required": false,
"label": {
"en": "Phone",
"id": "Telepon",
"tr": "Telefon",
"de": "Telefon",
"es": "Teléfono",
"fr": "Téléphone",
"pt": "Telefone",
"it": "Telefono",
"ar": "الهاتف",
"ru": "Телефон",
"nl": "Telefoon",
"pl": "Telefon",
"ja": "電話番号",
"ko": "전화번호",
"zh": "电话"
},
"max": 50,
"placeholder": {
"en": "Country code and phone number",
"id": "Kode negara dan nomor telepon",
"tr": "Ülke kodu ve telefon numarası",
"de": "Ländervorwahl und Telefonnummer",
"es": "Código de país y teléfono",
"fr": "Indicatif du pays et numéro",
"pt": "Código do país e telefone",
"it": "Prefisso internazionale e numero",
"ar": "رمز الدولة ورقم الهاتف",
"ru": "Код страны и номер телефона",
"nl": "Landcode en telefoonnummer",
"pl": "Numer telefonu z kodem kraju",
"ja": "国番号と電話番号を入力してください",
"ko": "국가 코드와 전화번호를 입력하세요",
"zh": "请输入国家代码和电话号码"
},
"autocomplete": "tel"
},
"message": {
"type": "string",
"control": "textarea",
"required": true,
"label": {
"en": "Message",
"id": "Pesan",
"tr": "Mesaj",
"de": "Nachricht",
"es": "Mensaje",
"fr": "Message",
"pt": "Mensagem",
"it": "Messaggio",
"ar": "الرسالة",
"ru": "Сообщение",
"nl": "Bericht",
"pl": "Wiadomość",
"ja": "メッセージ",
"ko": "메시지",
"zh": "留言"
},
"max": 20000,
"placeholder": {
"en": "Describe your question or request",
"id": "Jelaskan pertanyaan atau permintaan Anda",
"tr": "Sorunuzu veya talebinizi açıklayın",
"de": "Beschreiben Sie Ihre Frage oder Anfrage",
"es": "Describe tu pregunta o solicitud",
"fr": "Décrivez votre question ou demande",
"pt": "Descreva sua dúvida ou solicitação",
"it": "Descrivi la tua domanda o richiesta",
"ar": "صف سؤالك أو طلبك",
"ru": "Опишите ваш вопрос или запрос",
"nl": "Beschrijf uw vraag of verzoek",
"pl": "Opisz swoje pytanie lub prośbę",
"ja": "ご質問やご要望を入力してください",
"ko": "질문이나 요청 내용을 설명하세요",
"zh": "请描述您的问题或需求"
}
}
},
"extensions": {
"presentation": [
"label",
"placeholder",
"help",
"order"
],
"field_types": [
"string",
"integer",
"boolean"
]
},
"workflow": {
"initial": "received",
"states": {
"received": {
"en": "Received",
"id": "Diterima",
"tr": "Alındı",
"de": "Eingegangen",
"es": "Recibido",
"fr": "Reçu",
"pt": "Recebido",
"it": "Ricevuto",
"ar": "تم الاستلام"
},
"in_progress": {
"en": "In progress",
"id": "Sedang diproses",
"tr": "İşlemde",
"de": "In Bearbeitung",
"es": "En curso",
"fr": "En cours",
"pt": "Em andamento",
"it": "In corso",
"ar": "قيد المعالجة"
},
"completed": {
"en": "Completed",
"id": "Selesai",
"tr": "Tamamlandı",
"de": "Abgeschlossen",
"es": "Completado",
"fr": "Terminé",
"pt": "Concluído",
"it": "Completato",
"ar": "مكتمل"
}
},
"transitions": {
"start": {
"from": [
"received"
],
"to": "in_progress",
"label": {
"en": "Start processing",
"id": "Mulai proses",
"tr": "İşleme al",
"de": "Bearbeitung starten",
"es": "Iniciar gestión",
"fr": "Commencer le traitement",
"pt": "Iniciar atendimento",
"it": "Avvia elaborazione",
"ar": "بدء المعالجة"
}
},
"complete": {
"from": [
"received",
"in_progress"
],
"to": "completed",
"label": {
"en": "Complete",
"id": "Selesaikan",
"tr": "Tamamla",
"de": "Abschließen",
"es": "Completar",
"fr": "Terminer",
"pt": "Concluir",
"it": "Completa",
"ar": "إكمال"
}
},
"reopen": {
"from": [
"completed"
],
"to": "received",
"label": {
"en": "Reopen",
"id": "Buka kembali",
"tr": "Yeniden aç",
"de": "Erneut öffnen",
"es": "Reabrir",
"fr": "Rouvrir",
"pt": "Reabrir",
"it": "Riapri",
"ar": "إعادة الفتح"
}
}
}
},
"processor": "submit.php"
}
}
},
"panel": {
"api": "2",
"entry": "submissions",
"pages": {
"submissions": {
"title": {
"en": "Contact",
"id": "Kontak",
"tr": "İletişim",
"de": "Kontakt",
"es": "Contacto",
"fr": "Contact",
"pt": "Contato",
"it": "Contatti",
"ar": "التواصل"
},
"permission": "view",
"view": "panel/submissions.json",
"actions": []
},
"submission": {
"title": {
"en": "Submission",
"id": "Kiriman",
"tr": "Form kaydı",
"de": "Einsendung",
"es": "Solicitud",
"fr": "Demande",
"pt": "Solicitação",
"it": "Richiesta",
"ar": "الطلب"
},
"permission": "view",
"view": "panel/submission.json",
"actions": []
}
},
"menu": [
{
"page": "submissions",
"label": {
"en": "Contact",
"id": "Kontak",
"tr": "İletişim",
"de": "Kontakt",
"es": "Contacto",
"fr": "Contact",
"pt": "Contato",
"it": "Contatti",
"ar": "التواصل"
},
"icon": "list",
"order": 100
}
],
"actions": []
}
}
Bildirilen yetenekler
Bir paketin ihtiyaç duyduğu yetenekleri bildirin. Sunucu, her işleme izin vermeden önce bunları denetler.
frontend.renderfrontend.assetsform.injectform.validatepublic.endpointsite.settings.readsite.settings.writeverification.challengeverification.verifypanel.renderpanel.actionforms.submissions.createforms.submissions.readforms.submissions.manageforms.instances.readforms.instances.manage
Kancalar ve yaşam döngüsü olayları
Ön yüz kancaları
page.headpage.body.startpage.body.endform.startform.before_fieldsform.after_fieldsform.before_submitform.after_submitform.end
Arka uç kancaları
form.before_validateform.validateform.after_validateform.before_processform.after_process
Yaşam döngüsü olayları
installenabledisableuninstallupgrade
Doğrulama ve işleme sırası
Ortak form motoru, doğrulamadan önce kiracıyı, imzalı yerleşim bağlamını, güncel eklentiyi/şemayı ve bildirilen yanıtları doğrular. Kanıt kurtarmayı denemeye ve kanonik yüke bağlar. Durumu ve kotayı yeniden denetledikten sonra sahip kısıtlı işlemci, deneme makbuzu, kullanım değişikliği ve bildirim işiyle birlikte tek bir içerik işleminde sunucu API’si üzerinden kaydeder. Aynı yeniden denemeler tekrar kaydetmeden makbuzu kurtarır. E-posta teslimi daha sonra gerçekleşir ve yeniden denenebilir; e-posta hatası kaydedilmiş bir gönderimi asla silmez.
Kısıtlı PHP çalışma ortamı
eyivo-php-subset-1
Bağlam ve sonuçlar
İşleyiciler $context değerini JSON uyumlu veri olarak alır: site_id, site_public_id, plugin_id, api, configuration, locale ve geçerli page/form_id/form_type/action/method/fields/validation_state. Site kimliğini her zaman sunucu sağlar. İşleme kancaları bir html alanı, doğrulama kancaları ise mantıksal bir valid alanı döndürür. Her zorunlu doğrulayıcı açıkça true döndürmelidir. Diğer arka uç kancaları bir dizi döndürür. Gönderilen alanlar sınırlıdır ve yalnızca herkese açık form alanlarını ve kanıtı içerir. Framework nesneleri, gizli anahtarlar, kullanıcı belirteçleri ve veritabanı bağlantıları asla sunulmaz.
API köprüsü ve izinler
$pluginApi; get, post, put, patch ve delete yöntemlerini sabit bir işlem kimliği ve bir parametre dizisiyle sunar. Her işlem; yöntem, yetenek, istek şeması, yanıt şeması ve isteğe bağlı eklenti kısıtlaması açısından manifeste göre denetlenir. Sunulmayan URL’ler reddedilir. Site ve eklenti kapsamı geçersiz kılınamaz. Ayar işlemleri, kimliği doğrulanmış Internal API yapılandırma yönetimiyle aynı uygulama hizmetini paylaşır. Ayar yazma işlemleri yetkili yaşam döngüsü işleyicileri ve sahibin yetkilendirdiği yönetme panel eylemleriyle sınırlıdır. Sayfa yükleyicileri, görüntüleme eylemleri, herkese açık uç noktalar ve işleme kancaları kurulum yapılandırmasını değiştiremez.
Desteklenen sözdizimini ve çalışma limitlerini görüntüleyin
{
"execution": "Interpreted PHP subset. Package code is never included, evaluated, or autoloaded by PHP.",
"statements": [
"local assignment",
"return array",
"if / else with braces"
],
"expressions": [
"single-quoted strings",
"integers",
"booleans",
"null",
"arrays",
"array lookup",
"concatenation",
"strict equality",
"strict inequality",
"boolean operators",
"null coalescing"
],
"functions": [
"trim",
"strtolower",
"strlen",
"count",
"htmlspecialchars"
],
"forbidden": [
"all undeclared functions",
"superglobals",
"objects and classes",
"dynamic calls",
"references",
"loops",
"includes",
"eval",
"filesystem access",
"network access",
"database access",
"environment access",
"configuration manipulation",
"deserialization"
],
"source_bytes": 32768,
"tokens": 4096,
"syntax_depth": 32,
"evaluation_steps": 4096,
"api_calls_per_handler": 16,
"handler_wall_seconds": 10,
"binary_expression_chain": 128,
"forms_per_page": 32,
"data_bytes": 131072
}
Varlıklar ve herkese açık uç noktalar
Paketler yerel betik, stil ve görsel dosyalarını kaydeder. Betikler/stiller eklenti işlendiğinde bir kez yüklenir; yalnızca kayıtlı dosyalar sunulur. Satır içi eklenti HTML’i bir öğe/öznitelik izin listesi kullanır. Özel tema İçerik Güvenliği Politikası, kayıtlı betik özetlerini Alt Kaynak Bütünlüğü ile yetkilendirir. Uç noktalar /__eyivo/plugins/{namespace}/{name}/{endpoint} yolunu, açık yöntemleri ve bildirilen girdi alanlarını kullanır. Kiracı çözümleme, hız limitleri ve güvenli olmayan yöntemler için CSRF koruması sunucunun denetiminde kalır. Eklenti uç noktaları asla rastgele uygulama rotaları eklemez.
İnsan Doğrulaması
eyivo/human-verification her sitede zorunludur. plugins.eyivo.com/verification adresindeki ortak hizmet, 180 saniyede süresi dolan şifreli altı haneli PNG doğrulamaları kullanır. Güvenilir istemci kimliği, verilen hizmetler ve kaynak IP’ler uygulanır. Kayıtlı form UUID’leri ve deneme kimlikleri her doğrulamayı bağlar; doğrulama kanonik yükü de bağlar. Kabul edilen aynı denemeler sonuçlarını 24 saat boyunca kurtarabilir; bu nedenle önceki anahtarları bu süre artı saat/ağ payı kadar saklayın. Süresi yeni dolan kanıtlar başarısız olur. Ortak eklenti veritabanı tekrar/hız limiti/makbuz durumunu saklar, form yanıtlarını veya gelen kutusu geçmişini asla saklamaz. Paketler veritabanı erişimi almaz.
Erişilebilirlik ve tarayıcı davranışı
Kontrolün yerelleştirilmiş etiketleri, girdi rehberliği, durum duyuruları ve bir görsel yenileme düğmesi vardır. JavaScript etkin olmalıdır. Bu ilk yalnızca görsel modu, görseli algılayamayan ziyaretçiler tamamlayamaz; erişilebilir alternatif bir doğrulama v1 kapsamında değildir. Desteklenen formları içeren sayfalar ortak HTML önbelleğini atlar. Tema önizlemeleri mevcut no-script politikasını korur ve çalışan doğrulamalar gönderemez.
Sunulan API işlemleri
Bu işlem kimliklerini $pluginApi üzerinden kullanın. Aşağıdaki her kayıt, çalışma zamanı izinlerini uygulamak için kullanılan aynı erişim manifestinden gelir.
site.settings.read
Read the current plugin's namespaced site configuration.
site.settings.read
$pluginApi->get('site.settings.read', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": [],
"response": {
"configuration": {
"type": "object"
}
},
"restricted_to_plugins": null,
"deprecated": false
}
site.settings.update
Replace the current plugin's configuration using its declared schema.
site.settings.write
$pluginApi->put('site.settings.update', ['configuration' => []]);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": {
"configuration": {
"type": "object",
"required": true
}
},
"response": {
"configuration": {
"type": "object"
}
},
"restricted_to_plugins": null,
"deprecated": false
}
form.verification.widget
Render a localized verification control for a supported form.
form.inject
$pluginApi->get('form.verification.widget', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": [],
"response": {
"html": {
"type": "string",
"max": 16384
}
},
"restricted_to_plugins": [
"eyivo/human-verification"
],
"deprecated": false
}
form.verification.challenge
Request a numeric image challenge bound to the current site and form.
verification.challenge
$pluginApi->get('form.verification.challenge', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": [],
"response": {
"token": {
"type": "string",
"max": 4096
},
"image": {
"type": "string",
"max": 65536
},
"expires_in": {
"type": "integer"
}
},
"restricted_to_plugins": [
"eyivo/human-verification"
],
"deprecated": false
}
form.verification.verify
Consume a proof once. Rejection never allows form processing.
verification.verify
$pluginApi->post('form.verification.verify', ['token' => $context['fields']['verification_token'], 'answer' => $context['fields']['verification_answer']]);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": {
"token": {
"type": "string",
"required": true,
"max": 4096
},
"answer": {
"type": "string",
"required": true,
"max": 12
}
},
"response": {
"valid": {
"type": "boolean"
}
},
"restricted_to_plugins": [
"eyivo/human-verification"
],
"deprecated": false
}
forms.submissions.create
Persist only the host-validated and verified attempt supplied out-of-band to the owning processor; accepts no answers or ownership override.
forms.submissions.create
$pluginApi->post('forms.submissions.create', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": [],
"response": {
"result": {
"type": "object"
}
},
"restricted_to_plugins": null,
"deprecated": false
}
forms.submissions.list
Read paginated submission summaries for the current site and plugin in an authenticated panel context.
forms.submissions.read
$pluginApi->get('forms.submissions.list', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": {
"form_type": {
"type": "string",
"max": 64
},
"form_id": {
"type": "string",
"max": 36
},
"cursor": {
"type": "string",
"max": 1024
},
"per_page": {
"type": "integer",
"min": 1,
"max": 25
},
"read": {
"type": "boolean"
},
"archived": {
"type": "boolean"
},
"workflow_state": {
"type": "string",
"max": 64
},
"from": {
"type": "string",
"max": 10
},
"to": {
"type": "string",
"max": 10
}
},
"response": {
"result": {
"type": "object"
}
},
"restricted_to_plugins": null,
"deprecated": false
}
forms.submissions.read
Read a historical submission snapshot owned by the current site and plugin.
forms.submissions.read
$pluginApi->get('forms.submissions.read', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": {
"submission_id": {
"type": "string",
"max": 36,
"required": true
}
},
"response": {
"result": {
"type": "object"
}
},
"restricted_to_plugins": null,
"deprecated": false
}
forms.submissions.update
Apply authorized reading/archive changes or a declared workflow transition using the current record revision.
forms.submissions.manage
$pluginApi->patch('forms.submissions.update', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": {
"submission_id": {
"type": "string",
"max": 36,
"required": true
},
"record_revision": {
"type": "integer",
"min": 1,
"required": true
},
"read": {
"type": "boolean"
},
"archived": {
"type": "boolean"
},
"transition": {
"type": "string",
"max": 64
}
},
"response": {
"result": {
"type": "object"
}
},
"restricted_to_plugins": null,
"deprecated": false
}
forms.submissions.delete
Explicitly delete an owned submission, cancel pending notifications and release its stored byte charge; preserve technical replay protection.
forms.submissions.manage
$pluginApi->delete('forms.submissions.delete', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": {
"submission_id": {
"type": "string",
"max": 36,
"required": true
},
"record_revision": {
"type": "integer",
"min": 1,
"required": true
}
},
"response": {
"result": {
"type": "object"
}
},
"restricted_to_plugins": null,
"deprecated": false
}
forms.instances.list
Read cursor-paginated compact form summaries belonging to the current site and plugin; settings are not included.
forms.instances.read
$pluginApi->get('forms.instances.list', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": {
"form_type": {
"type": "string",
"max": 64
},
"cursor": {
"type": "string",
"max": 1024
},
"per_page": {
"type": "integer",
"min": 1,
"max": 25
},
"q": {
"type": "string",
"max": 160
}
},
"response": {
"result": {
"type": "object"
}
},
"restricted_to_plugins": null,
"deprecated": false
}
forms.instances.create
Create a separate named form instance with an automatically generated UUID.
forms.instances.manage
$pluginApi->post('forms.instances.create', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": {
"form_type": {
"type": "string",
"max": 64,
"required": true
},
"name": {
"type": "string",
"max": 160,
"required": true
}
},
"response": {
"result": {
"type": "object"
}
},
"restricted_to_plugins": null,
"deprecated": false
}
forms.instances.update
Update a current form instance name or schema-compatible settings under owner/manage authorization and record revision.
forms.instances.manage
$pluginApi->patch('forms.instances.update', []);
Parametreleri, yanıtı ve kısıtlamaları görüntüleyin
{
"parameters": {
"form_id": {
"type": "string",
"max": 36,
"required": true
},
"record_revision": {
"type": "integer",
"min": 1,
"required": true
},
"name": {
"type": "string",
"max": 160
},
"settings": {
"type": "object"
}
},
"response": {
"result": {
"type": "object"
}
},
"restricted_to_plugins": null,
"deprecated": false
}
Uyumluluk ve dağıtım
Eklenti API 1, Forms API 1 ve Panel API 1/2’yi destekler. Form paketleri Panel API 2 liste/ayrıntı sayfalarını ve menü bildirimlerini gerektirir. Desteklenmeyen sözleşmeler ve güvenli olmayan sözdizimi reddedilir. Önce doğrulama makbuzu hizmetini, ardından master/içerik geçişlerini, eklenti uzlaştırmasını, eski veri geçişini ve kullanım muhasebesini dağıtın; uyumlu uygulama işleyicisini ve Apex başvurusunu daha sonra dağıtın. Geri alma sırasında geçmişi ve eski anahtarları koruyun. Eyivo ile gelen tüm temalar kayıtlı formları kullanır; eski iletişim POST istekleri 410 döndürür. Erişim manifesti bu başvuruyu ve çalışma zamanı izinlerini sağlar.