开发者

Using routes to generate URLs in a Symfony task

I am running Symfony 1.3.6 on Ubuntu 10.0.4 LTS.

I have written a Symfony task that generates a report which contains links (URLs).

Here is a snippet of the execute() method in my task class:

  protected function execute($arguments = array(), $options = array())
  {
    //create a context
    sfContext::createInstance($this->configuration);
    sfContext::getInstance()->getConfiguration()->loadHelpers(array('Url', 'Asset', 'Tag'));

    ...
    $url = url_for("@foobar?cow=marymoo&id=42");

    // Line 1
    echo '<a href="'.$url.'">开发者_如何学Go;This is a test</a>';

    // Line 2
    echo link_to('This is a test', $url); 
  }

The route name is defined like this:

foobar:
  url: /some/fancy/path/:cow/:id/hello.html
  param: {  module: mymodule, action: myaction }

When this is run, the generated link is:

Line 1 produces this output:

./symfony/symfony/some/fancy/path/marymoo/42/hello.html

instead of the expected:

/some/fancy/path/marymoo/42/hello.html

Line 2 generates an error:

Unable to find a matching route to generate url for params "array ( 'action' => 'symfony', 'module' => '.',)".

Again, the expected URL is:

/some/fancy/path/marymoo/42/hello.html

How may I resolve this?


To generate a URL in a task:

protected function execute($arguments = array(), $options = array())
{
  $routing = $this->getRouting();
  $url = $routing->generate('route_name', $parameters);
}

We add a method to generate routing so that the production URL is always used:

   /**
   * Gets routing with the host url set to the url of the production server
   * @return sfPatternRouting
   */
  protected function getProductionRouting()
  {
    $routing = $this->getRouting();
    $routingOptions = $routing->getOptions();
    $routingOptions['context']['host'] = 'www.example.com';
    $routing->initialize($this->dispatcher, $routing->getCache(), $routingOptions);
    return $routing;
  }


I you wanna to use standard helpers (like url_for) to generate url, maybe this code could help you:

  protected function execute($arguments = array(), $options = array())
  {
    // initialize the database connection
...
$context = sfContext::createInstance($this->configuration);

$routing = $context->getRouting();
$_options = $routing->getOptions();
$_options['context']['prefix'] = "";// "/frontend_dev.php" for dev; or "" for prod
$_options['context']['host'] = sfConfig::get('app_url_base');
$routing->initialize($this->dispatcher, $routing->getCache(),$_options);
$context->getConfiguration()->loadHelpers('Partial');
$context->set('routing',$routing);    
//$_SERVER['HTTP_HOST'] = sfConfig::get('app_url_base'); // ---> I don't remember why I have this on my code, shouldn't be necessary
...

Then, you can use url_for function everywhere with absolute=true parameter magically working.

Of course, you need to add a *url_base* definition in your app.yml (or maybe you can leave it harcoded)


I have had the same problem and found the following Code Snippet: http://snippets.symfony-project.org/snippet/378

The solution is rather similar, however it extends the ProjectConfiguration. The advantage of this approach is, that it works transparently in modules as as well.


You can tweak default request options for commands (sfTask) in the project configuration script config/ProjectConfiguration.class.php

class ProjectConfiguration extends sfProjectConfiguration {

    public function setup() {
        ...
        $this->dispatcher->connect('command.pre_command', array('TaskWebRequest', 'patchConfig'));
    }

}

class TaskWebRequest extends sfWebRequest {

    public function __construct(sfEventDispatcher $dispatcher, $parameters = array(), $attributes = array(), $options = array())
    {
        $options['no_script_name'] = true;
        $options['relative_url_root'] = '';
        parent::__construct($dispatcher, $parameters, $attributes, $options);
    }

    public static function patchConfig(sfEvent $event) {
        sfConfig::set('sf_factory_request', 'TaskWebRequest');
    }

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜