Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect language and redirect to subdomain on Symfony

I'm using Symfony 1.2.7. My web is in several languages, each of one is in a subdomain like en.example.com, es.example.com. If the user enters into example.com, I want to redirect him to his language. I also want to have support staging.example.com and redirect to es.staging.example.com and en.staging.example.com so I can test everything before the deployment.

I have the following code that works both on index.php and frontend_dev.php. My question is, can you improve it? is there a better or cleaner way? Thanks!

require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');

$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'dev', true);
$context = sfContext::createInstance($configuration);

// get the domain parts as an array
$host = array_reverse(explode('.', $_SERVER['HTTP_HOST']));
list($tld, $domain, $subdomain) = $host;

// determine which subdomain we're looking at
$app = ($subdomain == 'staging') ? $subdomain2=$host[3] : $subdomain;

if(empty($app) || $app == 'www')
{
  $browser_languages = $context->getRequest()->getLanguages();

  foreach($browser_languages as $language)
  {
    $allowed_culture = in_array($language, sfConfig::get('app_languagesAvailable'));
    if($allowed_culture)
    {
      $domain = $subdomain ? $subdomain.'.'.$domain : $domain;
      $url = 'http://'.str_replace($domain.'.'.$tld, $language.'.'.$domain.'.'.$tld, $_SERVER['HTTP_HOST']).$_SERVER['REQUEST_URI'];

      $context->getController()->redirect($url);
      break;
    }
  }
}

$context->dispatch();

Update Solution: Custom filter

<?php

class subdomainFilter extends sfFilter
{
    public function execute($filterChain)
    {
        $context = $this->getContext();
        $user = $this->getContext()->getUser();
        $request = $this->getContext()->getRequest();

        // get the domain parts as an array
        $host = array_reverse(explode('.', $request->getHost()));
        list($tld, $domain) = $host;
        $subdomain2 = $host[3];
        $subdomain = $host[2];

        // determine which subdomain we're looking at
        $app = ($host[2] == 'staging') ? $subdomain2 : $subdomain;

        if(empty($app) || $app == 'www')
        {
          // if first time
          if ($this->isFirstCall())
          {
            $browser_languages = $request->getLanguages();
            // set default lang, for API as CURL doesn't set the language
            $lang = sfConfig::get('app_default_culture');

            foreach($browser_languages as $language)
            {
              $allowed_culture = in_array($language, sfConfig::get('app_languagesAvailable'));
              if($allowed_culture)
              {
                $lang = $language;
                break;
              }
            }
          }else {
            // Get user culture
            $lang = $user->getCulture();
          }

          $domain = $subdomain ? $subdomain.'.'.$domain : $domain;
          $url = str_replace($domain.'.'.$tld, $lang.'.'.$domain.'.'.$tld, $request->getURI());
          $context->getController()->redirect($url);
        }

        $filterChain->execute();
    }
}
like image 715
fesja Avatar asked Nov 14 '22 09:11

fesja


1 Answers

Using Symfony's routing system is the proper solution for these kind of issues.

Take a look at http://www.symfony-project.org/jobeet/1_2/Doctrine/en/05 for general routing info and at http://www.symfony-project.org/blog/2009/03/02/call-the-expert-adding-subdomain-requirements-to-routing-yml for advanced routing issues.

Note: I strongly suggest updating to sf 1.4 because 1.2 isn't maintained anymore. (http://www.symfony-project.org/tutorial/1_4/en/upgrade)

like image 179
Treur Avatar answered Jan 21 '23 10:01

Treur