如何切换Symfony的php-translation / symfony-bundle EditInPlace

时间:2018-11-13 20:56:06

标签: symfony symfony4

我遵循此documentation进行了就地编辑,并设置了 Activator ,它可以正常工作!

但是,我将在生产站点上使用它,并允许通过ROLE_TRANSLATOR授权进行访问。这也可以,但我不希望Web界面始终处于“打开”状态

如何通过某种链接或切换启用它?

我的想法,只需添加一个URL参数(如?trans=yes,然后在激活器中即可)。

return ($this->authorizationChecker->isGranted(['ROLE_TRANSLATOR']) && $_GET['trans'] == 'yes');

很显然,$_GET不起作用,我什至没有尝试。

  1. 如何生成一个链接,以使用额外的URL参数简单地重新加载此页面
  2. 如何在“激活器”中检查该参数

或者,还有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

正如我发现的有关“服务”的更多信息一样,“正确”的方法是在RoleActivator.php文件中进行逻辑划分。

参考How to Inject Variables into all Templates via Referencing Services的文档,我提出了以下解决方案;

src / Security / RoleActivator.php

<?php

namespace App\Security;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Translation\Bundle\EditInPlace\ActivatorInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\HttpFoundation\RequestStack;

class RoleActivator implements ActivatorInterface
{
    /**
     * @var AuthorizationCheckerInterface
     */
    private $authorizationChecker;
    /**
     * @var TranslatorInterface
     */
    private $translate;
    /**
     * @var RequestStack
     */
    private $request;
    private $params;
    private $path;

    private $flag = null;

    public function __construct(AuthorizationCheckerInterface $authorizationChecker, TranslatorInterface $translate, RequestStack $request)
    {
        $this->authorizationChecker = $authorizationChecker;
        $this->translate = $translate;
        $this->request = $request;
    }

    /**
     * {@inheritdoc}
     */
    public function checkRequest(Request $request = null)
    {
        if ($this->flag === null) { $this->setFlag($request); }
        try {
            return ($this->authorizationChecker->isGranted(['ROLE_TRANSLATOR']) && $this->flag);
        } catch (AuthenticationCredentialsNotFoundException $e) {
            return false;
        }
    }

    public function getText()
    {
        if ($this->flag === null) { $this->setFlag(); }
        return ($this->flag) ? 'linkText.translate.finished' : 'linkText.translate.start'; // Translation key's returned
    }

    public function getHref()
    {
        if ($this->flag === null) { $this->setFlag(); }
        $params = $this->params;
        if ($this->flag) {
            unset($params['trans']);
        } else {
            $params['trans'] = 'do';
        }
        $queryString = '';
        if (!empty($params)) {
            $queryString = '?';
            foreach ($params as $key => $value) {
                $queryString.= $key.'='.$value.'&';
            }
            $queryString = rtrim($queryString, '&');
        }
        return $this->path.$queryString;
    }

    private function setFlag(Request $request = null)
    {
        if ($request === null) {
            $request = $this->request->getCurrentRequest();
        }
        $this->flag = $request->query->has('trans');
        $this->params = $request->query->all();
        $this->path = $request->getPathInfo();
    }
}

config \ packages \ twig.yaml

twig:
    # ...
    globals:
        EditInPlace: '@EditInPlace_RoleActivator'

config \ services.yaml

services:
    # ...
    EditInPlace_RoleActivator:
        class: App\Security\RoleActivator
        arguments: ["@security.authorization_checker"]

因此,我在php-translation示例之上添加的是getTextgetHref方法以及在private中设置并在其后读取的相应checkRequest变量

现在在我的树枝模板(位于标题中)

{% if is_granted('ROLE_TRANSLATOR') %}
    <a href="{{ EditInPlace.Href }}">{{ EditInPlace.Text }}</a>
{% endif %}

将新密钥添加到翻译文件中并完成。每次单击该链接,即可打开和关闭trans=do查询参数。您甚至可以添加带有类名的切换样式,只需将getText方法复制到getClass之类,并用三进制返回字符串ab