Controller ve Yönlendirme
Bir controller tek bir adres ailesine cevap verir; isteğin sayfa mı değişiklik mi olduğuna karar verir ve şablonun ihtiyaç duyduğunu toplar.
Genel Bakış
Her controller tek bir taban sınıftan türer; o taban hiçbir controller'ın tekrarlamaması gereken işi yapar. Eşleşen modeli yükler, view'ı sunar, şablon verisini toplar ve gelen operation'ı doğru metoda dağıtır.
Bir controller dosyasında iki tür metot bulunur: sayfa üreten metotlar ve veriyi değiştiren operation metotları. Diğer her şeyin yeri bir yardımcı.
Yapı
coremio/controllers/{yüzey}/{ad}.php — admin, website ya da system.
coremio/models/{yüzey}/{ad}.php. $this->model ile erişirsiniz; kendiniz kurmazsınız.
templates/{yüzey}/{ad}/, sunulan sayfa başına bir dosya.
coremio/operations/ altındaki trait'ler; controller onları kullanır ve metotları kendi metodu olur.
Başlangıç dosyayı yola göre dahil eder, sınıf adını üç adımda çözer ve tek bir giriş metodunu çağırır. Üç biçimden hiçbirine uymayan ad, "sınıf bulunamadı" hatası değil bulunamadı sayfası verir.
// 1. dosya yola göre dahil edilir, asla otomatik yüklenmez
include CONTROLLER_DIR . $surface . DS . $controller . '.php';
// 2. sınıf adı şu sırayla denenir (ayraçlar kaldırılır, büyük/küçük harf duyarsız)
// \WISECP\controllers\{yüzey}\{ad} -> {Ad}Controller -> Controller
// 3. ad ve rota anahtarı kuruluştan ÖNCE yayımlanır
Controllers::$cname = $controller; // "widgets"
Controllers::$rkey = $route_key; // eşleşen rota kaydı
// 4. params, constructor bir parametre bildirmediyse kuruluştan SONRA atanır
$this->controller = new $className();
$this->controller->params = $params;
// 5. giriş noktası: index() önceliklidir, main() yedektir
$content = method_exists($this->controller, 'index')
? $this->controller->index()
: $this->controller->main();
Referans
İki Tür Metot
Taban sınıf ikisini de bildirmez; ikisi de dağıtıcı konvansiyonu. Sayfa metodu adres parçasının adını taşır ve işaretleme döndürür; boş dize, şablonu kurma işini çağırana bırakır. Operation metodu kayıtlı operation'ın adını taşır, tek argüman alır, sayfa üretmez.
// page_{parça}[_{altparça}[_{altparça}]] - tire ve nokta alt çizgiye dönüşür
public function page_list(&$links, &$meta, &$breadcrumbs): string;
// kayıtlı her operation adı için bir operation metodu
public function save_widget(Operation $operation): bool;
Üç Sayfa Argümanı Ne Taşır
Referansla verilen çıktılar. Çağıran onları set_predefined_data()'ya geçirir, o da aşağıdaki adlarla yayımlar. Kırıntı anahtarı yolda çoğulunu kaybeder.
['controller' => LinkGenerator::admin("widgets")]. Sayfanın geri gönderdiği taban adres; şablonlar ve tablo bileşeni bunu okur.
['title' => 'Widgets']. Dizi olmalı: content artı variables biçimli bir dil anahtarında Language::gc() dize döner ve tip bildirimi hata fırlatır.
[['link' => string|null, 'title' => string], ...]. Null bağlantı, bağlantısız mevcut adım olarak görünür.
Taban Sınıfın Verdikleri
public Models $model; // sizin için, ada bakılarak kurulur
public View $view;
public array $params = []; // controller'dan sonraki URL parçaları
public array $data = []; // şablonun alacağı veri
public array $operations = []; // kayıt tablosu
public bool $loggedIn = false;
public bool $loginControl = false;
public static string|int $cname = ''; // controller adı
public static string|int $rkey = ''; // eşleşen rota anahtarı
public static array $rparams = []; // eşleşen rotanın parametreleri, slug DAHİL
public function addData($k = '', $v = ''): void;
public function getData($key);
public function takeDatas($which = []): void;
public function set_predefined_data(string $type = 'client', array $meta = [], array $breadcrumbs = [], array $links = []): void;
public function operation(string $name = '', array $operations = []): bool;
public function checkLogin(bool $redirect = true): bool;
public function client_gate(bool $requireComplete = true): ?string;
public function page_404($type = 'admin'): string;
public function page_denied(string $scope = ''): string;
public function CRLink($r_key = '', $params = [], $slang = ''): string|bool;
public function AdminCRLink($r_key = '', $params = [], $slang = ''): string|bool;
public function RouteURI($params = [], $key = null, $slang = '', $admin = false): string;
public function ControllerURI(): string;
protected function localize_lang_links(string $routeKey, array $slugByLang): void;
$this->data'ya adlandırılmış tek bir değer ekler. View diziyi extract eder, şablonlar bu adı değişken olarak okur.
null.
"admin" panel kabuğunu, "client" müşteri paneli bağlamını yükler ve filter:client.predefined_data'yı ateşler. Diğer her değer yalnız bağlantı, künye, kırıntı ve yerel ayarı yayımlar. Sayfa üretilmeden önce çağrılır.
set_predefined_data()'nın kurulduğu bloklar, anahtar kelimeyle: admin-sign-all, admin_info, lang_list, account_info, website_logos. Tam bir taraf kurmadan tek blok gerekiyorsa doğrudan çağrılır.
loginControl'ü kurar ve oturum yokken başlangıç giriş metodunu atlar.
null devam demektir; başka her değer zaten yönlendirmiş ya da cevaplamıştır, dönüşünü siz return edersiniz.
website/denied/scope-* ifadelerine eşlenir.
Kayıt Tablosu
Kayıt, bir isteğin gönderebileceği operation adını küçük bir özellik dizisine eşler. İki anahtar okunur, ikisi de isteğe bağlıdır.
public function __construct()
{
parent::__construct();
$this->operations = array_merge($this->operations, [
// 'privileges' => string[] oturumun TAMAMINA sahip olması gereken yetki anahtarları
// 'method' => string operation adından farklıysa çağrılacak metot
'save_widget' => ['privileges' => ['WIDGETS_OPERATION']],
'delete' => ['privileges' => ['WIDGETS_OPERATION'], 'method' => 'delete_widget'],
'view_detail' => ['privileges' => ['WIDGETS_LOOK', 'WIDGETS_OPERATION']],
]);
}
// coremio/classes/Controllers.php tam olarak bu iki anahtarı okur:
private function run_operation(string $name = '', array $properties = []): bool;
// $method = $properties["method"] ?? $name;
// $privileges = $properties["privileges"] ?? [];
// if ($privileges && !Admin::isPrivilege($privileges)) throw new Exception(...);
Yönlendirme
Adresler sabit yazılmaz; bağlantılar rota anahtarından üretilir. Her dilin kendi rota tablosu vardır, aynı controller her dilde farklı bir yola cevap verir. Bir rota kaydı 'anahtar' => ['desen', 'controller'] biçimindedir; (?) tek bir parçadır: 'services' => ['services/(?)', 'services'].
// Router: örnek metotları, Router::getInstance() üzerinden erişilir
public static function getInstance(array $routes = []): self;
public function get(string $url): ?array; // ['key' => string, 'controller' => string|callable, 'params' => array] ya da null
public function add(string $name, string $pattern, string|array|callable $handler): void;
public function generate(string $name, array $params = []): ?string;
public function matchController(array $params): string; // controller adı, slug hiçbir şeye çözülmezse ''
public function findRoute($controller, $params): bool; // *_lang tablolarında memo'lu slug araması
public function setRoutes(array $routes): self;
public function setLang($lang): self;
public function getRoutes(): array;
// LinkGenerator: statik
public static function admin($route = '', $params = [], $lang = '', $wqs = []): string|bool;
public static function client($route = '', $params = [], $lang = '');
public static function wQS(string|bool|null $url, array|string $params = []): string;
public static function convert_to_link(string $arg): string;
filter:routing.prematch, dinamik desenler, sabitler, en son filter:routing.match.
router.php dosyasından rota kaydeder; başlangıç her modül dizini için birini dahil eder. İşleyici callable olabilir.
admin("services", ["detail", 5], "", ["tab" => "invoices"]).
Örnek
namespace WISECP\controllers\admin;
use Controllers;
use Filter;
use Language;
use LinkGenerator;
use WISECP\Operations\AdminWidgets;
class widgets extends Controllers
{
use AdminWidgets; // operation metotları bu trait'te yaşar
public function __construct()
{
parent::__construct();
$this->checkLogin();
$this->operations = array_merge($this->operations, [
'save_widget' => ['privileges' => ['WIDGETS_OPERATION']],
]);
}
public function main()
{
if ($operation = Filter::init("REQUEST/operation", "route")) return $this->operation($operation);
$page = $this->params[0] ?? 'list';
$links = ['controller' => LinkGenerator::admin("widgets")];
$meta = ['title' => Language::gc("admin/widgets/page-list")];
$breadcrumbs = [
['link' => LinkGenerator::admin("dashboard"), 'title' => Language::gc("admin/index/breadcrumb-name")],
['link' => null, 'title' => Language::gc("admin/widgets/breadcrumb-list")],
];
$method = "page_" . str_replace(["-", "."], "_", $page);
if (method_exists($this, $method) && ($out = $this->$method($links, $meta, $breadcrumbs))) return $out;
// Sıraya dikkat: links burada SON argüman, yukarıda İLK argümandı.
$this->set_predefined_data("admin", $meta, $breadcrumbs, $links);
return $this->view->chose("admin")->render("widgets/" . $page, $this->data, true);
}
public function page_list(&$links, &$meta, &$breadcrumbs): string
{
$this->addData("rows", $this->model->list(false, [], ['id' => 'DESC'], 0, 25));
$this->addData("clink", $links["controller"]);
return ''; // main() templates/admin/widgets/list.php'yi render eder
}
}
<?php /* $rows ve $clink addData()'dan; $meta ile $breadcrumb set_predefined_data()'dan gelir */ ?>
<ul>
<?php foreach ($rows as $row): ?>
<li><a href="<?= $clink ?>/detail/<?= (int) $row['id'] ?>"><?= htmlspecialchars($row['title'] ?? '') ?></a></li>
<?php endforeach; ?>
</ul>
Tuzaklar
Dağıtıcı, ad kayıtlıysa ya da o adda bir metot varsa isteği kabul eder. Kaydedilmemiş metot boş özellik dizisiyle çalışır — yetki kontrolü yok. Kayıt bir metodu çağrılabilir yapmaz; ona yetki iliştirir.
Sayfa metodu (&$links, &$meta, &$breadcrumbs) alır; set_predefined_data() ($type, $meta, $breadcrumbs, $links) ister. Aldığınız sırayla geçirirseniz bağlantılar künyenin yerine oturur ve sayfa hata vermek yerine başlıksız görünür.
Rotalar çevrilir ve panel dizini yapılandırılabilir. Bağlantıları rota anahtarından üretin; sabit yazılmış yol başka dilde ya da kurulumda kırılır.
Veriyi değiştiren her şeyin yeri operation'dır; yetki kontrolü, demo koruması ve JSON hata biçimi orada geçerlidir. Sayfa metoduna gizlenmiş bir yazma bunların hiçbirine sahip değildir.
İ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.