![]() |
|
Code snippets for symfony 1.x |
|
The symfony routing system is tied to the sfContext resource via the factory handler.
It might an issue if you need to build routes in the cli mode, where sfContext has no instance. Sample: one of your cron jobs sends emails that contain links.
The best way I've found is to provide an access to the routing system linked to the ProjectConfiguration class. Add a static protected "$routing" variable and a static public method "getRouting()" :
class ProjectConfiguration extends sfProjectConfiguration { static protected $routing = null # Symfony routing system ; /** * Returns the routing resource for the active application */ static public function getRouting() { if (null !== self::$routing) { return self::$routing; } // If sfContext has an instance, returns the loaded routing resource if (sfContext::hasInstance() && sfContext::getInstance()->getRouting()) { self::$routing = sfContext::getInstance()->getRouting(); } else { // Initialization if (!self::hasActive()) { throw new sfException('No sfApplicationConfiguration loaded'); } $appConfig = self::getActive(); $config = sfFactoryConfigHandler::getConfiguration($appConfig->getConfigPaths('config/factories.yml')); $params = array_merge( $config['routing']['param'], array( 'load_configuration' => false, 'logging' => false, 'context' => array( 'host' => sfConfig::get('app_host', 'localhost'), 'prefix' => sfConfig::get('app_prefix', sfConfig::get('sf_no_script_name') ? '' : '/'.$appConfig->getApplication().'_'.$appConfig->getEnvironment().'.php'), 'is_secure' => sfConfig::get('app_host', false), ), ) ); $handler = new sfRoutingConfigHandler(); $routes = $handler->evaluate($appConfig->getConfigPaths('config/routing.yml')); $routeClass = $config['routing']['class']; self::$routing = new $routeClass($appConfig->getEventDispatcher(), null, $params); self::$routing->setRoutes($routes); } return self::$routing; } }
In the method, the 'context' parameter needs further explanations.
In a classic context, symfony is loaded after a web request. Sample: https://www.example.com/frontend_dev.php/products
This request provides data that are reused when sf needs to generate a new dynamic url:
In the cli mode, as Symfony is not loaded by a request, you have to provide these parameters (prefix can be guessed).
In app.yml, add:
all:
host: www.example.com
is_secure: false
Now, let's see how to generate the link. If your routing.yml file looks like it:
product_show: url: /products/:category_slug/:slug class: sfDoctrineRoute options: { model: Product, type: object } # ...
Then building the link is as simple as:
class Product extends BaseProduct { /** * Returns the public url */ public function getUrl() { return ProjectConfiguration::getRouting()->generate('product', $this, true); } /* ... */ }
Regards.
Comments on this snippet
The initialisation line for symfony 1.2.8 should read as following:
// Initialization if (!self::getActive())
There is no method self::hasActive() in symfony 1.2.8, only self::getActive()
Spotted a typo in the "context" array definition : ... 'is_secure' => sfConfig::get('app_is_secure', false), // NOT app_host ...
Thanks.