Model

Uygulamamız büyüdükçe, kısa süre içinde benzer veritabanı işlemlerini çeşitli konumlarda ve çeşitli sunucularda gerçekleştirmemiz gerektiğini fark ederiz, örneğin yayınlanan en yeni makaleleri almak gibi. Devam eden bir çalışma durumunu belirtmek için makalelere bir bayrak ekleyerek uygulamamızı geliştirirsek, uygulamamızdaki tüm konumları gözden geçirmeli ve yalnızca bitmiş makalelerin seçildiğinden emin olmak için bir where cümlesi eklemeliyiz.

Bu noktada, doğrudan veritabanı ile çalışmak yetersiz kalır ve yayınlanan makaleleri döndüren yeni bir fonksiyonla kendimize yardımcı olmak daha akıllıca olacaktır. Ve daha sonra başka bir cümle eklediğimizde (örneğin ileri tarihli makaleleri görüntülememek için), kodumuzu yalnızca bir yerde düzenleriz.

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

Makalelerimizle ilgilenmek için app/Model/ dizininde PostFacade model sınıfımızı 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 veritabanı Explorer'ını geçiyoruz. Bu, DI konteynerinin gücünden yararlanacaktır.

Düzenleyeceğimiz HomePresenter adresine geçeceğiz, böylece Nette\Database\Explorer bağımlılığından kurtulacağız ve bunun yerine yeni sınıfımıza yeni bir bağımlılık oluşturacağız.

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

Kullanım bölümünde App\Model\PostFacade kullanıyoruz, bu nedenle PHP kodunu PostFacade olarak kısaltabiliriz. Bu nesneyi kurucuda talep ediyoruz, $facade özelliğine yazıyoruz ve renderDefault yönteminde kullanıyoruz.

Geriye kalan son adım DI konteynerine bu nesneyi üretmeyi öğretmektir. Bu genellikle services bölümündeki config/services.neon dosyasına tam sınıf adını ve kurucu parametrelerini veren bir madde işareti eklenerek yapılır. Bu, tabiri caizse onu kaydeder ve nesne daha sonra service olarak adlandırılır. Otomatik bağlantı adı verilen bazı sihirler sayesinde, genellikle kurucu parametrelerini belirtmemize gerek yoktur çünkü DI bunları tanıyacak ve otomatik olarak aktaracaktır. Bu nedenle, sadece sınıfın adını vermek yeterli olacaktır:

...

services:
	- App\Model\PostFacade

Ancak, bu satırı eklemenize de gerek yoktur. services.neon adresinin başındaki search bölümünde, -Facade veya -Factory ile biten tüm sınıfların DI tarafından otomatik olarak aranacağı tanımlanmıştır, bu durum PostFacade için de geçerlidir.

Özet

PostFacade sınıfı bir kurucuda Nette\Database\Explorer sınıfını ister ve bu sınıf DI konteynerinde kayıtlı olduğu için konteyner bu örneği oluşturur ve geçirir. DI bu şekilde bizim için bir PostFacade örneği yaratır ve bir kurucu içinde bunu isteyen HomePresenter sınıfına geçirir. Bir çeşit Matruşka bebeği kodu :) Tüm bileşenler sadece ihtiyaç duydukları şeyi talep ederler ve nerede ve nasıl oluşturulduğuyla ilgilenmezler. Oluşturma DI container tarafından gerçekleştirilir.

Burada bağımlılık enjeksiyonu ve yapılandırma hakkında daha fazla bilgi edinebilirsiniz.