2010-07-19 7 views
7

Tôi đang chạy Symfony 1.3.6 trên Ubuntu 10.0.4 LTS.Sử dụng tuyến đường để tạo URL trong tác vụ Symfony

Tôi đã viết một tác vụ Symfony tạo báo cáo chứa liên kết (URL).

Dưới đây là một đoạn của phương pháp execute() trong lớp nhiệm vụ của tôi:

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

Tên đường được định nghĩa như thế này:

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

Khi điều này được điều hành, liên kết được tạo ra là:

Dòng 1 sản xuất kết quả này:

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

thay vì dự kiến:

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

Dòng 2 tạo ra một lỗi:

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

Một lần nữa, các URL được mong đợi là:

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

Làm thế nào tôi có thể giải quyết điều này?

Trả lời

17

Để tạo ra một URL trong một nhiệm vụ:

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

Chúng tôi thêm một phương pháp để tạo ra định tuyến để URL sản xuất luôn được sử dụng:

/** 
    * 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 cho đoạn mã đẹp, ngắn gọn cho tôi biết cách giải quyết vấn đề này. Tôi sẽ sửa đổi mã một chút để phù hợp với những gì tôi đang làm, kiểm tra nó, nếu nó hoạt động, tôi sẽ chấp nhận câu trả lời này. – morpheous

+0

Nó hoạt động !. Cảm ơn bạn, cảm ơn bạn, cảm ơn bạn! :) – morpheous

+0

Tôi nên đặt đoạn mã này ở đâu?Tôi không thể gọi $ this-> getRouting() từ một nhiệm vụ:/ – JavierIEH

1

Tôi đã có cùng một vấn đề và tìm thấy Đoạn mã sau đây: http://snippets.symfony-project.org/snippet/378

Giải pháp này khá giống nhau, tuy nhiên nó mở rộng ProjectConfiguration. Ưu điểm của phương pháp này là, nó hoạt động minh bạch trong các mô-đun như là tốt.

3

tôi bạn muốn sử dụng người giúp đỡ tiêu chuẩn (như url_for) để tạo url, có lẽ mã này có thể giúp bạn:

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

Sau đó, bạn có thể sử dụng url_for chức năng ở khắp mọi nơi với tuyệt đối tham số = true kỳ diệu làm việc.

Tất nhiên, bạn cần phải thêm một * url_base * định nghĩa trong app.yml của bạn (hoặc có thể bạn có thể để nó harcoded)

+2

thansk rất nhiều, điều này làm việc cho tôi. ít bình luận: '$ options' được sử dụng cho các tùy chọn dòng lệnh nhiệm vụ, do đó, một tên khác cho biến tránh các vấn đề .. – Tapper

+0

Cập nhật. Cảm ơn. – glerendegui

0

Bạn có thể tinh chỉnh tùy chọn theo yêu cầu mặc định cho lệnh (sfTask) trong kịch bản cấu hình dự án 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'); 
    } 

}