İki domain, bir Laravel kurulumu – Part 1


İki domain, veya daha fazla, tek Laravel kurulumu ile yönetilebilir mi? Cevap evet. Bu yazıda henüz bitirdiğim bir projede karşılaştığım sorunlardan ve bu sorunlara nasıl çözüm getirdiğimden bahsedeceğim. Proje temel olarak 2 adet domainin tek bir admin panelden yönetilmesi üzerine kurulu. Olması gereken şey siteye bir domainden girildiğinde sitenin Türkçe, diğer domain kullanılarak girildiğinde İngilizce olması. Aynı zamanda tüm görsellerin, JavaScript ve CSS dosyalarının, kısaca assetlerin diyelim, sadece bir yerden alınması ve bir yere yüklenmesi gerekiyor. Özetlemek gerekirse: 2 domain, bir admin paneli, bir veritabanı, ve bir public klasörü. Kısacası temel amaç hiçbir şeyin 2 kez yapılmaması (DRY).

1. Domaine göre site dilini belirlemek

İlk aşama domainlere göre dilleri değiştirmek. Bunu yapmak için Domain adında bir sınıf oluşturacağız. Bu sınıfın içerisinde çok fazla metod yok. Bu sınıfın yapacağı iş kendisine söylenen domaine göre sitenin dilini değiştirmek. Buna tarihler de dahil. Örnek bir Domain sınıfı şu şekilde olabilir:

<?php

namespace App;

use Illuminate\Container\Container;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;

class Domain {
    protected $domain;

    public function __construct($domain) {
        $this->domain = $domain;
        self::setLocale($domain);
    }

    public function domain() {
        return $this->domain;
    }

    public function lang() {
        return Config::get('app.locale');
    }

    public function dateLocale() {
        switch (strtolower($this->lang())) {
            case 'tr':
                return ['tr_TR.UTF-8', 'tr_TR', 'tr', 'turkish'];
            case 'en':
                return 'en-US';
            default:
                return 'en-US';
        }
    }

    public static function setLocale($domain) {
        // Set the language according to the domain
        switch($domain) {
            case 'localhost':
                App::setLocale('tr');
                break;
            case 'www.domain1.com':
            case 'domain1.com':
                App::setLocale('tr');
                break;
            case 'www.domain2.com':
            case 'domain2.com':
                App::setLocale('en');
                break;
            default:
                App::setLocale('en');
                break;
        }
    }
}

Gördüğünüz gibi yeni bir Domain instanceı oluşturduğumuzda bizden bir domain istiyor. Bu domaini magic field olarak kaydettikten sonra sitenin dilini belirtilen domaine göre setLocale metodunu çağırarak sitenin dilini belirliyor. Ayrıca localhosttan girildiğinde de, debug amaçlı olarak, dili belirleyebiliyor.

Elimizde sitenin dilini söylediğimiz domaine göre değiştirebilen bir sınıf var. Şimdi yapmamız gereken Laravel yüklendiğinde bir Domain instanceı oluşturmak. Bunu da service providerları kullanarak yapabiliriz. Service providerlar IoC (inversion of control) containera bir takım değişkenler ekleyebilmemizi sağlıyor. IoC container denilen şey aslında sadece bir array. İçerisinde bir çok değişken barındırıyor ve Laravel’in bel kemiği. Şimdi yapacağımız işlem ile bir Domain instanceını IoC containera ekleyeceğiz. Laravel yüklendiğinde default olarak gelen Providers\AppServiceProvider sınıfının içerisinde register metoduna gelin. Eğer metod yoksa oluşturabilirsiniz. Ekleyeceğimiz kod şu şekilde:

$this->app->singleton('domain', function($app) {
    return new \App\Domain($_SERVER['SERVER_NAME']);
});

Bu kod ne anlama geliyor? Bu kod IoC containera domain adında bir değişken ekliyor. IoC container bir array demiştik. Bu arraye domain anahtarını ve bu anahtarın değeri olarak da yeni bir Domain sınıfı instanceı eklemiş olduk. Koddaki singleton ifadesi “bu değişkeni sadece bir kere oluştur ve ben ne zaman domain istersem bana aynı instanceı ver” anlamına geliyor. Bir başka deyişle static değişken gibi. Callback fonksiyonu yeni bir Domain instanceı oluşturuyor. Domain instanceı oluştururken bizden istenen domaini de $_SERVER[‘SERVER_NAME’] ile alıyoruz. Şu an sitenin dilini domaine göre değiştirme kısmını tamamlamış bulunuyoruz.

Not: AppServiceProvider’ın config/app.php içerisinde providers arrayinde tanımlı olduğundan emin olun.

Bu bölümü bitirmeden son olarak yapmamızda fayda bulunan bir şey de az önce IoC containera eklediğimiz Domain instanceına istediğimiz zaman kolay bir şekilde ulaşabilmek için bir facade tanımlamak. Facadeı tanımlayabilmek için app klasörünüzün içerisine bir Facade klasörü oluşturun ve içerisine DomainFacade isminde bir sınıf ekleyin. Buna Domain de diyebilirsiniz fakat ben DomainFacade demeyi tercih ettim. DomainFacadeın içeriği şu şekilde:

<?php
namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class DomainFacade extends Facade {
    protected static function getFacadeAccessor() { return 'domain'; }
}

Burda tek yaptığımız şey az önce IoC containera eklediğimiz ‘domain’ anahtarını bir facade olarak tanımlamak. Bu daha sonra IoC containerdaki ‘domain’ anahtarının değerine DomainFacade:: şeklinde erişebilmemizi sağlayacak. Son olarak da config\app.php içerisindeki aliases arrayine facadeımızı ekliyoruz.

'DomainFacade' => App\Facades\DomainFacade::class,

Böylece artık uygulamanın herhangi bir yerinden, mesela uygulamanın diline ulaşmak istiyorsak, DomainFacade::lang() yazmamız yeterli. DomainFacade::domain() yazarak da şu anki domaini alabilirsiniz. Bu facadeın doğrudan IoC containerdaki Domain instanceı olduğunu unutmayın. Yani DomainFacade ile Domain sınıfındaki tüm metodlara ve değişkenlere erişebilirsiniz.

Devamını bir başka yazıda anlatacağım 🙂

İki domain, bir Laravel kurulumu – Part 2


“İki domain, bir Laravel kurulumu – Part 1” için bir yanıt

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir