Creazione e modifica dei post

È fantastico! Abbiamo un nuovo blog super cool, le persone discutono animatamente nei commenti e noi abbiamo finalmente un po' di tempo per programmare ulteriormente. Sebbene Adminer sia uno strumento eccellente, non è del tutto ideale per scrivere nuovi post sul blog. Probabilmente è il momento giusto per creare un semplice form per aggiungere nuovi post direttamente dall'applicazione. Facciamolo.

Iniziamo progettando l'interfaccia utente:

  1. Nella pagina iniziale aggiungeremo un link “Scrivi un nuovo post”.
  2. Questo link visualizzerà un form con un titolo e una textarea per il contenuto del post.
  3. Quando clicchiamo sul pulsante Salva, il post verrà salvato nel database.

Successivamente aggiungeremo anche il login e permetteremo l'aggiunta di post solo agli utenti loggati. Ma questo più tardi. Quale codice dobbiamo scrivere ora affinché tutto funzioni?

  1. Creeremo un nuovo presenter con un form per aggiungere post.
  2. Definiremo un callback che verrà eseguito dopo l'invio riuscito del form e che salverà il nuovo post nel database.
  3. Creeremo un nuovo template su cui sarà presente quel form.
  4. Aggiungeremo un link al form nel template della pagina principale.

Nuovo presenter

Chiameremo il nuovo presenter EditPresenter e lo salveremo in app/Presentation/Edit/EditPresenter.php. Ha anche bisogno di connettersi al database, quindi scriveremo di nuovo un costruttore che richiederà la connessione al database:

<?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,
	) {
	}
}

Form per il salvataggio dei post

Abbiamo già spiegato i form e i componenti durante la creazione dei commenti. Se non è ancora chiaro, andate a rivedere la creazione di form e componenti, noi aspetteremo qui ;)

Ora aggiungiamo questo metodo al presenter EditPresenter:

protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Titolo:')
		->setRequired();
	$form->addTextArea('content', 'Contenuto:')
		->setRequired();

	$form->addSubmit('send', 'Salva e pubblica');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}

Salvataggio di un nuovo post dal form

Continuiamo aggiungendo un metodo che elabori i dati dal form:

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

	$this->flashMessage("Il post è stato pubblicato con successo.", 'success');
	$this->redirect('Post:show', $post->id);
}

Solo un rapido riepilogo: questo metodo ottiene i dati dal form, li inserisce nel database, crea un messaggio per l'utente sull'avvenuto salvataggio del post e reindirizza alla pagina con il nuovo post, così vedremo subito come appare.

Pagina per la creazione di un nuovo post

Creiamo ora il template Edit/create.latte:

{block content}
<h1>Nuovo post</h1>

{control postForm}

Tutto dovrebbe essere già chiaro. L'ultima riga renderizza il form che creeremo a breve.

Potremmo creare anche il metodo renderCreate() corrispondente nel presenter, ma non è necessario. Non abbiamo bisogno di ottenere dati dal database e passarli al template, quindi quel metodo sarebbe vuoto. In questi casi, il metodo render<View> può essere omesso.

Link per la creazione dei post

Probabilmente sapete già come aggiungere un link a EditPresenter e alla sua azione create. Provateci.

Basta aggiungere al file app/Presentation/Home/default.latte:

<a n:href="Edit:create">Scrivi un nuovo post</a>

Modifica dei post

Ora aggiungeremo anche la possibilità di modificare un post. Sarà molto semplice. Abbiamo già pronto il form postForm e possiamo usarlo anche per la modifica.

Aggiungiamo una nuova pagina edit al presenter EditPresenter:

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

	if (!$post) {
		$this->error('Post non trovato');
	}

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

E creiamo un altro template Edit/edit.latte:

{block content}
<h1>Modifica post</h1>

{control postForm}

E modifichiamo il metodo postFormSucceeded, che sarà in grado sia di aggiungere un nuovo articolo (come fa ora) sia di modificare un articolo già esistente:

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('Il post è stato pubblicato con successo.', 'success');
	$this->redirect('Post:show', $post->id);
}

Se il parametro id è disponibile, significa che modificheremo il post. In tal caso, verifichiamo che il post richiesto esista davvero e, in caso affermativo, lo aggiorniamo nel database. Se il parametro id non è disponibile, significa che dovrebbe essere aggiunto un nuovo post.

Ma da dove viene il parametro id? Si tratta del parametro che è stato inserito nel metodo renderEdit.

Ora possiamo aggiungere un link al template app/Presentation/Post/show.latte:

<a n:href="Edit:edit $post->id">Modifica post</a>

Shrnutí

Il blog è ora funzionante, i visitatori commentano attivamente e non abbiamo più bisogno di Adminer per la pubblicazione. L'applicazione è completamente indipendente e chiunque può aggiungere un nuovo post. Aspetta un attimo, probabilmente non è del tutto corretto che chiunque – e intendo davvero chiunque abbia accesso a Internet – possa aggiungere nuovi post. È necessaria una qualche forma di sicurezza affinché solo un utente loggato possa aggiungere un nuovo post. Vedremo questo nel prossimo capitolo.