2012-01-11 28 views
8

Tôi đang cố gắng gửi email từ ContainerAwareCommand trong Symfony2. Nhưng tôi nhận được ngoại lệ này khi mẫu email được làm bởi:Symfony2 Templating mà không yêu cầu

$body = $this->templating->render($template, $data); 

Exception:

("You cannot create a service ("templating.helper.assets") of an inactive scope ("request").") 

tôi tìm thấy trong github rằng helper này cần đối tượng yêu cầu. Bất kỳ ai biết làm thế nào tôi có thể để dụ đối tượng Yêu cầu?

Trả lời

1

Vì bạn không có một yêu cầu, bạn cần phải gọi dịch vụ khuôn mẫu trực tiếp như thế này:

$this->container->get('templating')->render($template, $data); 
+3

Điều này không giải quyết được sự cố. Khi logn là tài sản được sử dụng (có thể không hiển thị trực tiếp trong các mẫu của bạn), nó cần phải có một dịch vụ RequestContext bằng cách nào đó. – BetaRide

+0

Tôi gặp lỗi tương tự nhưng giải pháp này không giải quyết được vấn đề.http: //stackoverflow.com/questions/17942738/erro-you-cannot-create-a-service-templating-helper-assets-of-an-inactive -sco – vishal

+0

Giải pháp này làm việc cho tôi khi tôi đăng nó. Tôi sẽ không tranh cãi trong một phút rằng nó không hoạt động với các phiên bản Symfony mới hơn so với lúc đó. Khi nói đến việc thoát khỏi con đường bị đánh đập, Symfony là một mục tiêu di chuyển. Tôi đã không có thời gian cho mã trong một thời gian vì vậy tôi không thể thực sự điều tra vào lúc này, nhưng bạn có thể thử giải pháp của BetaRide. – Matthew

19

Bạn cần phải thiết lập các container vào phạm vi quyền và cung cấp cho nó một (giả) theo yêu cầu. Trong hầu hết các trường hợp, điều này sẽ là đủ:

//before you render template add bellow code 
$this->getContainer()->enterScope('request'); 
$this->getContainer()->set('request', new Request(), 'request'); 

Câu chuyện đầy đủ là here. Nếu bạn muốn biết chi tiết, hãy đọc số này issue on github.

+1

FYI: Điều này đã không được chấp nhận và bị xóa trong Symfony 3 và được thay thế bằng "setScope" ở cấp dịch vụ: https://github.com/symfony/symfony/blob/master/UPGRADE-3.0.md#dependencyinjection – Rvanlaak

4

Sự cố phát sinh do bạn sử dụng hàm nội dung() trong mẫu của bạn.

Theo mặc định, tài sản() dựa vào Yêu cầu dịch vụ để tạo ra các url đối với tài sản của mình (nó cần phải biết đường dẫn cơ sở để bạn trang web là những gì hoặc tên miền là gì nếu bạn sử dụng url tài sản tuyệt đối , ví dụ).

Nhưng khi bạn chạy ứng dụng của mình từ dòng lệnh, không có Yêu cầu.

Một cách để sửa lỗi này nó để explicitely định nghĩa url căn cứ để nội dung trong config.yml như thế này:

framework: 
    templating: 
    assets_base_urls: { http: ["http://yoursite.com"], ssl: ["http://yoursite.com"] } 

Điều quan trọng là phải xác định cả httpssl, bởi vì nếu bạn bỏ qua một trong số họ nội dung() sẽ vẫn phụ thuộc vào dịch vụ Yêu cầu.

Nhược điểm (có thể) là tất cả các url đến nội dung giờ đây sẽ tuyệt đối.

+0

Cảm ơn để giải thích rõ ràng và giải pháp của bạn, nó hoạt động hoàn hảo! Tôi đã thử trước giải pháp này http://symfony.com/doc/current/cookbook/console/sending_emails.html nhưng không thành công –

+0

Với giải pháp này, tất cả nội dung đều sử dụng một url tuyệt đối. Nó có thể là một vấn đề đôi khi. – ke20

+0

Giải pháp này chỉ hoạt động nếu url http và url ssl giống hệt nhau. –

1

Làm theo câu trả lời của BetaRide để tôi đi đúng hướng nhưng điều đó không đủ. Sau đó, nó đã phàn nàn: "Không thể tạo URL cho tuyến đường được đặt tên" "vì tuyến đường như vậy không tồn tại".

Để tạo một yêu cầu hợp lệ Tôi đã sửa đổi nó để yêu cầu thư mục gốc của dự án như sau: (? Rễ bảo đảm)

$request = new Request(); 
$request->create('/'); 
$this->container->enterScope('request'); 
$this->container->set('request', $request, 'request'); 

Bạn có thể cần phải gọi một con đường khác, rễ làm việc cho tôi chỉ khỏe.

Symfony2 Docs

Bonus thêm:

tôi đã phải làm rất nhiều khuôn mẫu/định tuyến trong cli qua Symfony2 lệnh mà tôi đã cập nhật các phương pháp initializeContainer() trong AppKernel. Nó tạo ra một lộ trình vào thư mục gốc của trang web, đặt bối cảnh router và hàng giả một người dùng đăng nhập:

protected function initializeContainer() 
{ 
    parent::initializeContainer(); 
    if (PHP_SAPI == 'cli') { 

     $container = $this->getContainer(); 

     /** 
     * Fake request to home page for cli router. 
     * Need to set router base url to request uri because when request object 
     * is created it perceives the "/portal" part as path info only, not base 
     * url and thus router will not include it in the generated url's. 
     */ 
     $request = Request::create($container->getParameter('domain')); 
     $container->enterScope('request'); 
     $container->set('request', $request, 'request'); 
     $context = new RequestContext(); 
     $context->fromRequest($request); 
     $container->get('router')->setContext($context); 
     $container->get('router')->getContext()->setBaseUrl($request->getRequestUri()); 

     /** 
     * Fake admin user login for cli. Try database read, 
     * gracefully print error message if failed and continue. 
     * Continue mainly for doctrine:fixture:load when db still empty. 
     */ 
     try { 
      $user = $container->get('fos_user.user_manager')->findUserByUsername('admin'); 
      if ($user !== null) { 
       $token = $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles()); 
       $this->getContainer()->get('security.token_storage')->setToken($token); 
      } 
     } catch (\Exception $e) { 
      echo "Fake Admin user login failed.\n"; 
     } 
    } 
} 

Bạn có thể không cần $container->get('router')->getContext()->setBaseUrl($request->getRequestUri()); phần cuối cùng, nhưng tôi đã phải làm điều đó vì gốc trang web của tôi là tại miền .com/siteroot/và các bộ định tuyến đã được tước/siteroot/đi cho thế hệ url.

+0

FYI: Điều này không được chấp nhận và bị xóa trong Symfony 3 và được thay thế bằng "setScope" ở cấp dịch vụ: https://github.com/symfony/symfony/blob/master/UPGRADE-3.0.md#dependencyinjection – Rvanlaak

Các vấn đề liên quan