我试图从Symfony2中的ContainerAwareCommand
发送电子邮件。但是当电子邮件模板呈现时,我得到了这个例外:
$body = $this->templating->render($template, $data);
异常:
("You cannot create a service ("templating.helper.assets") of an inactive scope ("request").")
我在github中发现这个助手需要请求对象。有人知道如何实例化Request对象吗?
答案 0 :(得分:19)
您需要将容器设置为正确的范围并为其提供(假的)请求。在大多数情况下,这就足够了:
//before you render template add bellow code
$this->getContainer()->enterScope('request');
$this->getContainer()->set('request', new Request(), 'request');
完整的故事是here。如果您想了解详细信息,请阅读此issue on github。
答案 1 :(得分:4)
问题出现是因为您在模板中使用了 asset()功能。
默认情况下, asset()依靠 Request 服务为您的资产生成网址(它需要知道您网站的基本路径是什么,或者是什么例如,如果您使用绝对资产网址,则为域名。
但是当您从命令行运行应用程序时,没有请求。
解决此问题的一种方法是在config.yml中明确定义资产的基本网址,如下所示:
framework:
templating:
assets_base_urls: { http: ["http://yoursite.com"], ssl: ["http://yoursite.com"] }
定义 http 和 ssl 非常重要,因为如果省略其中一个 asset()仍将依赖于请求服务
(可能的)缺点是资产的所有网址现在都是绝对的。
答案 2 :(得分:1)
由于您没有请求,您需要直接调用模板服务:
$this->container->get('templating')->render($template, $data);
答案 3 :(得分:1)
按照BetaRide的回答让我走上正轨但这还不够。然后它抱怨:“无法生成指定路线的URL”“因为这样的路线不存在。”
要创建一个有效的请求,我已经修改了它以请求项目的根目录,如下所示:
$request = new Request();
$request->create('/');
$this->container->enterScope('request');
$this->container->set('request', $request, 'request');
您可能需要调用不同的路径(安全的root?),root对我来说很好。
加分:
我必须通过Symfony2命令在cli中做很多模板/路由,我已经在AppKernel中更新了initializeContainer()
方法。它创建到站点根目录的路由,设置路由器上下文并伪造用户登录:
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";
}
}
}
您可能不需要最后$container->get('router')->getContext()->setBaseUrl($request->getRequestUri());
部分,但我必须这样做,因为我的网站根位于domain.com/siteroot/,并且路由器正在剥离/ siteroot / away以生成网址。