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

How to toggle Symfony's php-translation/symfony-bundle EditInPlace

我按照此 documentation 进行 就地编辑 ,并设置 Activator,它起作用了!

但是,我将在生产站点上使用它并允许通过 ROLE_TRANSLATOR 授权进行访问。这也有效,但我不希望网络界面总是 "on"

我如何通过某种 link 或切换来启用它?

我的想法,只需要添加一个URL参数就很简单了,比如?trans=yes然后在activator中;

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

显然,$_GET不行,我都没试过。

  1. 如何生成 link 以使用额外的 URL 参数
  2. 简单地重新加载此页面
  3. 如何在 "Activator"
  4. 中检查该参数

或者,有没有更好的方法?

执行此操作的 "proper" 方法,因为我发现更多关于 "services" 的内容是直接在 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 方法以及在 checkRequest 中设置的相应 private 变量之后阅读。

现在在我的树枝模板中(在 header 中)我只使用

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

将新密钥添加到翻译文件中,大功告成。每次单击 link,trans=do 查询参数就会打开和关闭。您甚至可以添加带有 class 名称的切换样式,只需将 getText 方法复制到 getClass 和 return 字符串 ab与三元。