Ürün Modülü Müşteri Yönetimi
Bir ürün hizmetinde müşterinin ne göreceğine ve ne yapabileceğine beş isteğe bağlı üye karar verir. Bunlar yönetim sekmesi, göstergeler, kısayollar, aksiyonlar ve görünüm işaretidir.
Genel Bakış
Ürün modülü müşteriye varsayılan olarak hiçbir şey açmaz. Aşağıdaki beş üye isteğe bağlıdır ve tipten bağımsızdır; doldurmak için çekirdekte değişiklik gerekmez.
Özet sekmesi client_overview_data() çıktısından kurulan kullanım halkalarını ve hesap satırlarını gösterir; Yönetim sekmesi sizin pano sayfanızı gösterir. İkisinde de gösterge olabilir, bu yüzden modül hangisini doldurduğunu bilmelidir.
Ön Koşullar
- Çalışan bir ürün modülü: Ürün Modülü Yazma.
specialya dasoftwaretipinde,activeve bir modüle bağlı hizmet. Askıya alınmış dahil diğer durumlar başta reddedilir.- Müşteri olarak test edin; yönetici görünümü işareti ayarlamaz.
Yapı
| İstediğiniz | Modül ne yapar | Varsayılan |
|---|---|---|
| Müşteride hiç ekran olmasın | Hiçbir şey | Varsayılan |
| Yönetim sekmesi olsun | pages/dashboard.php ekleyin ya da page_dashboard() tanımlayın | Sekme yok |
| Sekme olmasın, pano yalnız yöneticide | has_client_management() false döndürsün | Sekme çıkar |
| Özette kullanım göstergeleri | client_overview_data() doldurun | Boş, gösterge yok |
| Özette kısayollar | client_quick_actions() doldurun | Boş, kısayol yok |
| Çalıştırılabilir bir aksiyon | Adını $client_callable_methods içinde bildirin, handle_{ad}() yazın | Reddedilir |
| GET ile sunulan aksiyon (indirme) | Ayrıca $client_readonly_methods içinde sayın | Token ve POST |
| Bir pano bloğunu müşteriden gizleyin | Bloğu $client_area denetimiyle sarın | İkisine de görünür |
Yönetim sekmesine tıklandı
└─ use_module_method'suz GET isteği -> ClientServices::get_management_details
├─ sahip + tip + etkin durum denetimi
├─ client_module_instance() -> $client_area = true, $area_link atanır
├─ ProductModule::service_management_page() -> get_page('dashboard')
└─ satır içi script etiketleri ayrılır, tema köprüsünce ayrıca değerlendirilir
Genel Bakış sekmesi
└─ hizmetler controller'ı, special ve software hizmetler için
├─ client_overview_data() -> kullanım halkaları + hesap satırları
└─ client_quick_actions() -> kısayol butonları
Bir kısayol ya da pano butonu
└─ POST use_module_method -> izin listesi -> handle_{name}()
Adım Adım
Yönetim Sekmesini Açın
Pano sayfası eklemek onaydır: kapı dosyaya bakar.
- Modülünüzde
pages/dashboard.phpoluşturun; içeride$modulecanlı örnektir. - Pano yalnız yöneticiler içinse kapıyı ezin. Admin hizmet sayfası yine de gösterir.
- Tema köprüsü satır içi script'leri HTML'den ayırır ve ayrıca değerlendirir.
Özeti Doldurun
client_overview_data() üç liste döndürür. Henüz bir şey sağlanmamışken boş dizi döndürün; özet o zaman gösterge göstermez.
gauges: limitli her kaynak için bir kayıt; sıfır ya da altı sınırsız demektir.resources: isteğe bağlı sayaçlar — kullanılan ve toplam biçimi ya da oran olmayan tek birvalue.account: kimlik satırları. Hizmet parolası sizin yerinize eklenir.
Bir Aksiyon Açın
İki şey gerekir, tek başına hiçbiri yetmez: adın izin listesinde olması ve handle_ ön ekli bir metot.
public array $client_callable_methods = ['reset_usage'];şeklinde, ön eksiz bildirin.public function handle_reset_usage(): arrayyazın — argümansız; istekten ve hizmetten okuyun.- API istemcisini handler'ın içinde kurun: müşteri çağrısı için hiçbir şey hazırlanmaz.
İki Kez Göstermekten Kaçının
Aynı dosya, özet sekmesi olmayan admin hizmet sayfasına da hizmet eder. Blokları silmek yerine $client_area arkasında gizleyin.
Referans
Beş Üye
// ProductModule üzerinde bildirilir; ihtiyacınız olanı ezin.
public bool $client_area = false; // yalnız müşteri basıcısı true yapar
public array $client_callable_methods = []; // handle_ ön eki OLMADAN adlar
public array $client_readonly_methods = []; // yukarıdakilerin alt kümesi, GET ile güvenli
public function has_client_management(): bool;
public function client_overview_data(): array;
public function client_quick_actions(int $limit = 8): array;
// Bildirilen bir çağrılabilir için işleyiciniz. Parametresiz; JSON yükünü döndürür.
public function handle_reset_usage(): array;
client_overview_data() Biçimi
return [
'gauges' => [
[
'key' => 'storage',
'label' => $this->lang['storage-usage'],
'icon' => 'bi bi-hdd',
'used' => 4.5,
'total' => 20, // 0 ya da altı sınırsız demektir; netlik için -1 geçin
'unit' => 'GB',
],
],
'resources' => [
// Oran biçimi: göstergeyle aynı anahtarlar.
['key' => 'seats', 'label' => 'Seats', 'icon' => 'bi bi-people', 'used' => 3, 'total' => 10, 'unit' => ''],
// Değer biçimi: limiti olmayan tek bir okuma.
['key' => 'region', 'label' => 'Region', 'icon' => 'bi bi-globe', 'value' => 'eu-west'],
],
'account' => [
['key' => 'account_id', 'label' => 'Account ID', 'type' => 'text', 'copyable' => true, 'value' => 'ac_1042'],
['key' => 'username', 'label' => 'Username', 'type' => 'text', 'copyable' => true, 'value' => 'acme'],
['key' => 'status', 'label' => 'Status', 'type' => 'badge', 'badge_color' => 'success', 'value' => 'Active'],
['key' => 'console', 'label' => 'Console', 'type' => 'link', 'value' => 'https://panel.example.com'],
],
];
text, link, badge ya da password. copyable kopyalama butonu ekler; bağlantı satırı tam genişlik alır.
success, warning, danger ya da varsayılan. İkon renkten gelir.
username olan satırın ardına, öyle bir satır yoksa en sona eklenir.
client_quick_actions() Biçimi
public function client_quick_actions(int $limit = 8): array
{
$actions = [
// action => true: işleyiciyi yerinde, çağrılabilir izin listesi üzerinden koşturur.
['key' => 'reset_usage', 'label' => $this->lang['action-reset-usage'],
'icon' => 'bi bi-arrow-counterclockwise', 'action' => true, 'method' => 'reset_usage'],
// action => false: bunun yerine yönetim sekmesindeki bir sayfaya gider.
['key' => 'backups', 'label' => $this->lang['action-backups'],
'icon' => 'bi bi-archive', 'action' => false, 'method' => 'backups'],
];
// Limite uyun: kaç tanesinin sığacağına çağıran karar verir.
return array_slice($actions, 0, $limit);
}
Handler'ınız Çalışmadan Önce
"Aksiyonum hiçbir şey yapmıyor" bildirimlerinin çoğu bu retlerden biridir.
// ClientServices::use_module_method, kararlara indirgenmiş hali.
$service = $this->owned_managed_service($uid); // sahiplik, tip, modül ve aktif durum denetimi
$method = (string) Filter::init("REQUEST/method", "route");
$module = $this->client_module_instance($service); // $client_area ve $area_link değerlerini ayarlar
$handleMethod = 'handle_' . str_replace('-', '_', $method);
$isTool = in_array($method, ['tool_action', 'tool_table', 'sso_panel_login'], true);
// İKİ koşul birden: izin listesinde bildirilmiş VE işleyici gerçekten var.
$isClientCallable = !$isTool
&& in_array($method, $module->client_callable_methods ?? [], true)
&& method_exists($module, $handleMethod);
if (!$isTool && !$isClientCallable)
throw new \Exception(Language::gc("website/services/err-invalid"));
// Salt okunur çağrılabilirler jetonu ve aktif hizmet şartını atlar.
$isReadonly = $isClientCallable && in_array($method, $module->client_readonly_methods ?? [], true);
$mutates = ($method === 'tool_action' || $isClientCallable) && !$isReadonly;
if ($mutates && !\Validation::verify_csrf_token((string) Filter::init("POST/token", "hclear"), "services"))
throw new \Exception(Language::g("needs/csrf-failed"));
if ($mutates && ($service['status'] ?? '') !== 'active')
throw new \Exception(Language::gc("website/services/err-invalid"));
none dışında bir modül adı taşımalıdır. "Hizmet Detaylarını Kısıtla" ile işaretlenen hizmet de bulunamadı sayılır.
handle_create gibi metotları müşteriye kapalı tutan şey budur.
active ister, dolayısıyla askıya alınmış hizmet okumada da reddedilir. Değişiklik yapan çağrı ayrıca geçerli bir token ister.
Örnek
Modül yarısı ve pano yarısı; $client_area kararı ikincisinde verilir.
// handle_ ön eki olmadan bildirilir. Burada olmayan her şey reddedilir.
public array $client_callable_methods = ['reset_usage', 'download_report'];
// GET bağlantısı üzerinden sunulur, bu yüzden jeton ve POST şartından muaftır.
public array $client_readonly_methods = ['download_report'];
public function client_overview_data(): array
{
$remote = $this->fetchRemoteStatus();
if (!$remote) return []; // henüz bir şey sağlanmadı: gösterge yok
$gauges = [];
if (isset($remote['storage_limit']))
$gauges[] = [
'key' => 'storage',
'label' => $this->lang['storage-usage'],
'icon' => 'bi bi-hdd',
'used' => (float) ($remote['used_storage'] ?? 0),
'total' => (float) $remote['storage_limit'] > 0 ? (float) $remote['storage_limit'] : -1,
'unit' => 'GB',
];
$account = [];
$username = (string) ($this->options['login']['username'] ?? '');
// Controller parola satırını tam bunun ardına ekler.
if ($username !== '')
$account[] = ['key' => 'username', 'label' => $this->lang['username'], 'type' => 'text', 'copyable' => true, 'value' => $username];
$status = (string) ($remote['status'] ?? '');
if ($status !== '')
$account[] = [
'key' => 'status',
'label' => $this->lang['account-status'],
'type' => 'badge',
'badge_color' => $status === 'active' ? 'success' : 'secondary',
'value' => $this->lang['status-' . $status] ?? ucfirst($status),
];
if (!$gauges && !$account) return [];
return ['gauges' => $gauges, 'resources' => [], 'account' => $account];
}
public function handle_reset_usage(): array
{
// Müşteri tetikler: API istemcisini sizin için hazırlayan hiçbir şey yok.
$this->initApi();
$accountId = $this->options['config']['id'] ?? '';
if (!$accountId) throw new Exception($this->lang['err-not-provisioned']);
$this->api->call('accounts/' . $accountId . '/usage/reset', [], 'POST');
return ['status' => 'successful', 'message' => $this->lang['usage-reset-ok']];
}
<?php
/** @var ProductModule $module */
// Yöneticide Özet sekmesi yok, bu yüzden bu blokları korumak zorunda. Müşteri aynı
// sayıları orada zaten görüyor; o yüzden burada silmek yerine gizleyin.
if (!($module->client_area ?? false)):
?>
<div class="row">
<!-- gösterge widget'ları ve hesap kartı -->
</div>
<?php endif; ?>
<!-- Aksiyonlar iki görünümde de kalır: burası yönetim yüzeyidir. -->
<button type="button" class="btn btn-primary" id="acmeResetUsage">Reset Usage</button>
<script>
(function () {
// Her aramayı null'a karşı koruyun: $client_area ile gizlenen blok kimliklerini de
// götürür ve buradaki yakalanmamış hata bu düğmeyi değil tüm paneli düşürür.
var btn = document.getElementById('acmeResetUsage');
if (!btn) return;
btn.addEventListener('click', function () {
run_module_method('reset_usage');
});
})();
</script>
Tuzaklar
$client_area ile gizlenen blok, eleman kimliklerini de götürür. O kayıp düğüm üzerinde addEventListener çağıran satır içi script hata fırlatır. Script köprüsü de onunla düşer ve müşteri genel bir "yüklenemedi" mesajı alır. Her aramayı koruyun.
Aksiyonu panoya koyun, kısayol da oraya işaret etsin.
Zamanlanmış görev bağlamında şablon çıktısı atlanır. Komut satırından bir sonda sıfır uzunlukta sayfa bildirir, gerçek istek panelin tamamını döndürür. Gerçek HTTP üzerinden ya da yönetici kimliğine bürünerek doğrulayın.
İlgili Makaleler
Geri bildiriminiz için teşekkürler!
Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.