Nette Documentation Preview

syntax
Model
*****

Uygulama büyüdükçe, yakında farklı yerlerde, farklı presenter'larda, veritabanıyla benzer işlemler yapmamız gerektiğini fark edeceğiz. Örneğin, en son yayınlanan makaleleri almak. Uygulamayı, örneğin makalelere taslak olup olmadıklarını belirten bir bayrak ekleyerek geliştirirsek, o zaman uygulamada makalelerin veritabanından alındığı tüm yerleri gözden geçirmeli ve yalnızca taslak olmayan makalelerin seçilmesi için where koşulunu eklemeliyiz.

Bu noktada, veritabanıyla doğrudan çalışmak yetersiz hale gelir ve bize yayınlanmış makaleleri döndürecek yeni bir fonksiyonla yardım etmek daha akıllıca olacaktır. Ve daha sonra başka bir koşul eklediğimizde, örneğin gelecekteki bir tarihe sahip makalelerin gösterilmemesi gerektiğini, kodu yalnızca tek bir yerde düzenleriz.

Fonksiyonu örneğin `PostFacade` sınıfına yerleştireceğiz ve `getPublicArticles()` olarak adlandıracağız.

`app/Model/` dizininde, makalelerimizle ilgilenecek olan model sınıfımız `PostFacade`'i oluşturacağız:

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

Sınıfta, yapıcı aracılığıyla veritabanı Explorer:[api:Nette\Database\Explorer]'ı aktarmasını isteyeceğiz. Böylece [DI konteynerinin|dependency-injection:passing-dependencies] gücünden yararlanacağız.

`HomePresenter`'a geçeceğiz, onu `Nette\Database\Explorer` bağımlılığından kurtulacak ve yeni sınıfımıza olan yeni bağımlılıkla değiştirecek şekilde düzenleyeceğiz.

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

Use bölümünde `App\Model\PostFacade` var, bu yüzden PHP kodundaki yazımı `PostFacade` olarak kısaltabiliriz. Bu nesneyi yapıcıda isteyeceğiz, `$facade` özelliğine yazacağız ve renderDefault metodunda kullanacağız.

Geriye kalan son adım, DI konteynerine bu nesneyi nasıl üreteceğini öğretmektir. Bu genellikle `config/services.neon` dosyasındaki `services` bölümüne bir madde işareti ekleyerek, sınıfın tam adını ve yapıcı parametrelerini belirterek yapılır. Böylece onu kaydederiz ve nesne daha sonra **servis** olarak adlandırılır. [Autowiring |dependency-injection:autowiring] adlı sihir sayesinde, çoğu zaman yapıcı parametrelerini belirtmemiz gerekmez, çünkü DI onları kendi başına tanır ve aktarır. Bu nedenle yalnızca sınıfın adını belirtmek yeterli olacaktır:

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

services:
	- App\Model\PostFacade
```

Ancak, bu satırı eklemeniz bile gerekmez. `services.neon` başındaki `search` bölümünde, `-Facade` veya `-Factory` ile biten tüm sınıfların DI tarafından kendi kendine bulunacağı tanımlanmıştır, bu da `PostFacade` durumu için geçerlidir.


Özet
====

`PostFacade` sınıfı, yapıcıda `Nette\Database\Explorer`'ın aktarılmasını ister ve bu sınıf DI konteynerinde kayıtlı olduğundan, konteyner bu örneği oluşturur ve aktarır. DI bizim için `PostFacade` örneğini bu şekilde oluşturur ve onu isteyen HomePresenter sınıfının yapıcısına aktarır. Böyle bir matruşka. :) Herkes sadece ne istediğini söyler ve neyin nerede ve nasıl yaratıldığıyla ilgilenmez. Oluşturma işini DI konteyneri halleder.

.[note]
Burada [dependency injection |dependency-injection:introduction] ve [yapılandırma |nette:configuring] hakkında daha fazla bilgi edinebilirsiniz.

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

Model

Uygulama büyüdükçe, yakında farklı yerlerde, farklı presenter'larda, veritabanıyla benzer işlemler yapmamız gerektiğini fark edeceğiz. Örneğin, en son yayınlanan makaleleri almak. Uygulamayı, örneğin makalelere taslak olup olmadıklarını belirten bir bayrak ekleyerek geliştirirsek, o zaman uygulamada makalelerin veritabanından alındığı tüm yerleri gözden geçirmeli ve yalnızca taslak olmayan makalelerin seçilmesi için where koşulunu eklemeliyiz.

Bu noktada, veritabanıyla doğrudan çalışmak yetersiz hale gelir ve bize yayınlanmış makaleleri döndürecek yeni bir fonksiyonla yardım etmek daha akıllıca olacaktır. Ve daha sonra başka bir koşul eklediğimizde, örneğin gelecekteki bir tarihe sahip makalelerin gösterilmemesi gerektiğini, kodu yalnızca tek bir yerde düzenleriz.

Fonksiyonu örneğin PostFacade sınıfına yerleştireceğiz ve getPublicArticles() olarak adlandıracağız.

app/Model/ dizininde, makalelerimizle ilgilenecek olan model sınıfımız PostFacade'i oluşturacağız:

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

Sınıfta, yapıcı aracılığıyla veritabanı Explorer'ı aktarmasını isteyeceğiz. Böylece DI konteynerinin gücünden yararlanacağız.

HomePresenter'a geçeceğiz, onu Nette\Database\Explorer bağımlılığından kurtulacak ve yeni sınıfımıza olan yeni bağımlılıkla değiştirecek şekilde düzenleyeceğiz.

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

Use bölümünde App\Model\PostFacade var, bu yüzden PHP kodundaki yazımı PostFacade olarak kısaltabiliriz. Bu nesneyi yapıcıda isteyeceğiz, $facade özelliğine yazacağız ve renderDefault metodunda kullanacağız.

Geriye kalan son adım, DI konteynerine bu nesneyi nasıl üreteceğini öğretmektir. Bu genellikle config/services.neon dosyasındaki services bölümüne bir madde işareti ekleyerek, sınıfın tam adını ve yapıcı parametrelerini belirterek yapılır. Böylece onu kaydederiz ve nesne daha sonra servis olarak adlandırılır. Autowiring adlı sihir sayesinde, çoğu zaman yapıcı parametrelerini belirtmemiz gerekmez, çünkü DI onları kendi başına tanır ve aktarır. Bu nedenle yalnızca sınıfın adını belirtmek yeterli olacaktır:

...

services:
	- App\Model\PostFacade

Ancak, bu satırı eklemeniz bile gerekmez. services.neon başındaki search bölümünde, -Facade veya -Factory ile biten tüm sınıfların DI tarafından kendi kendine bulunacağı tanımlanmıştır, bu da PostFacade durumu için geçerlidir.

Özet

PostFacade sınıfı, yapıcıda Nette\Database\Explorer'ın aktarılmasını ister ve bu sınıf DI konteynerinde kayıtlı olduğundan, konteyner bu örneği oluşturur ve aktarır. DI bizim için PostFacade örneğini bu şekilde oluşturur ve onu isteyen HomePresenter sınıfının yapıcısına aktarır. Böyle bir matruşka. :) Herkes sadece ne istediğini söyler ve neyin nerede ve nasıl yaratıldığıyla ilgilenmez. Oluşturma işini DI konteyneri halleder.

Burada dependency injection ve yapılandırma hakkında daha fazla bilgi edinebilirsiniz.