views:

299

answers:

4

Hi all,

I'm trying to match subdomains to a customer id in symfony.

i.e. i have customer1.example.com and customer2.example.com

Domains are stored in a table.

When a user goes to customer1.example.com, I would like to get the subdomain, look up the domain name in the database, once matched, it will then deploy the app config for that customer and then store the customer_Id in a global attribute so i know exactly which customer I'm dealing with througout the whole application. The virtual host will have the relevant wildcard servername.

Have you managed to achieve this, and if so, how? If not, any ideas would be a great help!

I'm thinking about using a filter to do it.

:-)

A: 

Because you want to load different app, filter won't help. Just use the frontcontroller (index.php) to extract the subdomain, and if the app directory exists, load the app (else 404). You can even store the id in app configuration.

Marek
Hey Marek. I'm not deploying a different app, I just want to use the sudomain as a parameter variable.For example: Instead of having http://example.com/company1/admin, I want to have http://company1.example.com/adminSame app for every customer, but i'm using the subdomain to get the companies relevant data.I managed to succeed last night. I created a filter (domainMatchFilter.class.php).
Jamie
I grabbed the subdomain, did a search on the customer table to match the domain (domain field in the table has an index on it). Once found it set a config variable with the customer object from the result set. i.e. sfConfig::set("customer", $customer).If no customer is found it redirects to the homepage (example.com). Do you think it'd be better to redirect to a page which says this customer does not exist etc.?This filter is run on every page request which is a bit slow because it queries the database everytime, however, it's the only way I know how to do it.
Jamie
I want it to work like uservoice.com. You sign up, and you get your own domain, i.e. company1.uservoice.com etc. which is much nicer than uservoice.com/company1
Jamie
Ok, I misunderstood. The filter method is the right approach, and don't worry about the extra query. For usability, you should really say this customer does not exist.
Marek
A: 

I'm doing something similar. Note, I haven't tried this exact setup.

$tokens = explode('.', $_SERVER['SERVER_NAME'], 2);
$app = $tokens[0] == 'www' ? 'default' : $tokens[0]; //assumes you aren't allowing www.app.example.com, change if you are

try
{
  $appConfiguration = ProjectConfiguration::getApplicationConfiguration($app, 'prod', false);
}
catch(InvalidArgumentException $e) //thrown if app doesn't exist
{
  $fallbackConfiguration = ProjectConfiguration::getApplicationConfiguration('default', 'prod', false); 
  $context = sfContext::createInstance($fallbackConfiguration);
  $request = $context->getRequest();
  $request->setParameter('module', 'default'); //set what route you want an invalid app to go to here
  $request->setParameter('action', 'invalidApplication');
  $context->dispatch();
}
if (isset($appConfiguration))
{
  sfContext::createInstance($appConfiguration)->dispatch();
}
jeremy
A: 

Take a look at sfDomainRoutePlugin - it does what you want. However, in its current version you don't get the Propel or DoctrineRoute functionality, which means you must manually lookup the customer based on the subdomain parameter returned from the plugin. Example:

app/frontend/config/routing.yml

# pick up the homepage
homepage:
  url:          /
  class:        sfDomainRoute
  param:        { module: homepage, action: index }
  requirements:
    sf_host:    [www.example.com, example.com]

# catch subdomains for customers
customer_subdomain:
  url:          /
  class:        sfDomainRoute
  param:        { module: customer, action: index }

app/frontend/modules/customer/actions.class.php

public function executeIndex(sfWebRequest $request)
{ 
  // get the subdomain parameter
  $this->subdomain = $request->getParameter('subdomain');
  // retrieve customer (you have to create the retrieveBySubdomain method)
  $this->customer = CustomerPeer::retrieveBySubdomain($this->subdomain);
}

This is just an example, but I use a similar approach myself, and the plugin does what is advertised. Good luck.

If you're adventurous, yuo could take a look at Chapter 2 in the "More with symfony book". This would help you understand the code in sfDomainRoutePlugin.

cvaldemar
A: 

also going to be needing yo set your domain as a wildcard domain, if not you going to need to create manually each subdomain per client.

another solution that is not so symphony dependent is using a .htaccess

    <IfModule mod_rewrite.c>
   Options +FollowSymLinks
   Options +Indexes
   RewriteEngine On
   RewriteBase /
   RewriteCond %{HTTP_HOST} !www.domain.com$ [NC]
   RewriteCond %{HTTP_HOST} ^(www.)?([a-z0-9-]+).domain.com [NC]
   RewriteRule (.*) $1?sub=%2&page=$1&domain=%{HTTP_HOST} [QSA,L]
<IfModule>

that code basically will send to the requested page the subdomain, the domain and the page requested. then in php you can check if it is equal to your client username. and allow you also to use parked domains for your clients at the same time.

i hope it helps.

shadow_of__soul