Kayıt Oluşturma ve Düzenleme Formu

Nette'de, her ikisi için de aynı formu kullanarak bir kaydın eklenmesini ve düzenlenmesini nasıl doğru bir şekilde uygulayabiliriz?

Birçok durumda, kayıt ekleme ve düzenleme formları aynıdır, belki sadece düğme üzerindeki etiket farklıdır. Formu önce kayıt eklemek, sonra düzenlemek için kullanacağımız ve son olarak her iki çözümü birleştireceğimiz basit presenter örneklerini göstereceğiz.

Kayıt Ekleme

Kayıt eklemeye hizmet eden bir presenter örneği. Veritabanıyla olan asıl işi, kodu gösterim için önemli olmayan Facade sınıfına bırakacağız.

use Nette\Application\UI\Form;

class RecordPresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private Facade $facade,
	) {
	}

	protected function createComponentRecordForm(): Form
	{
		$form = new Form;

		// ... form alanlarını ekleyin ...

		$form->onSuccess[] = [$this, 'recordFormSucceeded'];
		return $form;
	}

	public function recordFormSucceeded(Form $form, array $data): void
	{
		$this->facade->add($data); // veritabanına kayıt ekleme
		$this->flashMessage('Başarıyla eklendi');
		$this->redirect('...');
	}

	public function renderAdd(): void
	{
		// ...
	}
}

Kayıt Düzenleme

Şimdi bir kaydı düzenlemeye hizmet eden presenter'ın nasıl görüneceğini göstereceğiz:

use Nette\Application\UI\Form;

class RecordPresenter extends Nette\Application\UI\Presenter
{
	private $record;

	public function __construct(
		private Facade $facade,
	) {
	}

	public function actionEdit(int $id): void
	{
		$record = $this->facade->get($id);
		if (
			!$record // kaydın varlığının doğrulanması
			|| !$this->facade->isEditAllowed(/*...*/) // yetki kontrolü
		) {
			$this->error(); // hata 404
		}

		$this->record = $record;
	}

	protected function createComponentRecordForm(): Form
	{
		// eylemin 'edit' olduğunu doğrulayın
		if ($this->getAction() !== 'edit') {
			$this->error();
		}

		$form = new Form;

		// ... form alanlarını ekleyin ...

		$form->setDefaults($this->record); // varsayılan değerlerin ayarlanması
		$form->onSuccess[] = [$this, 'recordFormSucceeded'];
		return $form;
	}

	public function recordFormSucceeded(Form $form, array $data): void
	{
		$this->facade->update($this->record->id, $data); // kaydın güncellenmesi
		$this->flashMessage('Başarıyla güncellendi');
		$this->redirect('...');
	}
}

Presenter yaşam döngüsünün hemen başında çalışan action metodunda, kaydın varlığını ve kullanıcının onu düzenleme iznini doğrularız.

Kaydı $record özelliğinde saklarız, böylece varsayılan değerleri ayarlamak için createComponentRecordForm() metodunda ve ID için recordFormSucceeded() metodunda kullanılabilir olur. Alternatif bir çözüm, varsayılan değerleri doğrudan actionEdit() içinde ayarlamak ve URL'nin bir parçası olan ID değerini getParameter('id') kullanarak almaktır:

	public function actionEdit(int $id): void
	{
		$record = $this->facade->get($id);
		if (
			// varlığın doğrulanması ve yetki kontrolü
		) {
			$this->error();
		}

		// formun varsayılan değerlerini ayarlama
		$this->getComponent('recordForm')
			->setDefaults($record);
	}

	public function recordFormSucceeded(Form $form, array $data): void
	{
		$id = (int) $this->getParameter('id');
		$this->facade->update($id, $data);
		// ...
	}
}

Ancak, ve bu tüm kodun en önemli çıkarımı olmalı, formu oluştururken eylemin gerçekten edit olduğundan emin olmalıyız. Aksi takdirde, actionEdit() metodundaki doğrulama hiç gerçekleşmezdi!

Ekleme ve Düzenleme için Aynı Form

Ve şimdi her iki presenter'ı tek bir tanede birleştireceğiz. Ya createComponentRecordForm() metodunda hangi eylemin söz konusu olduğunu ayırt edebilir ve formu buna göre yapılandırabiliriz ya da bunu doğrudan action metotlarına bırakıp koşuldan kurtulabiliriz:

class RecordPresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private Facade $facade,
	) {
	}

	public function actionAdd(): void
	{
		$form = $this->getComponent('recordForm');
		$form->onSuccess[] = [$this, 'addingFormSucceeded'];
	}

	public function actionEdit(int $id): void
	{
		$record = $this->facade->get($id);
		if (
			!$record // kaydın varlığının doğrulanması
			|| !$this->facade->isEditAllowed(/*...*/) // yetki kontrolü
		) {
			$this->error(); // hata 404
		}

		$form = $this->getComponent('recordForm');
		$form->setDefaults($record); // varsayılan değerlerin ayarlanması
		$form->onSuccess[] = [$this, 'editingFormSucceeded'];
	}

	protected function createComponentRecordForm(): Form
	{
		// eylemin 'add' veya 'edit' olduğunu doğrulayın
		if (!in_array($this->getAction(), ['add', 'edit'])) {
			$this->error();
		}

		$form = new Form;

		// ... form alanlarını ekleyin ...

		return $form;
	}

	public function addingFormSucceeded(Form $form, array $data): void
	{
		$this->facade->add($data); // veritabanına kayıt ekleme
		$this->flashMessage('Başarıyla eklendi');
		$this->redirect('...');
	}

	public function editingFormSucceeded(Form $form, array $data): void
	{
		$id = (int) $this->getParameter('id');
		$this->facade->update($id, $data); // kaydın güncellenmesi
		$this->flashMessage('Başarıyla güncellendi');
		$this->redirect('...');
	}
}