Crearea și editarea postărilor

Este minunat! Avem un blog nou super cool, oamenii discută aprins în comentarii și avem în sfârșit puțin timp pentru mai multă programare. Deși Adminer este un instrument excelent, nu este tocmai ideal pentru scrierea de postări noi pe blog. Probabil că este momentul potrivit pentru a crea un formular simplu pentru adăugarea de postări noi direct din aplicație. Să trecem la treabă.

Să începem cu proiectarea interfeței utilizator:

  1. Pe pagina de pornire, adăugăm un link “Scrie o postare nouă”.
  2. Acest link va afișa un formular cu titlu și o zonă de text (textarea) pentru conținutul postării.
  3. Când facem clic pe butonul Salvare, postarea va fi salvată în baza de date.

Mai târziu, vom adăuga și autentificarea și vom permite adăugarea de postări doar utilizatorilor autentificați. Dar asta mai târziu. Ce cod trebuie să scriem acum pentru ca totul să funcționeze?

  1. Creăm un nou presenter cu un formular pentru adăugarea postărilor.
  2. Definim un callback care se va executa după trimiterea cu succes a formularului și care va salva noua postare în baza de date.
  3. Creăm un nou șablon în care va fi formularul respectiv.
  4. Adăugăm un link către formular în șablonul paginii principale.

Noul presenter

Vom numi noul presenter EditPresenter și îl vom salva în app/Presentation/Edit/. De asemenea, trebuie să se conecteze la baza de date, așa că vom scrie din nou aici un constructor care va necesita conexiunea la baza de date:

<?php
namespace App\Presentation\Edit;

use Nette;
use Nette\Application\UI\Form;

final class EditPresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}
}

Formular pentru salvarea postărilor

Am explicat deja formularele și componentele la crearea comentariilor. Dacă încă nu este clar, mergeți să parcurgeți crearea formularelor și componentelor, noi vom aștepta aici între timp ;)

Acum adăugați această metodă în presenterul EditPresenter:

protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Titlu:')
		->setRequired();
	$form->addTextArea('content', 'Conținut:')
		->setRequired();

	$form->addSubmit('send', 'Salvează și publică');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}

Salvarea unei postări noi din formular

Continuăm prin adăugarea metodei care va procesa datele din formular:

private function postFormSucceeded(array $data): void
{
	$post = $this->database
		->table('posts')
		->insert($data);

	$this->flashMessage("Postarea a fost publicată cu succes.", 'success');
	$this->redirect('Post:show', $post->id);
}

Doar o recapitulare rapidă: această metodă obține datele din formular, le inserează în baza de date, creează un mesaj pentru utilizator despre salvarea cu succes a postării și redirecționează către pagina cu noua postare, astfel încât să vedem imediat cum arată.

Pagina pentru crearea unei postări noi

Creăm acum șablonul Edit/create.latte:

{block content}
<h1>Postare nouă</h1>

{control postForm}

Totul ar trebui să fie deja clar. Ultima linie redă formularul pe care îl vom crea.

Am putea crea și o metodă renderCreate corespunzătoare, dar nu este necesar. Nu avem nevoie să obținem date din baza de date și să le transmitem șablonului, așa că metoda ar fi goală. În astfel de cazuri, metoda nu trebuie să existe deloc.

Probabil știți deja cum să adăugați un link către EditPresenter și acțiunea sa create. Încercați să o faceți.

Este suficient să adăugați în fișierul app/Presentation/Home/default.latte:

<a n:href="Edit:create">Scrie o postare nouă</a>

Editarea postărilor

Acum vom adăuga și posibilitatea de a edita o postare. Va fi foarte simplu. Avem deja formularul postForm gata și îl putem folosi și pentru editare.

Adăugăm o nouă pagină edit în presenterul EditPresenter:

public function renderEdit(int $id): void
{
	$post = $this->database
		->table('posts')
		->get($id);

	if (!$post) {
		$this->error('Postarea nu a fost găsită');
	}

	$this->getComponent('postForm')
		->setDefaults($post->toArray());
}

Și creăm un alt șablon Edit/edit.latte:

{block content}
<h1>Editează postarea</h1>

{control postForm}

Și modificăm metoda postFormSucceeded, care va putea atât să adauge un articol nou (așa cum face acum), cât și să editeze un articol existent:

private function postFormSucceeded(array $data): void
{
	$id = $this->getParameter('id');

	if ($id) {
		$post = $this->database
			->table('posts')
			->get($id);
		$post->update($data);

	} else {
		$post = $this->database
			->table('posts')
			->insert($data);
	}

	$this->flashMessage('Postarea a fost publicată cu succes.', 'success');
	$this->redirect('Post:show', $post->id);
}

Dacă parametrul id este disponibil, înseamnă că vom edita postarea. În acest caz, verificăm dacă postarea solicitată există într-adevăr și, dacă da, o actualizăm în baza de date. Dacă parametrul id nu este disponibil, atunci înseamnă că ar trebui adăugată o postare nouă.

Dar de unde vine parametrul id? Este parametrul care a fost introdus în metoda renderEdit.

Acum putem adăuga un link în șablonul app/Presentation/Post/show.latte:

<a n:href="Edit:edit $post->id">Editează postarea</a>

Rezumat

Blogul este acum funcțional, vizitatorii comentează activ și nu mai avem nevoie de Adminer pentru publicare. Aplicația este complet independentă și oricine poate adăuga o postare nouă. Stai puțin, probabil că nu este tocmai în regulă ca oricine – și prin asta înțeleg absolut oricine cu acces la internet – să poată adăuga postări noi. Este necesară o anumită securitate, astfel încât doar un utilizator autentificat să poată adăuga o postare nouă. Vom aborda acest aspect în capitolul următor.