Symfony: Yeniden kullanilabilir bundle gelistirmek

mehmet soylu
6 min readFeb 5, 2021

--

Bu yazi https://symfony.com/doc/current/bundles/best_practices.html adresinin kisitli ve birebir olmayan cevirisidir. Kendim ogrenmek icin yazdigim ve cevirdigim icin orijinal kaynagi takip etmeniz veya daha tecrubeli insanlari cevirileri varsa okumaniz sizin acinizdan daha iyi olabilir.

Bu yazida yeniden kulanilabilir bundlelerin ayarlarina ve genisletilmesine deginilecek. Yeniden kullanılabilir paketler, birçok şirket projesinde özel olarak veya herhangi bir Symfony projesinin bunları yükleyebilmesi için herkese açık olarak paylaşılması amaçlanan paketlerdir.

Bundle Adi

Bir bundle ayni zamanda bir namespace demektir. Namespace ve icerdigi classlar PSR-4 standardi ile calismak icin uyumlu olmalidir. Bir vendor ismi ile baslar ve devaminda varsa kategori adi yoksa namespace icin kisabir ad kullaniyor.

Bir namespace ona bir paket sinifi ekledigimiz zaman bundle haline gelir. Bundle ismi su kurallara uymalidir;

  • Sadece alfanumerik karakterler ve alt cizgi kullanabilir
  • Bas harfi buyuk harfla baslayarak camelCase seklinde isimlendirme
  • En fazla iki kelime ile aciklayici ve kisa bir ad
  • Vendor ( uretici , satici ) adinin once kullanilmasi
  • Bundle kelimesi ile eklenmis son isim

Bazi bundle ve namespace adi ornekleri

Acme\Bundle\BlogBundle = AcmeBlogBundle

Acme\BlogBundle = AcmeBlogBundle

getName() methodu kural olarak bundle sinifina ekleniyor ve bundle adini donderiyor.

Eger yazdiginiz bundle herkesle paylasmak icin ise mutlaka bundle class vendor adi ile baslamali. Yani AcmeBlogBundle gibi fakat BlogBundle gibi degil!

Symfony cekirdek bundle class ise her zaman Symfony kelimesini kullanmiyor. Fakat her zaman bir bundle alt namespace kullaniyor. Mesela Symfony\Bundle\FrameworkBundle\FrameworkBundle gibi.

Her bundle bir aliasa (takma isme ) sahiptir. Tamami kucuk harf ve alt cizgi kullanilan bir takma isimdir bu. AcmeBlogBundle icin acme_blog isminin kullanilmasi gibi. Bu takma isim bundle isimlerinin benzersiz olmasini saglamak ve ayarlarda kullanilmak ( yaml config dosyalari ) icin vardir.

Dizin yapisi

Temel dizin yapisi soyledir;

<sizin-bundle>/
├─ AcmeBlogBundle.php
├─ Controller/
├─ README.md
├─ LICENSE
├─ Resources/
│ ├─ config/
│ ├─ doc/
│ │ └─ index.rst
│ ├─ translations/
│ ├─ views/
│ └─ public/
└─ Tests/

Asagidaki dosyalar ise otomatik yapilarin calismasi icin zorunludur:

  • AcmeBlogBundle.php: Siradan bir dizini bir symfony paketi olarak tanimlayan class budur.
  • README.md: Bundle tanitimi, ayarlari ve kullanim orneklerini iceren ve github formatina uygun bir icerikle sunan dosyadir.;
  • LICENSE: Lisans dosyasidir ve cogunlukla paketler MIT lisansi ile yayinlanir. Siz yine istediginiz lisansi kullanabilirsiniz.
  • Resources/doc/index.rst: Dokumantasyon kok dosyasidir.

Bundle icinde en cok kullanilan class ve dosya adresleri kisa tutulmalidir. En cok iki dizin derinligine sahip olmalidir.

Bundle dizini sadece okunabilirdir. Gecici dosyalar cache ve log gibi ana dizinlerde tutulmalidir. Bundle repository altinda yer alacaksa araclar bundle dizininde dosyalar olusturabilirler.

Belirli konumlara sahip ve pek cok gelistirici tarafindan kullanilan class ve dosyalar; ( bazilari olmazsa olmaz bazilari teamulendir)

Classlar

Bundle dizin yapisi namespace hiyerarsisidir. Ornegin

Acme/BlogBundle/Controller/ContentController.php

adresindeki bir ContentController sinifi

Acme\BlogBundle\Controller\ContentController

seklinde bir sinif adina sahip olur.

Tum classlar symfony kod standardini takip etmelidir.

Commands, Helpers, Listeners ve Controller gibi bazi classlar facades ( cepheler ) olarak gorulmeli ve kisa tutulmalidir.

Event dispatcher ile baglanan siniflar sonunaListener eklenmelidir.

Exception classlari Exception alt dizininde yer almalidir.

Vendorlar

Bir bundle PHP kutuphanelerini icermemelidir. Bunun yerine symfony’nin bunlarin autoload (yukleyecegini) edecegini varsaymalidir.

JavaScript ve CSS icinde Twitter Bootstrap gibi ucuncu parti kutuphaneleri icermemelidir.

Testler

Bir bundle PHPUnit icin yazilmis testlerle olusturulmali ve bunlari Tests dizininde tutmalidir. Testler su prensiplere uymalidir;

  • Ornek bir uygulamada testler basit bir phpunit komutu ile kullanilabilmelidir
  • Functional testler yalnizca cevap ciktilarini kontrol etmek ve bazi profil uyarilari icin kullanilmalidir
  • Kodlarin en az 95% testler ile denenebilir olmalidir.

Not

Bir takim testAllTests.php scriptinden olusmamali fakat phpunit.xml.dist dosyasi icinde yer almalidir.

Continuous Integration

Her commit ve pull request icin CI (surekli entegrasyon)kullanilmalidir. Bu en iyi yoldur. Bunun icin Travis ve Github Actions gibi pek cok servis vardir.

Bir bundle icinde sunlar test edilebilmelidir:

  • Bağımlılıklarının alt sınırı ( composer update --prefer-lowest ile );
  • Desteklenen PHP versiyonlari;
  • Desteklenen major Symfony surumleri

Boylece PHP ve Symfony surumleri soyle bir destek listesi olusturulabilir

Testler, SYMFONY_DEPRECATIONS_HELPER env değişkeni max[direct]=0 olarak ayarlanarak çalıştırılmalıdır. Bu, bundledaki hiçbir kodun, deprecated özellikleri doğrudan kullanmamasını sağlar. En düşük bağımlılık testleri, bu değişken disabled=1olarak ayarlanarak çalıştırılabilir.

Belirli bir Symfony Versiyonunun Sart Kilinmasi

You can use the special SYMFONY_REQUIRE environment variable together with Symfony Flex to install a specific Symfony version:

# Tum symfony paketleri icin symfony 5.* gerektirir
export SYMFONY_REQUIRE=5.*

# CI ortami icin symfony flex kurulmasi
composer global require --no-progress --no-scripts --no-plugins symfony/flex

# bagimliliklarin yuklenmesi ( --prefer-dist and --no-progress kullanilmasi tavsiye edilir )
composer update --prefer-dist --no-progress

Burada composer icin cache kullanilacaksa vendor/ dizini altinda bu yapilmamali, farkli bir temp dizin yazilmalidir.

Kurulum

Bundlelar composer.json dosyasında “type”: “symfony-bundle” ayarlamalıdır. Bununla, Symfony Flex, yüklendiğinde paketinizi otomatik olarak etkinleştirebilecektir.

Paketiniz herhangi bir kurulum gerektiriyorsa (ör. Yapılandırma, yeni dosyalar, .gitignore’da değişiklikler vb.), Bir Symfony Flex recipe oluşturmalısınız.

Dokumantasyon

Tum classlar PHPDoc standardinda olmalidir.

Kapsamli dokumanlarResources/doc/ dizininde yer almalidir. Kok dosya yani index (mesela Resources/doc/index.rst ya da Resources/doc/index.md) tek zorunlu dosyadir. reStructuredText (rST) Symfony websitesindeki dokumantasyonu temsilen kullanilir.

Kurulum talimatlari

Üçüncü taraf paketlerin kurulumunu kolaylaştırmak için, README.md dosyanızda aşağıdaki standartlaştırılmış talimatları kullanmayı düşünün.

Installation
============

Make sure Composer is installed globally, as explained in the
[installation chapter](https://getcomposer.org/doc/00-intro.md)
of the Composer documentation.

Applications that use Symfony Flex
----------------------------------

Open a command console, enter your project directory and execute:

```console
$ composer require <package-name>
```

Applications that don't use Symfony Flex
----------------------------------------

### Step 1: Download the Bundle

Open a command console, enter your project directory and execute the
following command to download the latest stable version of this bundle:

```console
$ composer require <package-name>
```

### Step 2: Enable the Bundle

Then, enable the bundle by adding it to the list of registered bundles
in the `config/bundles.php` file of your project:

```php
// config/bundles.php

return [
// ...
<vendor>\<bundle-name>\<bundle-long-name>::class => ['all' => true],
];
```

Son kararli surum kurulumu;

composer require friendsofsymfony/user-bundle ).

Spesifik olarak bir surum kurmak;

composer require friendsofsymfony/user-bundle “~2.0@dev”

Routing

Bundle route adresleri paket takma adi ile baslar. Mesela, AcmeBlogBundle icin acme_blog_ ile baslayan route adi gibi.

Temalar

Bundle bir tema parcasi iceriyorsa bu Twig olmalidir. Tam bir uygulama saglamayan bir paket layout icermemelidir.

Ceviri Dosyalari

Bir bundle cevirileri XLIFF formatinda tanimlanmalidir. (acme_blog).Bu ceviriler diger bundle cevirileri ile karismamalidir.

Ayarlar

Daha cok esneklik saglamak icin bir bundle Symfony mekanizmalarini kullanarak ayarlarlanabilir

Basit ayarlar icin Symfony ayarlari icinde `parameters` kismina guvenilebilir.

Symfony parametreleri basit anahtar/deger ciftlarina sahiptir. Tipki PHP degiskenleri gibi. Her parametre degisken adi bundle takma ismi ile baslamalidir. Bu bir sart degil oneridir, genel olarak uyulmalidir. Takma adi ( alias ) acme_blog ise author epostasi soyle belirtilebilir.

acme_blog.author.email

Bundle kullanici su sekilde ayar yapabilir;

# config/services.yaml
parameters:
acme_blog.author.email: 'fabien@example.com'

Parametreler kod icinde boyle cagrilabilir;

$container->getParameter('acme_blog.author.email');

Detaylari ve daha iyi ayarlar icin https://symfony.com/doc/current/bundles/configuration.html adresine bakabilirsiniz.

Versiyonlama

Pek cok bundle Semantic Versioning Standard kullanir.

Services

Bir bundle servislere sahipse bunlar projede tam class isimleri ile anilmalidir. Ornegin AcmeBlogBundle icin acem_blog takma isminin kullanilmasi gibi.

Bunun nedeni, bundlelarin, uygulama hizmetlerini derlerken bir ek yük getirmemesi için hizmet autowiring veya autoconfiguration gibi özelliklere güvenmemesidir.

Bunu disinda uygulama tarafindan kullanilmayacak servisler ozel sekilde tanimlanmalidir. Her kullaniciya acik servisler interface ve class bazli isimlendirilmelidir. Ornegin;

MonologBundle, bir alias Psr\Log\LoggerInterface interface ile olusturulacaksa logger seklinde isimlendirilmesiLoggerInterface interface kullandigina dair bir ipucu olur.

Servisler autowiring veya autoconfiguration kullanmamalidir. Bu islemler ozellikle ayar dosyalarinda belirtilerek yapilmalidir.

Detaylar https://symfony.com/doc/current/bundles/extension.html

Composer Metadata

Composer.json su metadatalari icermelidir;

nameverndor ve bundle adi. johnsmith/blog-bundle gibi.

descriptionBundle amaci hakkinda kisa bir bilgi.

typeBir bundle icin bu deger her zamansymfony-bundle oluyor.

license bir ya da dizi seklinde bir kac tane lisans. https://spdx.org/licenses/ adresinde lisans kisaltmalari mevcut.

autoloadBu bilgiler Symfony tarafından bundle sınıflarını yüklemek için kullanılır. PSR-4 standardi tavsiye edilir.

Kaynaklar

Eger bundle herhangi bir kaynak ile iliskilendirilecekse fiziksel dosya ve dizin adresleri yerine programsal adresleri kullanmalisiniz. ( __DIR__/config/services.xmlyerine @FooBundle/Resources/config/services.xml) gibi.

Bu sekilde herhangi bir bundle icin bundle ozelliklerini override ederken avantaj saglanir. detaylar icin https://symfony.com/doc/current/components/http_kernel.html#http-kernel-resource-locator

Sablonlarin yukaridaki gibi programsal adresleri yazilirken basitlestirilmis surumu kullandigina dikkat edin. Resources/views/Default/ icindeki index.html.twig cagrilacaksa twig icinde @Foo/Default/index.html.twig kullanmak gibi.

use the namespace as key, and the location of the bundle’s main class (relative to composer.json) as value. For example, if the main class is located in the bundle root directory: "autoload": { "psr-4": { "SomeVendor\\BlogBundle\\": "" } }. If the main class is located in the src/ directory of the bundle: "autoload": { "psr-4": { "SomeVendor\\BlogBundle\\": "src/" } }.

In order to make it easier for developers to find your bundle, register it on Packagist, the official repository for Composer packages.

--

--