Operation'lar
Veriye yapılan her değişiklik bir operation'dan geçer. İzinlerin, demo modunun, kancaların ve hata biçiminin her ekranda değil bir kez karara bağlanmasının sebebi budur.
Genel Bakış
Operation, bir isteğin adını anabildiği bir metottur. Bir istek operation adı taşıdığında controller hiçbir sayfa üretmez. O operation'a iliştirilen yetkiyi kontrol eder, metodu çağırır ve olan biteni bir JSON yanıtına çevirir.
Metodun kendisi bir trait içinde yazılır; böylece bir controller tek bir trait kullanarak ilişkili bir operation ailesini kazanır. Controller hangi operation'ları kabul ettiğini ve her birinin neye ihtiyaç duyduğunu bildirir.
Yapı
Dağıtıcının Sizin İçin Yaptıkları
// operation(): ad KAYITLIYSA ya da yalnızca metot olarak VARSA kabul edilir
$isOperation = isset($operations[$name]);
$isMethod = method_exists($this, $name);
$properties = $operations[$name] ?? [];
if ($isOperation || $isMethod) return $this->run_operation($name, $properties);
// Hiçbiri değilse son söz modüllerindir; dizi dönen bir dinleyici yanıtın kendisi olur.
foreach (Hook::run("register:admin.operations", Controllers::$cname, $name) as $hfn)
if ($hfn && is_array($hfn)) { echo Utility::jencode($hfn); return true; }
// Yine yoksa: {"status":"error","message":"Undefined operation: <ad>"}
// run_operation(), sırayla:
// 1. kayıttaki yetkiler -> Admin::isPrivilege(), aksi hâlde throw
// 2. method_exists($this, $method), aksi hâlde throw
// 3. $this->$method(new Operation($name, $properties));
// 4. catch (Exception $e) -> {"status":"error","message":$e->getMessage()}
Yazma biçiminizi değiştiren madde sonuncusudur. Hata yanıtı kurmazsınız; fırlatırsınız ve çağıranın okuduğu şey fırlattığınız mesajdır.
Referans
Operation Nesnesi
public ?string $name = ''; // bu operation'ın kayıtlı adı
public static ?string $last = ''; // bu süreçte kurulan son operation
public function __construct($name = '', $properties = []);
public function demo(): void; // demo modunda fırlatır
public function hook(string $name = '', array $vars = []): array; // ['overwrite' => array] | ['output' => mixed] | []
public static function output($response): bool; // her zaman true döner
public static function name(): ?string; // $last'ı okur, $this->name'i DEĞİL
output([]) çağıranın ayrıştıramayacağı boş bir gövdeyle cevaplar. Statiktir ama konvansiyon gereği örnek üzerinden çağrılır ve metot orada dursun diye döndürülür.
$last'ı okur. Operation'ın içinde ikisi aynıdır; sonradan çalışan bir dinleyicide kancanın zaten geçtiği adı tercih edin.
Kanca Sözleşmesi
İki ad paylaşılan genişleme noktalarının kısaltmasıdır, diğer her ad olduğu gibi kullanılır. Dinleyiciler her zaman üç argüman alır: controller adı, operation adı ve geçirdiğiniz değişkenler.
// Operation'ın içinde. "before" => filter:admin.operation.before
// "after" => filter:admin.operation.after
$hook = $operation->hook('before', get_defined_vars());
if ($hook && $hook["overwrite"] ?? []) extract($hook["overwrite"]); // dinleyici yerel değişkenlerinizi değiştirdi
if ($hook && $hook["output"] ?? false) return $operation->output($hook["output"]);
// Modülün hooks.php dosyasında. Dinleyici üç biçimden BİRİNİ döndürerek karar verir:
Hook::add('filter:admin.operation.before', 1, function ($controller, $operation, $vars) {
if ($controller !== 'widgets' || $operation !== 'save_widget') return null;
// 1. reddet: hook() bu mesajla fırlatır, run_operation onu hata JSON'una çevirir
if (!$vars["name"]) return ['status' => "error", 'message' => "Name is required"];
// 2. değiştir: bunlar extract() ile operation'ın yerel değişkenleri olur
if ($vars["name"] === "x") return ['overwrite_vars' => ['name' => "X"]];
// 3. cevapla: operation işi yapmak yerine bunu döndürür
return ['output' => ['status' => "successful", 'id' => 0]];
});
output() tarafından, referansla ve ikinci argümanda operation adıyla ateşlenir. Bir alan eklemek ya da çıkarmak için son şans.
Yanıt
Başarı ve başarısızlık tek bir alanı paylaşır, böylece çağıran yalnız status'a bakarak dallanır. Hata biçimini dağıtıcı sizin için üretir; başarı biçimi ise geçirdiğiniz şeydir ve konvansiyon gereği aynı alanı artı ekranın ihtiyacını taşır.
{ "status": "successful", "id": 42, "message": "Changes saved" }
{ "status": "error", "message": "Name is required" }
Örnek
namespace WISECP\Operations;
use Exception;
use Filter;
use Language;
use Operation;
trait AdminWidgets
{
public function save_widget(Operation $operation): bool
{
// Demo modu her yazmayı reddeder; bu her zaman ilk satırdır.
$operation->demo();
$id = (int) Filter::init("POST/id", "rnumbers");
$name = Filter::init("POST/name", "hclear");
if (!$name) throw new Exception(Language::gc("widgets/error-name-required"));
$hook = $operation->hook('before', get_defined_vars());
if ($hook && $hook["overwrite"] ?? []) extract($hook["overwrite"]);
if ($hook && $hook["output"] ?? false) return $operation->output($hook["output"]);
$saved = $id
? $this->model->update($id, ['name' => $name])
: $this->model->add(['name' => $name]);
if (!$saved) throw new Exception(Language::gc("widgets/error-save-failed"));
$response = ['status' => "successful", 'id' => (int) ($id ?: $saved)];
$hook = $operation->hook('after', get_defined_vars());
if ($hook && $hook["overwrite"] ?? []) extract($hook["overwrite"]);
if ($hook && $hook["output"] ?? false) return $operation->output($hook["output"]);
return $operation->output($response);
}
}
Diğer taraf, controller'ın kendi adresine yapılan sıradan bir form gönderimidir; operation adı bir alan olarak taşınır.
curl -X POST "$PANEL/widgets" \
-H "X-Requested-With: XMLHttpRequest" \
-d "operation=save_widget&id=42&name=Sidebar"
# {"status":"successful","id":42}
# {"status":"error","message":"You don't have privileges to access this operation."}
Tuzaklar
O olmadan demo kurulumu yazmayı gerçekten yapar ve yalnızca reddetmiş gibi görünür. En başta, herhangi bir okuma ya da doğrulamadan önce durur; böylece hiçbir şey onu atlayamaz.
Dağıtıcı yalnızca var olan bir metodu boş özellik dizisiyle çalıştırır; boş yetki listesi de kontrolün tamamen atlanması demektir. Controller'ın bir trait'ten kazandığı her public metot bir giriş noktasıdır: ya kaydedin ya da controller'a koymayın.
Fırlattığınız mesaj isteği yapan kişiye gösterilir. Sabit bir metin, kurulumun herkese tek bir dilde cevap vermesi demektir.
output() yanıtı yazar ve true döner; metodu durdurmaz. Döndürülmeyen bir çağrıdan sonrası yine çalışır ve JSON'un ardına ikinci bir gövde yazabilir.
İ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.