Nette Documentation Preview

syntax
Modelo
******

À medida que a aplicação cresce, logo descobriremos que em diferentes lugares, em diferentes presenters, precisamos realizar operações semelhantes com o banco de dados. Por exemplo, obter os artigos publicados mais recentemente. Se melhorarmos a aplicação, por exemplo, adicionando um sinalizador aos artigos para indicar se estão em rascunho, teremos que percorrer todos os lugares na aplicação onde os artigos são obtidos do banco de dados e adicionar uma condição where para selecionar apenas os artigos não rascunhados.

Nesse momento, o trabalho direto com o banco de dados se torna insuficiente e será mais conveniente usar uma nova função que nos retornará os artigos publicados. E quando adicionarmos outra condição posteriormente, por exemplo, que artigos com data futura não devem ser exibidos, modificaremos o código em apenas um lugar.

Colocaremos a função, por exemplo, na classe `PostFacade` e a chamaremos de `getPublicArticles()`.

No diretório `app/Model/`, criaremos nossa classe de modelo `PostFacade`, que cuidará dos artigos:

```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');
	}
}
```

Na classe, solicitaremos a passagem do Database Explorer:[api:Nette\Database\Explorer] através do construtor. Aproveitaremos assim o poder do [contêiner de DI|dependency-injection:passing-dependencies].

Mudaremos para o `HomePresenter`, que modificaremos para nos livrarmos da dependência de `Nette\Database\Explorer` e a substituiremos pela nova dependência de nossa nova classe.

```php .{file:app/Presentation/Home/HomePresenter.php}
<?php
namespace App\Presentation\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);
	}
}
```

Na seção use, temos `App\Model\PostFacade`, então podemos encurtar a escrita no código PHP para `PostFacade`. Solicitaremos este objeto no construtor, o escreveremos na propriedade `$facade` e o usaremos no método renderDefault.

Resta o último passo, que é ensinar o contêiner de DI a produzir este objeto. Isso geralmente é feito adicionando um marcador ao arquivo `config/services.neon` na seção `services`, indicando o nome completo da classe e os parâmetros do construtor. Assim, o registramos e o objeto é então chamado de **serviço**. Graças à mágica chamada [autowiring |dependency-injection:autowiring], geralmente não precisamos especificar os parâmetros do construtor, pois o DI os reconhece e os passa automaticamente. Bastaria, portanto, indicar apenas o nome da classe:

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

services:
	- App\Model\PostFacade
```

No entanto, você nem precisa adicionar esta linha. Na seção `search` no início de `services.neon`, está definido que todas as classes terminadas com a palavra `-Facade` ou `-Factory` serão encontradas automaticamente pelo DI, o que também é o caso de `PostFacade`.


Resumo
======

A classe `PostFacade` solicita a passagem de `Nette\Database\Explorer` em seu construtor e, como esta classe está registrada no contêiner de DI, o contêiner cria esta instância e a passa. O DI cria assim para nós a instância de `PostFacade` e a passa no construtor para a classe HomePresenter, que a solicitou. É como uma matriosca. :) Todos apenas dizem o que querem e não se preocupam onde e como algo é criado. O contêiner de DI cuida da criação.

.[note]
Aqui você pode ler mais sobre [injeção de dependência |dependency-injection:introduction] e [configuração |nette:configuring].

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

Modelo

À medida que a aplicação cresce, logo descobriremos que em diferentes lugares, em diferentes presenters, precisamos realizar operações semelhantes com o banco de dados. Por exemplo, obter os artigos publicados mais recentemente. Se melhorarmos a aplicação, por exemplo, adicionando um sinalizador aos artigos para indicar se estão em rascunho, teremos que percorrer todos os lugares na aplicação onde os artigos são obtidos do banco de dados e adicionar uma condição where para selecionar apenas os artigos não rascunhados.

Nesse momento, o trabalho direto com o banco de dados se torna insuficiente e será mais conveniente usar uma nova função que nos retornará os artigos publicados. E quando adicionarmos outra condição posteriormente, por exemplo, que artigos com data futura não devem ser exibidos, modificaremos o código em apenas um lugar.

Colocaremos a função, por exemplo, na classe PostFacade e a chamaremos de getPublicArticles().

No diretório app/Model/, criaremos nossa classe de modelo PostFacade, que cuidará dos artigos:

<?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');
	}
}

Na classe, solicitaremos a passagem do Database Explorer através do construtor. Aproveitaremos assim o poder do contêiner de DI.

Mudaremos para o HomePresenter, que modificaremos para nos livrarmos da dependência de Nette\Database\Explorer e a substituiremos pela nova dependência de nossa nova classe.

<?php
namespace App\Presentation\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);
	}
}

Na seção use, temos App\Model\PostFacade, então podemos encurtar a escrita no código PHP para PostFacade. Solicitaremos este objeto no construtor, o escreveremos na propriedade $facade e o usaremos no método renderDefault.

Resta o último passo, que é ensinar o contêiner de DI a produzir este objeto. Isso geralmente é feito adicionando um marcador ao arquivo config/services.neon na seção services, indicando o nome completo da classe e os parâmetros do construtor. Assim, o registramos e o objeto é então chamado de serviço. Graças à mágica chamada autowiring, geralmente não precisamos especificar os parâmetros do construtor, pois o DI os reconhece e os passa automaticamente. Bastaria, portanto, indicar apenas o nome da classe:

...

services:
	- App\Model\PostFacade

No entanto, você nem precisa adicionar esta linha. Na seção search no início de services.neon, está definido que todas as classes terminadas com a palavra -Facade ou -Factory serão encontradas automaticamente pelo DI, o que também é o caso de PostFacade.

Resumo

A classe PostFacade solicita a passagem de Nette\Database\Explorer em seu construtor e, como esta classe está registrada no contêiner de DI, o contêiner cria esta instância e a passa. O DI cria assim para nós a instância de PostFacade e a passa no construtor para a classe HomePresenter, que a solicitou. É como uma matriosca. :) Todos apenas dizem o que querem e não se preocupam onde e como algo é criado. O contêiner de DI cuida da criação.

Aqui você pode ler mais sobre injeção de dependência e configuração.