Nette Documentation Preview

syntax
Modello
*******

Man mano che la nostra applicazione cresce, ci accorgiamo presto di dover eseguire operazioni di database simili in varie posizioni e in vari presentatori, ad esempio acquisendo gli articoli pubblicati più recenti. Se miglioriamo la nostra applicazione aggiungendo un flag agli articoli per indicare lo stato di work-in-progress, dobbiamo anche esaminare tutte le posizioni della nostra applicazione e aggiungere una clausola where per assicurarci che vengano selezionati solo gli articoli finiti.

A questo punto, il lavoro diretto con il database diventa insufficiente e sarà più intelligente aiutarsi con una nuova funzione che restituisca gli articoli pubblicati. E quando in seguito aggiungeremo un'altra clausola (ad esempio per non visualizzare gli articoli con data futura), modificheremo il codice in un solo punto.

Inseriamo la funzione nella classe `PostFacade` e la chiamiamo `getPublicArticles()`.

Creeremo la nostra classe modello `PostFacade` nella cartella `app/Model/` per occuparci dei nostri articoli:

```php .{file:app/Model/PostFacade.php}
<?php
namespace App\Model;

use Nette;

final class PostFacade
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}

	public function getPublicArticles()
	{
		return $this->database
			->table('posts')
			->where('created_at < ', new \DateTime)
			->order('created_at DESC');
	}
}
```

Nella classe passiamo il database Explorer:[api:Nette\Database\Explorer]. Questo sfrutterà la potenza del [contenitore DI |dependency-injection:passing-dependencies].

Passiamo a `HomePresenter`, che modificheremo in modo da eliminare la dipendenza da `Nette\Database\Explorer`, sostituendola con una nuova dipendenza dalla nostra nuova classe.

```php .{file:app/UI/Home/HomePresenter.php}
<?php
namespace App\UI\Home;

use App\Model\PostFacade;
use Nette;

final class HomePresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private PostFacade $facade,
	) {
	}

	public function renderDefault(): void
	{
		$this->template->posts = $this->facade
			->getPublicArticles()
			->limit(5);
	}
}
```

Nella sezione d'uso, stiamo usando `App\Model\PostFacade`, quindi possiamo abbreviare il codice PHP in `PostFacade`. Richiediamo questo oggetto nel costruttore, lo scriviamo nella proprietà `$facade` e lo usiamo nel metodo renderDefault.

L'ultimo passo da fare è insegnare al contenitore DI a produrre questo oggetto. Di solito lo si fa aggiungendo un punto elenco al file `config/services.neon` nella sezione `services`, indicando il nome completo della classe e i parametri del costruttore.
Questo lo registra, per così dire, e l'oggetto viene chiamato **service**. Grazie a una magia chiamata [autowiring |dependency-injection:autowiring], di solito non è necessario specificare i parametri del costruttore, perché DI li riconosce e li passa automaticamente. Pertanto, sarebbe sufficiente fornire solo il nome della classe:

```neon .{file:config/services.neon}
...

services:
	- App\Model\PostFacade
```

Tuttavia, non è necessario aggiungere questa riga. Nella sezione `search` all'inizio di `services.neon` si definisce che tutte le classi che terminano con `-Facade` o `-Factory` saranno cercate automaticamente da DI, cosa che avviene anche per `PostFacade`.


Riepilogo .[#toc-summary]
=========================

La classe `PostFacade` chiede `Nette\Database\Explorer` in un costruttore e poiché questa classe è registrata nel contenitore DI, il contenitore crea questa istanza e la passa. DI crea così un'istanza di `PostFacade` per noi e la passa in un costruttore alla classe HomePresenter che l'ha richiesta. Una specie di matrioska di codice. :) Tutti i componenti richiedono solo ciò di cui hanno bisogno e non si preoccupano di dove e come viene creato. La creazione è gestita dal contenitore DI.

.[note]
Qui si possono leggere ulteriori informazioni sulla [dependency injection |dependency-injection:introduction] e sulla [configurazione |nette:configuring].

{{priority: -1}}
{{sitename: Nette Quickstart}}

Modello

Man mano che la nostra applicazione cresce, ci accorgiamo presto di dover eseguire operazioni di database simili in varie posizioni e in vari presentatori, ad esempio acquisendo gli articoli pubblicati più recenti. Se miglioriamo la nostra applicazione aggiungendo un flag agli articoli per indicare lo stato di work-in-progress, dobbiamo anche esaminare tutte le posizioni della nostra applicazione e aggiungere una clausola where per assicurarci che vengano selezionati solo gli articoli finiti.

A questo punto, il lavoro diretto con il database diventa insufficiente e sarà più intelligente aiutarsi con una nuova funzione che restituisca gli articoli pubblicati. E quando in seguito aggiungeremo un'altra clausola (ad esempio per non visualizzare gli articoli con data futura), modificheremo il codice in un solo punto.

Inseriamo la funzione nella classe PostFacade e la chiamiamo getPublicArticles().

Creeremo la nostra classe modello PostFacade nella cartella app/Model/ per occuparci dei nostri articoli:

<?php
namespace App\Model;

use Nette;

final class PostFacade
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}

	public function getPublicArticles()
	{
		return $this->database
			->table('posts')
			->where('created_at < ', new \DateTime)
			->order('created_at DESC');
	}
}

Nella classe passiamo il database Explorer. Questo sfrutterà la potenza del contenitore DI.

Passiamo a HomePresenter, che modificheremo in modo da eliminare la dipendenza da Nette\Database\Explorer, sostituendola con una nuova dipendenza dalla nostra nuova classe.

<?php
namespace App\UI\Home;

use App\Model\PostFacade;
use Nette;

final class HomePresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private PostFacade $facade,
	) {
	}

	public function renderDefault(): void
	{
		$this->template->posts = $this->facade
			->getPublicArticles()
			->limit(5);
	}
}

Nella sezione d'uso, stiamo usando App\Model\PostFacade, quindi possiamo abbreviare il codice PHP in PostFacade. Richiediamo questo oggetto nel costruttore, lo scriviamo nella proprietà $facade e lo usiamo nel metodo renderDefault.

L'ultimo passo da fare è insegnare al contenitore DI a produrre questo oggetto. Di solito lo si fa aggiungendo un punto elenco al file config/services.neon nella sezione services, indicando il nome completo della classe e i parametri del costruttore. Questo lo registra, per così dire, e l'oggetto viene chiamato service. Grazie a una magia chiamata autowiring, di solito non è necessario specificare i parametri del costruttore, perché DI li riconosce e li passa automaticamente. Pertanto, sarebbe sufficiente fornire solo il nome della classe:

...

services:
	- App\Model\PostFacade

Tuttavia, non è necessario aggiungere questa riga. Nella sezione search all'inizio di services.neon si definisce che tutte le classi che terminano con -Facade o -Factory saranno cercate automaticamente da DI, cosa che avviene anche per PostFacade.

Riepilogo

La classe PostFacade chiede Nette\Database\Explorer in un costruttore e poiché questa classe è registrata nel contenitore DI, il contenitore crea questa istanza e la passa. DI crea così un'istanza di PostFacade per noi e la passa in un costruttore alla classe HomePresenter che l'ha richiesta. Una specie di matrioska di codice. :) Tutti i componenti richiedono solo ciò di cui hanno bisogno e non si preoccupano di dove e come viene creato. La creazione è gestita dal contenitore DI.

Qui si possono leggere ulteriori informazioni sulla dependency injection e sulla configurazione.