melanjutkan tulisan saya sebelumnya tentang Translation di symfony 4, kali ini saya lanjutkan dengan translation di routing symfony. Contoh penggunaan translation di url adalah seperti url berikut :
versi bahasa inggris, https://phptherightway.com/pages/Design-Patterns.html
dan di versi bahasa indonesia, http://id.phptherightway.com/pages/Design-Patterns.html
nah kira kira kita akan belajar membuat translation di url.
Event
pertama kita buat folder baru bernama EventSubscriber di dalam folder src. Oh iya, bagi yang belum punya bahan untuk latihan kali ini, silahkan download di akun github saya di https://github.com/kematjaya0/tutorial atau silahkan baca ditulisan saya sebelumnya di https://catatan-pemrograman.blogspot.com/2018/10/menggunakan-translation-di-symfony-4.html.
Kemudian buat file baru bernama LocaleRewriteListener,php yang implements class EventSubscriberInterface.php. Seperti pada kode berikut :
<?php //src/EventSubscriber/LocaleRewriteListener.php
/**
* Description of LocaleRewriteListener
*
* @author NUR HIDAYAT
*/
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class LocaleRewriteListener implements EventSubscriberInterface{
/**
* @var Symfony\Component\Routing\RouterInterface
*/
private $router;
/**
* @var routeCollection \Symfony\Component\Routing\RouteCollection
*/
private $routeCollection;
/**
* @var string
*/
private $defaultLocale;
/**
* @var array
*/
private $supportedLocales;
/**
* @var string
*/
private $localeRouteParam;
public function __construct(RouterInterface $router, $defaultLocale = 'id', array $supportedLocales = array(), $localeRouteParam = '_locale')
{
$this->router = $router;
$this->routeCollection = $router->getRouteCollection();
$this->defaultLocale = $defaultLocale;
$this->supportedLocales = $supportedLocales;
$this->localeRouteParam = $localeRouteParam;
}
public function isLocaleSupported($locale)
{
return in_array($locale, $this->supportedLocales);
}
public function onKernelRequest(GetResponseEvent $event) // function yang wajib ada di setiap class yang implements dari interface EventSubscriberInterface
{
$request = $event->getRequest(); // mengambil object Request
$path = $request->getPathInfo(); // mengambil path / url dari request
$route_exists = false; //by default assume route does not exist.
// check dari routing yang tersedia, apakah url ada atau tidak
foreach($this->routeCollection as $routeObject){
$routePath = $routeObject->getPath();
if($routePath == "/{_locale}".$path){
$route_exists = true;
break;
}
}
// jika path routing ada
if($route_exists == true){
$locale = $request->getPreferredLanguage(); // ambil bahasa
if($locale=="" || $this->isLocaleSupported($locale)==false){
$locale = $request->getDefaultLocale();
}
// set url dengan disertai bahasa
$event->setResponse(new RedirectResponse($request->getSchemeAndHttpHost().$request->getBaseUrl()."/".$locale.$path));
}
}
public static function getSubscribedEvents() // override function untuk setting prioritas class yang dijalankan terlebih dahulu
{
return array(
KernelEvents::REQUEST => array(array('onKernelRequest', 19)),
);
}
}
class di atas adalah Event Dispatcher yang digunakan untuk meredirect url / mereplace url yg masuk yang apabila url request tidak disertai dengan bahasa / locale, maka akan ditambahkan dengan bahasa / locale default dari aplikasi. Untuk pembahasan Event Dispatcher bisa disimak pada tulisan saya lain kali. Setiap class yang implements interface EventSubscriberInterface.php harus mempunyai function onKernelRequest() yang akan dijalankan saat terjadi request ke aplikasi. Kemudian tambahkan / daftarkan file Event Dispatcher kita di config service.yml.
App\EventSubscriber\LocaleRewriteListener:
arguments: ["@router", "%kernel.default_locale%", "%locale_supported%"]
tags:
- { name: kernel.event_subscriber }
dan tambahkan kode berikut di bagian parameters sehingga menjadi seperti berikut:
parameters:
locale: 'en'
app_locales: en|id
locale_supported: ['en','id']
sehingga file service.yml kita menjadi seperti berikut :
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: 'en'
app_locales: en|id
locale_supported: ['en','id']
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: false # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
App\EventSubscriber\LocaleRewriteListener:
arguments: ["@router", "%kernel.default_locale%", "%locale_supported%"]
tags:
- { name: kernel.event_subscriber }
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
kemudian buat lagi satu class bernama LocaleSubscriber.php di dalam folder src/EventSubscriber yang juga implement dari Interface Symfony\Component\EventDispatcher\EventSubscriberInterface.php seperti berikut:
<?php // src/EventSubscriber/LocaleSubscriber.php
/**
* Description of LocaleSubscriber
*
* @author NUR HIDAYAT
*/
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class LocaleSubscriber implements EventSubscriberInterface{
private $defaultLocale;
public function __construct($defaultLocale = 'id')
{
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
if ($locale = $request->attributes->get('_locale')) {
$request->getSession()->set('_locale', $locale);
}else{
$request->getSession()->set('_locale', $this->defaultLocale);
}
$request->setDefaultLocale($request->getSession()->get('_locale', $this->defaultLocale));
}
public static function getSubscribedEvents()
{
return array(
KernelEvents::REQUEST => array(array('onKernelRequest', 21)),
);
}
}
class diatas digunakan untuk menyimpan settingan bahasa yang diperoleh dari url dan disimpan ke session agar dapat digunakan ditempat lain seperti di Controller atau di template twig. Kemudian jangan lupa untuk menambahkannya di file services.yaml sehingga file config/services.yaml kita menjadi seperti berikut:
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: 'en'
app_locales: en|id
locale_supported: ['en','id']
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: false # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
App\EventSubscriber\LocaleSubscriber:
arguments: ['%kernel.default_locale%']
App\EventSubscriber\LocaleRewriteListener:
arguments: ["@router", "%kernel.default_locale%", "%locale_supported%"]
tags:
- { name: kernel.event_subscriber }
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
nah kemudian untuk memeriksa apakah file kita berhasil di load / dijalankan, buka folder project kita di cmd kemudian jalankan perintah berikut:
php bin/console debug:event-dispatcher kernel.request
maka kira-kira akan muncul seperti ini:
nah, jika class tadi muncul di daftar tersebut seperti gambar di atas, maka kita berhasil menambahkannya sebagai event di symfony.
Routing
Sampai disini, kita sudah berhasil menambahkan Event di project symfony kita kemudian kita lanjutkan untuk konfigurasi routing. Kita buka file config/routes/annotations.yaml sehingga menjadi seperti berikut :
controllers:
resource: ../../src/Controller/
type: annotation
prefix: /{_locale}
requirements:
_locale: '%app_locales%'
defaults:
_locale: '%locale%'
ini untuk memaksa pengguna / user untuk memasukkan kode negara di url. Untuk memeriksa daftar routing, jalankan perintah ini di CMD :
nah pada gambar di atas terlihat bahwa routing kita menjadi /{_locale}/ yang berarti user harus menyertakan kode negara untuk mengakses halaman web. Sekarang kita coba akses menggunakan POSTMAN:
sehingga pesan yang keluar adalah bahasa inggris, sekarang kita coba POST data menggunakan url dengan kode id :
sehingga pesan yang keluar adalah bahasa indonesia seperti pada gambar berikut:
sekian dulu tulisan saya kali ini, semoga bermanfaat, dan lain kesempatan saya akan coba tulis tentang Service. Terima kasih
Catatan : Sorce Code Latihan dapat di unduh di github saya di https://github.com/kematjaya0/tutorial
pada contoh di atas, saya mencoba melakukan insert data dengan url disertai kode negara inggris :
http://localhost:8000/en/api/test/insert
sehingga pesan yang keluar adalah bahasa inggris, sekarang kita coba POST data menggunakan url dengan kode id :
http://localhost:8000/id/api/test/insert
sehingga pesan yang keluar adalah bahasa indonesia seperti pada gambar berikut:
sekian dulu tulisan saya kali ini, semoga bermanfaat, dan lain kesempatan saya akan coba tulis tentang Service. Terima kasih
Catatan : Sorce Code Latihan dapat di unduh di github saya di https://github.com/kematjaya0/tutorial
0 Komentar