2010-07-19 44 views
7

我正在运行Symfony 1.3.6在Ubuntu 10.0.4 LTS上。在Symfony任务中使用路由生成URL

我写了一个Symfony任务,生成一个包含链接(URL)的报告。

这里是​​方法在我的任务类的代码段:

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.'">This is a test</a>'; 

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

路线名称这样定义:

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

当这个运行时,生成的链接是:

1行产生此输出:

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

,而不是预期:

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

线2产生一个错误:

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

再次,预期网址是:

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

我怎么可能会解决这个?

回答

17

为了生成任务的URL:

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

我们添加到生成路由的方法,使生产URL总是使用:

/** 
    * 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; 
    } 
+0

+1为漂亮,简洁的片段,它告诉我如何解决这个问题。我会稍微修改代码以适应我的工作,测试它,如果它有效,我会接受这个答案。 – morpheous 2010-07-20 07:03:08

+0

它的工作原理!谢谢你,谢谢,谢谢! :) – morpheous 2010-07-20 08:36:57

+0

我应该在哪里放这个片段?我不能在任务中调用$ this-> getRouting():/ – JavierIEH 2012-10-22 14:00:33

3

我你想使用标准的帮手(如url_for)生成URL,也许这代码可以帮助你:

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

然后,您可以使用带有绝对= true参数url_for功能到处奇迹般地工作。

当然,你需要在你的app.yml中添加* url_base *定义(或者你可以把它harcoded)

+2

thansk很多,这为我工作。小评论:'$ options'用于任务命令行选项,所以变量的名称不同可以避免问题.. – Tapper 2012-10-30 16:34:18

+0

已更新。谢谢。 – glerendegui 2012-11-01 15:48:22

0

你可以调整默认请求选项为项目配置脚本命令(sfTask) 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'); 
    } 

}