İki domain, bir Laravel kurulumu – Part 2


Serinin birinci parçasında Laravel’in dilini domaine göre nasıl ayarlayabileceğimizden bahsetmiştim. Bu yazıda da biraz veritabanı tasarımından ve uygulamada kullanılan CSS, JavaScript dosyaları ve görseller gibi assetlerin tek klasörden alınmasından bahsetmek istiyorum.

2. Veritabanı tasarımı

Veritabanı tasarımı üzerinde çok fazla konuşulabilecek bir konu değil açıkçası. Ekstra olarak yapılması gereken tek şey tablolarınızdaki çeviri gerektirecek kolonlara suffixler eklemek. Örneğin posts tablonuzda yazıların kısa açıklamasını ve içeriğini tuttuğunuz alanların isimleri excerpt ve content olsun. Bu alanların sonuna _tr ve _en ekleri getireceğiz. Yani kolonların yeni adları excerpt_tr, excerpt_en ve content_tr, content_en olacak. Burada önemli olan suffixler ile bir önceki yazıda oluşturduğumuz Domain objesinin lang() metodundan dönen değerlerin eşleşmesi.

Bunları yaptıktan sonra Post objesinin içerisine getterlar ekleyerek sitenin diline göre içeriği alabiliriz:

public function getExcerpt() {
    return $this->{'excerpt_' . DomainFacade::lang()};
}

public function getContent() {
    return $this->{'content_' . DomainFacade::lang()};
}

3. Domainleri tek Laravel kurulumundan yönetmek ve assetleri tek klasörden almak

Şu an farklı dillerde açabildiğimiz bir Laravel uygulamamız ve bu işe uygun bir veritabanımız var. Peki iki domaini de bu Laravel kurulumundan nasıl yönetebiliriz?

Laravel kurulumunun olduğu dosya ve domainlerin bulunduğu klasörler aşağıdaki gibi olsun:

.main-laravel
    .laravel
        .app
        .bootstrap
        .diğer laravel dosyaları
.public_html
    .domain1.com (ana domain)
        .index.php
        .diğer dosyalar
    .domain2.com
        .index.php

Bu yapıya göre iki domain de subdomain olarak eklenmiş durumda. Eğer ana domaini subdomain olarak eklemek istemiyorsanız uygulamanızın public klasöründeki tüm dosyaları doğrudan public_html içerisine atabilirsiniz. Biz yukarıdaki yapıyı baz alarak ilerleyeceğiz. İlk olarak Laravel kurulumunu yapacağımız dosyayı public_html klasörünün dışında bir yere taşıyoruz. Bu durumda bu klasör main-laravel/laravel klasörü. public_html içerisinde ise 2 adet subdomain klasörümüz var. Bu domainlerden bir tanesini ana domain olarak belirliyoruz ve uygulamanın public klasöründe bulunan tüm dosyaları bu klasörün içerisine atıyoruz. domain2.com klasöründe ise sadece index.php dosyası olacak. Bu aşamadan sonra yapılması gereken tek şey iki domain için de index.php dosyalarının içeriğini doğru ayarlamak.

Öncelikle domain1.com içerisindeki index.php’den başlayalım.

<?php
// domain1.com/index.php
require __DIR__.'/../../main-laravel/laravel/bootstrap/autoload.php';

$app = require_once __DIR__.'/../../main-laravel/laravel/bootstrap/app.php';
$app->bind('path.public', function() {
    return __DIR__;
});

// Aşağıda bir değişiklik yok.

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);

Burada yapmamız gereken Laravel’in bulunduğu klasördeki autoload.php‘yi require etmek ve $app değişkenini de yine aynı klasörde bulunan bootstrap/app.php olarak belirlemek. Son olarak da uygulamada public_path() fonksiyonunu çağırdığımızda domain1.com klasörünün yolunu almak için path.public değerini index.php‘nin şimdi bulunduğu yer olarak ayarlıyoruz, yani __DIR__.

domain1.com’un kurulum işlemini bitirmiş bulunuyoruz. Şimdi de domain2.com‘a bakalım. domain2.com klasörü içerisinde sadece index.php olacak demiştik. Çünkü assetleri domain1.com’dan almak istiyoruz. Ayrıca siteye dosya upload edildiğinde yine domain1.com içerisine upload edilsin istiyoruz. Bunları yapabilmek için domain2.com‘un içerisindeki index.php dosyamız da şu şekilde olmalı:

<?php
// domain2.com/index.php
require __DIR__.'/../../main-laravel/laravel/bootstrap/autoload.php';

$app = require_once __DIR__.'/../../main-laravel/laravel/bootstrap/app.php';
$app->bind('path.public', function() {
	return __DIR__ . '/../domain1.com';
});

use Illuminate\Container\Container;
function asset($path, $secure = null) {
    return Container::getInstance()->make('url')->asset('http://www.domain1.com/' . $path, $secure);
}

// Aşağıda bir değişiklik yok.

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);

Burada yine Laravel kurulumunun olduğu klasörden autoload.php‘yi require ediyoruz ve $app değişkenini de yine bootstrap/app.php olarak belirliyoruz. Buraya kadar domain1.com ile aynı. Şimdi yapacağımız işlem domain2.com’dan girilip public_path() fonksiyonunu çağrıldığında domain1.com klasörünün döndürülmesini sağlayacak. Görüldüğü gibi path.public değeri için şu an bulunduğumuz klasörden bir üst klasöre çıkıp domain1.com’u gösterdik.

Şimdi yapacağımız şey Laravel’in yardımcı fonksiyonlarından asset() fonksiyonunu override etmek olacak. Böylece uygulamada kullandığınız tüm asset() fonksiyonlarını tek tek değiştirmeniz gerekmeyecek. Yukarıdaki kodda da göreceğiniz gibi asset($path) ile bir asset yüklemek istediğimiz zaman artık doğrudan domain1.com üzerinden yüklenecek.

Şimdi dikkat etmeniz gereken en önemli şey dosyaları upload ederken de domain1.com içerisine upload etmek. Bunu nasıl yapacağız peki? Upload edilen dosyaları taşıyacağınız pathi gösterirken her zaman public_path() değerini prefix olarak kullanın. Tek yapmanız gereken bu. Artık dosyalarınız domain1.com klasörünün içerisine kaydedilecek ve oradan çekilecek.

Ayarlamanız gereken son şey de .htaccess ile ilgili. domain2.com açıldığında assetleri domain1.com’dan aldığımız için, domain1.com’un .htaccess dosyasında domain2.com’un assetleri kullanabilmesi için izin vermemiz gerekiyor. Bunu da şu şekilde yapabilirsiniz:

<IfModule mod_headers.c>
    SetEnvIf Origin "http(s)?://(www\.)?(domain2.com)$" AccessControlAllowOrigin=$0$1
    Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    Header set Access-Control-Allow-Credentials true
	Header add Access-Control-Allow-Methods: "POST,OPTIONS,DELETE,PUT"
</IfModule>

Böylece tamamlamış olduk 🙂 Artık istediğiniz kadar domaini bir Laravel kurulumundan hiçbir şeyi tekrar etmeyerek yönetebilirsiniz.


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

Bir yanıt yazın

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