4. sfDoctrineRouteCollection
foobar GET /foobar.:sf_formatfoobar_new
GET /foobar/new.:sf_formatfoobar_create POST
/foobar.:sf_formatfoobar_edit GET
/foobar/:id/edit.:sf_formatfoobar_update PUT
/foobar/:id.:sf_formatfoobar_delete DELETE
/foobar/:id.:sf_formatfoobar_show GET
/foobar/:id.:sf_formatfoobar_object GET
/foobar/:id/:action.:sf_formatfoobar_collection POST
/foobar/:action/action.:sf_format
foobar GET /foobar.:sf_formatfoobar_new
GET /foobar/new.:sf_formatfoobar_create POST
/foobar.:sf_formatfoobar_edit GET
/foobar/:id/edit.:sf_formatfoobar_update PUT
/foobar/:id.:sf_formatfoobar_delete DELETE
/foobar/:id.:sf_formatfoobar_show GET
/foobar/:id.:sf_formatfoobar_object GET
/foobar/:id/:action.:sf_formatfoobar_collection POST
/foobar/:action/action.:sf_format
Try: $ ./symfony app:routes myapp
It’s RESTful!
6. •First Step: Overloading your classes
Setting a Default Route Class
# /apps/myapp/config/config_handlers.yml
config/routing.yml:
class: myRoutingConfigHandler
# /apps/myapp/config/config_handlers.yml
config/routing.yml:
class: myRoutingConfigHandler
•Configure which classes parse your YAML files
•Register your handler class in your project configuration
•Config files are parsed before classes are autoloaded
Question: How do you configure the config_handlers handler??
do this only if you’re very lazy
<?php
// /config/config.php
$configCache = sfProjectConfiguration::getActive()->getConfigCache();
$configCache->registerConfigHandler('config/routing.yml', 'myRoutingConfigHandler');
<?php
// /config/config.php
$configCache = sfProjectConfiguration::getActive()->getConfigCache();
$configCache->registerConfigHandler('config/routing.yml', 'myRoutingConfigHandler');
7. <?php
/**
* Sets default routing class
*/
class myRoutingConfigHandler extends sfRoutingConfigHandler
{
protected function parse($configFiles)
{
// ...
$routes[$name] = array(isset($params['class']) ? $params['class'] : $this-
>getDefaultRouteClass(), array(
$params['url'] ? $params['url'] : '/',
isset($params['params']) ? $params['params'] : (isset($params['param']) ?
$params['param'] : array()),
isset($params['requirements']) ? $params['requirements'] : array(),
isset($params['options']) ? $params['options'] : array(),
));
}
}
return $routes;
}
public function getDefaultRouteClass()
{
$default = sfConfig::get('app_routing_route_class');
return $default ? $default : 'sfRoute';
}
}
<?php
/**
* Sets default routing class
*/
class myRoutingConfigHandler extends sfRoutingConfigHandler
{
protected function parse($configFiles)
{
// ...
$routes[$name] = array(isset($params['class']) ? $params['class'] : $this-
>getDefaultRouteClass(), array(
$params['url'] ? $params['url'] : '/',
isset($params['params']) ? $params['params'] : (isset($params['param']) ?
$params['param'] : array()),
isset($params['requirements']) ? $params['requirements'] : array(),
isset($params['options']) ? $params['options'] : array(),
));
}
}
return $routes;
}
public function getDefaultRouteClass()
{
$default = sfConfig::get('app_routing_route_class');
return $default ? $default : 'sfRoute';
}
}
Setting a Default Route Class
•Extend the sfRoutingConfigHandler class to return a configurable default route
class
8. Subdomain routing
# apps/*/config/routing.yml
homepage_sub1:
url: /
param: { module: main, action: homepage1 }
class: sfRequestHostRoute
requirements:
sf_host: sub1.example.com
homepage_sub2:
url: /
param: { module: main, action: homepage2 }
class: sfRequestHostRoute
requirements:
sf_host: sub2.example.com
# apps/*/config/routing.yml
homepage_sub1:
url: /
param: { module: main, action: homepage1 }
class: sfRequestHostRoute
requirements:
sf_host: sub1.example.com
homepage_sub2:
url: /
param: { module: main, action: homepage2 }
class: sfRequestHostRoute
requirements:
sf_host: sub2.example.com
•Create a custom route Class (we are using sfRequestHostRoute)
•specify your subdomain in route requirements
•note: Don’t Forget! Routes of class sfRoute can still match this url without
subdomains.
9. class sfRequestHostRoute extends sfRequestRoute
{
public function matchesUrl($url, $context = array())
{
if (isset($this->requirements['sf_host']) && $this->requirements['sf_host'] != $context['host'])
{
return false;
}
return parent::matchesUrl($url, $context);
}
}
class sfRequestHostRoute extends sfRequestRoute
{
public function matchesUrl($url, $context = array())
{
if (isset($this->requirements['sf_host']) && $this->requirements['sf_host'] != $context['host'])
{
return false;
}
return parent::matchesUrl($url, $context);
}
}
Subdomain routing
•Create sfREquestHostRoute class, extend sfRequestRoute
•Overload matchesUrl method - This method is called on all routes declared in
routing.yml until one returns true
•check ‘host’ requirement. If it matches, continue to match the url. return false
otherwise
10. Subdomain routing (cont)
class sfRequestHostRoute extends sfRequestRoute
{
// ...
public function generate($params, $context = array(), $absolute = false)
{
$url = parent::generate($params, $context, $absolute);
if (isset($this->requirements['sf_host']) && $this->requirements['sf_host'] != $context['host'])
{
// apply the required host
$protocol = $context['is_secure'] ? 'https' : 'http';
$url = $protocol.'://'.$this->requirements['sf_host'].$url;
}
return $url;
}
}
class sfRequestHostRoute extends sfRequestRoute
{
// ...
public function generate($params, $context = array(), $absolute = false)
{
$url = parent::generate($params, $context, $absolute);
if (isset($this->requirements['sf_host']) && $this->requirements['sf_host'] != $context['host'])
{
// apply the required host
$protocol = $context['is_secure'] ? 'https' : 'http';
$url = $protocol.'://'.$this->requirements['sf_host'].$url;
}
return $url;
}
}
•Overload generate method (called when using link_to and url_for methods,
etc.)
•If this route has an sf_host requirement set, add this to the generated url, and
prepend to the matching host
•This will ensure links reroute to the new subdomain
11. <?php
class myRequestHostRoute extends sfRoute
{
protected $_subdomains = array('foo', 'bar'),
$_root = 'dev.localhost',
$_default = 'www';
public function matchesUrl($url, $context = array())
{
if (!in_array($context['sf_host'], $this->_subdomains))
{
return false;
}
return parent::matchesUrl($url, $context);
}
// ...
}
<?php
class myRequestHostRoute extends sfRoute
{
protected $_subdomains = array('foo', 'bar'),
$_root = 'dev.localhost',
$_default = 'www';
public function matchesUrl($url, $context = array())
{
if (!in_array($context['sf_host'], $this->_subdomains))
{
return false;
}
return parent::matchesUrl($url, $context);
}
// ...
}
Dynamic Subdomain routing
•Turns Passed Parameter “subdomain” into a subdoman (as long as it’s in the
array of specified subdomains)
note: this class is untested
12. public function generate($params, $context = array(), $absolute = false)
{
$url = parent::generate($params, $context, false);
// if accessing by ip or different domain, bypass subdomain routing
if (!strstr($context['host'], $this->_root))
{
return $url;
}
// apply the required host
$protocol = $context['is_secure'] ? 'https' : 'http';
// if the subdomain is set, and is in our list of known subdomains
if (isset($params['subdomain']) && in_array($params['subdomain'], $this->_subdomains))
{
$url = $protocol.'://'. $params['subdomain'].'.'.$this->_root.$url;
}
else
{
// use class default if subdomain does not exist
$url = $protocol.'://'.$this->_default.'.'.$this->_root.$url;
}
return $url;
}
}
public function generate($params, $context = array(), $absolute = false)
{
$url = parent::generate($params, $context, false);
// if accessing by ip or different domain, bypass subdomain routing
if (!strstr($context['host'], $this->_root))
{
return $url;
}
// apply the required host
$protocol = $context['is_secure'] ? 'https' : 'http';
// if the subdomain is set, and is in our list of known subdomains
if (isset($params['subdomain']) && in_array($params['subdomain'], $this->_subdomains))
{
$url = $protocol.'://'. $params['subdomain'].'.'.$this->_root.$url;
}
else
{
// use class default if subdomain does not exist
$url = $protocol.'://'.$this->_default.'.'.$this->_root.$url;
}
return $url;
}
}
Dynamic Subdomain routing (cont)
See http://healthandwellness.vanderbilt.edu to see dynamic subdomain routing in action