Kayıt Oluşturma ve Düzenleme Formu

Her ikisi için de aynı formu kullanarak Nette'de kayıt ekleme ve düzenleme nasıl düzgün bir şekilde uygulanır?

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

Kayıt Ekleme

Kayıt eklemek için kullanılan bir sunum örneği. Gerçek veritabanı işini, kodu örnekle ilgili 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ı ekle ...

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

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

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

Bir Kaydı Düzenleme

Şimdi bir kaydı düzenlemek için kullanılan bir sunucunun nasıl görüneceğini görelim:

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ı doğrulayın
			|| !$this->facade->isEditAllowed(/*...*/) // izinleri kontrol et
		) {
			$this->error(); // 404 hatası
		}

		$this->record = $record;
	}

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

		$form = new Form;

		// ... form alanları ekle ...

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

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

Sunucu yaşam döngüsünün hemen başında çağrılan action yönteminde, kaydın varlığını ve kullanıcının düzenleme iznini doğrularız.

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

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

		// varsayılan form 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, tüm kodlardan çıkarılacak en önemli sonuç bu olmalıdır, formu oluştururken eylemin gerçekten edit olduğundan emin olmamız gerekir. Çünkü aksi takdirde actionEdit() yöntemindeki doğrulama hiç gerçekleşmez!

Ekleme ve Düzenleme için Aynı Form

Ve şimdi her iki sunucuyu bir araya getireceğiz. Ya createComponentRecordForm() yönteminde hangi eylemin yer aldığını ayırt edip formu buna göre yapılandırabiliriz ya da doğrudan eylem yöntemlerine 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ı doğrulamak
			|| !$this->facade->isEditAllowed(/*...*/) // izinleri kontrol edin
		) {
			$this->error(); // 404 hatası
		}

		$form = $this->getComponent('recordForm');
		$form->setDefaults($record); // varsayılanları ayarla
		$form->onSuccess[] = [$this, 'editingFormSucceeded'];
	}

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

		$form = new Form;

		// ... form alanları ekle ...

		return $form;
	}

	public function addingFormSucceeded(Form $form, array $data): void
	{
		$this->facade->add($data); // veritabanına kayıt ekle
		$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ı güncelle
		$this->flashMessage('Başarıyla güncellendi');
		$this->redirect('...');
	}
}