我有一个symfony2 web项目,由10个页面组成,通过5个控制器呈现。用户可以通过上面的任何页面登陆网站(例如通过共享链接)。我需要向在当前会话期间首次打开页面的用户显示欢迎弹出窗口(只有position:absolute
div)。
我已将弹出窗口放在常用的twig模板中,该模板由所有需要的页面使用。现在我必须确定是否显示弹出窗口。我将根据控制器的布尔值显示弹出窗口。
我必须使用会话和cookie,但我必须在每个页面上执行此操作,并且我不想在每个方法中编写相同的代码(检查并设置cookie,输出布尔值以在模板中显示弹出窗口)每个控制器。根据DRY概念,有没有办法解决这个问题?
答案 0 :(得分:1)
您可以创建一个包装类来处理检查,设置和获取当前会话值并使其成为服务。
<?php
namespace My\Bundle\My\Namespace;
use Symfony\Component\HttpFoundation\Session\Session;
class SessionManager /* or whatever you want to call it */
{
public function __construct(Session $session)
{
$this->session = $session;
}
public function getMyValue()
{
return $this->session->get('my.value.key',null);
}
public function setMyValue($value)
{
$this->session->set('my.value.key',$value);
return $this;
}
public function hasMyValue()
{
return $this->session->has('my.value.key');
}
}
并在您的捆绑服务.yml
<service id="mytag.session_manager" class="My\Bundle\My\Namespace\SesionManager">
<argument type="service" id="session" />
</service>
在您的控制器中
public function someAction()
{
$sessionManager = $this->get('mytag.session_manager');
if($sessionManager->hasMyValue())
{
// do something
}
}
答案 1 :(得分:0)
感谢Sgoettschkes在这里回答Where to place common business logic for all pages in symfony2 我尝试过这种方法 http://symfony.com/doc/current/book/templating.html#embedding-controllers
它看起来很棒: 我的弹出窗口包含在主模板中,如此
{{ render(controller('MalyutkaMainBundle:WelcomePopup:index')) }}
在控制器内我操纵会话变量
class WelcomePopupController extends Controller {
public function indexAction(Request $request) {
$session = $this->get('session');
$showWelcomePopup = 0;
if ($session->has("have_seen_welcome_popup_on")) {
// tbd compare to the date of publishing of the new popup screen
} else {
$showWelcomePopup = 1;
$session->set("have_seen_welcome_popup_on", new \DateTime());
}
$params = array (
'show_welcome_popup' => $showWelcomePopup
);
return $this->render('MalyutkaMainBundle:WelcomePopup:welcome_popup.html.twig', $params);
}
}
在其他控制器中没有添加任何内容 - 正是我想要做的事情。 但是不可能以这种方式更改cookie,因此我将数据存储在会话中。