Symfony dynamic subdomains - php

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.
:-)

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.

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.

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.

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();
}

Related

How to point a domain to a WordPress page?

I have a WordPress page with this structure http://mywebsite.com/page
I want my http://otherdomain.com to point to http://mywebsite.com/page but the user should see the http://otherdomain.com domain at his browser? The A record in my DNS points http://otherdomain.com and http://mywebsite.com to the same IP.
How to achieve this goal? I though about VirtualHosts but since the folder /page doesn't really exist in the server but is created dynamically by WordPress via .htaccess
How can I point my domain to the WordPress page?
After Roel answer I edited my htaccess.conf file at the WordPress Bitnami installation to add this:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^otherdomain\.com.br$
RewriteRule (.*) http://www.otherdomain.com.br/$1 [R=301,L]
RewriteRule ^$ http://mywebsite.com.br/page/ [L,R=301]
The code is being called, because it adds the www to the main URL, but it's not working, because it displays contents from mywebsite.com.br and not from mywebsite.com.br/page.
I tried another code which is
RewriteEngine on
RewriteCond %{HTTP_HOST} otherdomain\.com.br [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ http://mywebsite.com.br/page/$1 [L]
In this case, it display the contents from http://mywebsite.com.br/pagehowever it changes my URL http://mywebsite.com.br/page as well which is not what I'm looking for, since I want to keep the user's browser at http://otherdomain.com.br
All SEO and duplicate content issues aside:
WordPress is aware of the domain it is supposed to be answering to in the database. The WordPress site itself will also redirect based on the domain name set in the WordPress dashboard (under "Settings" => "General").
This isn't going to work well using htaccess. You're actually going to want the domain name http://otherdomain.com to point to the server where mywebsite.com lives (not using a forward, but modifying the A record in your DNS). The reason is that when you rewrite the domain name, the WordPress site is also going to look for css and js files at that domain (looking for them at otherdomain.com). If you have the domain pointed to the WordPress server, this will work properly.
In order to cause WordPress to allow "answering" to multiple domains, you need to modify the code in your WordPress installation so that it will not rewrite the url to http://mywebsite.com. To do this, add the below PHP code to your WordPress theme's function.php file:
What you need to do is to add filter(s) to the relevant hooks that return the site URL, so you can modify it as you see fit:
// This will allow you to modify the site url that is stored in the db when it is requested by WP
add_filter('option_siteurl', 'my_custom_filter_siteurl', 1);
// This will allow you to modify the home page url that is stored in the db when it is requested by WP
add_filter('option_home', 'my_custom_filter_home', 1);
// Modify the site url that WP gets from the database if appropriate
function my_custom_filter_siteurl( $url_from_settings ) {
// Call our function to find out if this is a legit domain or not
$current_domain = my_custom_is_domain_valid();
// If so, use it
if ( $current_domain ) {
return "http://{$current_domain}";
// Otherwise, use the default url from settings
} else {
return $url_from_settings;
}
}
// Modify the home page url that WP gets from the database if appropriate
function my_custom_filter_home( $home_from_settings ) {
// Call our function to find out if this is a legit domain or not
$current_domain = my_custom_is_domain_valid();
// If so, use it
if ( $current_domain ) {
$base_url = "http://{$current_domain}";
// Modify / remove this as appropriate. Could be simply return $base_url;
return $base_url . "/home-page";
// Otherwise, use the default url from settings
} else {
return $home_from_settings;
}
}
// Utility function to determine URL and whether valid or not
function my_custom_is_domain_valid() {
// Create a whitelist of valid domains you want to answer to
$valid = array(
'otherdomain.com',
'mywebsite.com.br',
);
// Get the current domain name
$current_server = $_SERVER['SERVER_NAME'];
// If it's a whitelisted domain, return the domain
if ( in_array( $current_server, $valid ) ) {
return $current_server;
}
// Otherwise return false so we can use the default set in the DB
return FALSE;
}
Adding the following filters and functions will cause the desired page to appear as the home page, without the /page in the URL:
// This will allow you to modify if a page should be shown on the home page
add_filter('option_show_on_front', 'my_custom_show_on_front');
// This will allow you to modify WHICH page should be shown on the home page
add_filter('option_page_on_front', 'my_custom_page_on_front');
// Modify if a page should be shown on the home page
function my_custom_show_on_front( $default_value ) {
// We only want to do this on specific domain
$is_other_domain = my_custom_is_other_domain();
// Ensure it's the domain we want to show the specific page for
if ( $is_other_domain ) {
return 'page';
// Otherwise, use the default setting
} else {
return $default_value;
}
}
// Modify WHICH should be shown on the home page
function my_custom_page_on_front( $default_value ) {
// We only want to do this on specific domain
$is_other_domain = my_custom_is_other_domain();
// Ensure it's the domain we want to show the specific page for
if ( $is_other_domain ) {
// If it's the proper domain, set a specific page to show
// Alter the number below to be the ID of the page you want to show
return 5;
} else {
// Otherwise, use the default setting
return $default_value;
}
}
// Utility function to easily determine if the current domain is the "other" domain
function my_custom_is_other_domain() {
$current_domain = my_custom_is_domain_valid();
return ($current_domain == 'otherdomain.com') ? $current_domain : FALSE;
}
You'll need to add rewrite rules.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^otherdomain\.com$
RewriteRule (.*) http://www.otherdomain.com/$1 [R=301,L]
RewriteRule ^$ http://mywebsite.com/page [L,R=301]
You shouldn't be redirecting the user to mywebsite.com with [L,R=301], rather, you should use the P flag which allows you to ask mod_rewrite to act as a proxy for the domain otherdomain.com. something like this,
RewriteRule /(.*) http://mywebsite.com/page/$1 [P]
make sure to change the css files too to the following,
RewriteRule /css/(.*) http://mywebsite.com/css/$1 [P]
which will allow all your otherwebsite.com css to become mywebsite.com css and display as otherwebsite.com/css rather than mywebsite.com/page/css
but in order to do this, you need to have mod_proxy loaded and enabled. Do however note that this will reduce performance compared to using mod_proxy directly, as it doesn't handle persistent connections or connection pooling.
Try this regex. It may not work, but it will give you some idea on where to find the solution.
Basically you need to use an external redirect from otherdomain to mywebsite and then an internal redirect from mywebsite to otherdomain. But it may cause a loop so you need to use some condition to escape it.
RewriteEngine on
RewriteCond %{ENV:REDIRECT_FINISH} !^$
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^otherdomain\.com.br$ [NC]
RewriteRule ^(.*)$ http://mywebsite.com.br/page/$1 [R,L]
RewriteRule ^.*$ http://otherdomain.com.br [E=FINISH:1]

How to create Wildcard sub-domains

I am using joomla 3.3, I have a site on which user can create their own store with domain name so how can I create sub domain by which user can access their sub domain.
Suppose if a user create abc.example.com then that user should be able to access abs.example.com
So how to do this.
i have added these lines to .htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.zzphonecase\.com(.*)$ /index.php/%2/%1
and these lines in index.php file of template
$host = explode ('.', $_SERVER ['HTTP_HOST']);
$subdomain = $host [0];
if((!strcasecmp ($subdomain, 'www')) || (!strcasecmp ($subdomain, 'zzphonecase')))
{
//main site enter code here
}
else
{
//enter code here
// subdomain
http_response_code (404);
echo 'Error 404 : your domain could not be found';
return false;
}
The problem is when and where you load the domain redirect. you're loading it at the template layer...way too late in the process. it has to be loaded before the joomla framework is loaded (top of root index.php. i use "virtual domains" for multisite domain management, and fabrik for custom forms & components extensively on my sites. you could create a form in fabrik that adds and entry & parameters to the virtual domain database table. little bit of a learning curve on how to execute it, but once you get it this will make it very simple for you. You can then setup your wildcard domain and point it to the site root and let the virtual domains component do all the work for you. Seriously...multisite management in joomla is a real pain. others have done the work for you!

Username as subdomain on laravel

I've set up a wildcard subdomain *.domain.com & i'm using the following .htaccess:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !www\.
RewriteCond %{HTTP_HOST} (.*)\.domain\.com
RewriteRule .* index.php?username=%1 [L]
Everything works perfectly.
I want to implement this method in laravel. Mainly I want to have my user's profile displayed when you go to username.domain.com. Any ideas on achieving this?
This is easy. Firstly - do NOT change the .htaccess file from the default provided by Laravel. By default all requests to your domain will be routed to your index.php file which is exactly what we want.
Then in your routes.php file just use a 'before' filter, which filters all requests to your application before anything else is done.
Route::filter('before', function()
{
// Check if we asked for a user
$server = explode('.', Request::server('HTTP_HOST'));
if (count($server) == 3)
{
// We have 3 parts of the domain - therefore a subdomain was requested
// i.e. user.domain.com
// Check if user is valid and has access - i.e. is logged in
if (Auth::user()->username === $server[0])
{
// User is logged in, and has access to this subdomain
// DO WHATEVER YOU WANT HERE WITH THE USER PROFILE
echo "your username is ".$server[0];
}
else
{
// Username is invalid, or user does not have access to this subdomain
// SHOW ERROR OR WHATEVER YOU WANT
echo "error - you do not have access to here";
}
}
else
{
// Only 2 parts of domain was requested - therefore no subdomain was requested
// i.e. domain.com
// Do nothing here - will just route normally - but you could put logic here if you want
}
});
edit: if you have a country extension (i.e. domain.com.au or domain.com.eu) then you will want to change the count($server) to check for 4, not 3
Laravel 4 has this functionality out of the box:
Route::group(array('domain' => '{account}.myapp.com'), function() {
Route::get('user/{id}', function($account, $id) {
// ...
});
});
Source
While I can't say what the full solution would be in your case, I would start with the SERVER_NAME value from the request (PHP: $_SERVER['SERVER_NAME']) such as:
$username = str_replace('.domain.com', '', Request::server('SERVER_NAME'));
Make sure you additionally clean/sanitize the username, and from there you can lookup the user from the username. Something like:
$user = User::where('username', '=', $username)->first();
Somewhere in the routes file you could conditionally define a route if the SERVER_NAME isn't www.domain.com, or domain.com, though I'm sure others can come up with a much more eloquent way for this part...
ability add subdomains like subdomain *. domain.com should be switched by your hosting provider, in the .htaccess you can not configure support of subdomains

Problem with redirecting and links using MVC in PHP

I try to go into MVC but come to a problem that is not explained anywhere, it is how to redirect from one to another controller.
I'm using the following .htaccess file:
RewriteEngine On
RewriteCond% {REQUEST_FILENAME}!-F
RewriteCond% {REQUEST_FILENAME}!-D
RewriteRule ^(.*)$ index.php? Url = $ 1 [L, QSA]
to use the controller directly after it put its methods and id th.
All this work accessing them in a standard way but when choosing a view to further pages ienata used directly as the controller.
<a href="next_page_controler"> NEXT_PAGE </ a>
and access the next controller, but when I want to access methods must use
<a href="next_page_controler/**controler_model**"> NEXT-pAGE_MODEL </ a>
and here we have two problems :
IN repeatedly link in address bar is displayed once again repeated as
www.site_pat/next_page_controler/next_page_controler/next_page_controler/next_page_controler/next_page_controler/controler_model
When you try to redirect as the method controler_model using header (Location: controler_name); nothing gets pulls no message or anything just want to try but the redirect does not work .
How to solve the problems I guess a lot of you have encountered these are basic things and I think that shouting at all began to work with framework should understand these basics.
Theres something wrong with your htaccess, should be something like...
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}!-F
RewriteCond %{REQUEST_FILENAME}!-D
RewriteRule ^(.*)$ index.php/$1 [L, QSA]
UPDATE:
#prodigitalson coud you give me an example
So a super simple example might look like the following code. Ive never actually written a router from sractch because im typically using a framework, so there are probably soem features youll need that this doesnt include... Routing is a fairly complex things depending on how resuable you want it to be. I would reommend looking at how a few different php frameworks do it for good examples.
// define routes as a regular expression to match
$routes = array(
'default' => array(
'url' => '#^/categories/(?P<category_slug>\w*(/.*)?$#',
'controller' => 'CategoryController'
)
)
);
// request - you should probably encapsulate this in a model
$request = array();
// loop through routes and see if we have a match
foreach($routes as $route){
// on the first match we assign variables to the request and then
// stop processing the routes
if(preg_match($route['url'], $_SERVER['REQUEST_URI'], $params)){
$request['controller'] = $route['controller'];
$request['params'] = $params;
$request['uri'] = $_SERVER['REQUEST_URI'];
break;
}
}
// check that we found a match
if(!empty($request)){
// dispatch the request to the proper controller
$controllerClass = $request['controller'];
$controller = new $controllerClass();
// because we used named subpatterns int he regex above we can access parameters
// inside the CategoryController::execute() with $request['params']['category_slug']
$response = $controller->execute($request);
} else {
// send 404
}
// in this example $controller->execute() returns the compiled HTML to render, but
// but in most systems ive used it returns a View object, or the name of the template to
// to be rendered - whatever happens here this is where you send your response
print $response;
exit(0);
You shouldnt be implementing your controller routing soley from .htaccess. You should simple have all request other than for static assets go to index.php. Then on the php side you firgure out where to dispatch the request based on the pattern of the url.

send each request to appropriate controller

I want to make a small web application, and I'm not sure how to go about this.
What I want to do is send every request to the right controller. Kind of how CodeIgniter does it.
So if user asks for domain.com/video/details
I want my bootstrap (index?) file to send him to the "Video" controller class and call the "details" method in that class.
If the user asks for domain.com/profile/edit I want to send him to the "Profile" controller class and call the "edit" method in that class.
Can someone explain how I should do this? I have some experience using MVC frameworks, but have never "written" something with MVC myself.
Thanks!
Edit: I understand now how the url points to the right Controller, but I don't see where the object instance of the Controller is made, to call the right method?
You need to re-route your requests. Using apache, this can be done using mod_rewrite.
For example, add a .htaccess file to your public base directory and add the following:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?rt=$1 [L,QSA]
This will redirect users trying to access
/profile/edit
to
index.php?rt=profile/edit
In index.php, you can access the $_GET['rt'] to determine which controller and action has been requested.
Use mod-rewrite (.htaccess) to
rewrite the url from
www.example.com/taco to
www.example.com/index.php?taco/
in index.php, grab the first URL
parameter key, use that to route to
the correct url. As it will look
like "taco/"
You may want to add / to the front
and back if it doesn't exist. As
this will normalize the urls and
make life easier
If you want to preserve the ability
to have traditional query strings.
Inspect the URL directly and take
the query string portion. break that
on ?, which will leave you with the
routing info in key 0 and the rest
in key 1. split that on &, then
split each of those on = and set the
first to the key and the second to
the value of an array. Replace $_GET
with that array.
Example:
$path = explode("?", $_SERVER["QUERY_STRING"],2);
$url = $path[0];
if(substr($url,0,1) != "/")
{
$url = "/".$url;
}
if(substr($url,-1,1) != "/")
{
$url = $url."/";
}
unset($_GET);
foreach(explode("&", $path[1]) as $pair)
{
$get = explode("=", $pair, 2);
$_GET[$get[0]] = $get[1];
}
// Define the Query String Path
define("QS_PATH", $url);
Depending on what you want to do or how much work you want to do, another option versus writing your own MVC is to use Zend Framework. It does exactly what you're asking for and more. You still need to configure URL rewriting as mentioned in the other answers, but it quick and easy.
Even if you're not interested in Zend Framework, the following link can help you configure your rewrite rules: http://framework.zend.com/wiki/display/ZFDEV/Configuring%2BYour%2BURL%2BRewriter

Categories