获取Twig仅显示页面或菜单的授权部分

时间:2017-11-17 09:25:38

标签: twig

我打算将网站转换为使用MVC和php。 我打算使用Twig模板引擎,以便我可以从页面模板中删除所有代码,但我遇到了一个问题,那就是我的菜单。我只希望某个级别的用户访问每个菜单项。

我有一个我调用的函数,如果允许某个级别,则返回true。 因此,例如,如果您有购买级别,您将被允许查看菜单项1,但不允许查看菜单项2.例如,销售将无法看到前两个菜单项。

我知道你不能在Twig中调用函数或类。

例如(我的函数属于一个名为logon的类,但这不重要)

<?php if ($logon->user_access('purchase','accountant','poweruser')):?>
    Menu Item 1
<?php endif;?>

 <?php if ($logon->user_access('accountant','poweruser')):?>
    Menu Item 2 
 <?php endif;?>

  <?php if ($logon->user_access('sales')):?>
    Menu Item 2 
 <?php endif;?>

问题是如何在不使用php的情况下使用此功能在树枝中制作模板? 我完全不熟悉使用模板引擎。

...编辑 @Yoshi

好的,我在index.php中加入了

的twig
require_once dirname(__DIR__).'/vendor/Twig/vendor/autoload.php';

然后每当我想渲染页面时,我都会从我的核心/视图中调用一个函数

public static function renderTwig($template,$args =[])
{
    static $twig = null;

    if($twig === null){
        $loader = new \Twig_Loader_Filesystem('../App/Views');
        $twig = new \Twig_Environment($loader);
        echo $twig->render($template, $args);   
    }
}

然后在我的控制器中我打电话

View::renderTwig('Home/index.html',[
            'css'=> $css,
            'name' => 'Dave',
            'colours' => ['red','green','blue']
        ]);

我将这一切都从我一直关注的教程中设置为&#34;从头开始创建php mvc项目&#34;。

PS。我想在我的renderTwig函数中,我可以发送在每个页面上使用的变量并将其添加到页面的arg数组中。这样我就不需要为每个页面添加身份验证。

编辑: 我在这里做一个小修正案。尽管Yoshi的回答是正确的。我有一个小问题,我现在已经解决了,我想我会分享这个。 在twig模板中,我正在使用它

{% if user_access('sales','purchase') %}Do something{% endif %}

问题是我不知道进入的项目数量,所以我需要使用args,这导致我一个小问题,因为下面一行将字符串发送到我的函数,但只是一件事。

return $this->logon->user_access($roles);

func_get_args的问题是你无法将它传递给另一个函数。它只能在您发送给它的函数中读取。所以我的小修正案是这样的。

return $this->logon->user_access($args = func_get_args());

现在问题在于它发送了一个数组,但我的php例程设置为使用args,我想在php中使用与twig中相同的函数。所以我做的是检查一个数组是否进来,我只是循环通过数组,但如果一个非数组进来我检查了args。例如

public function user_access($levels)
{
    $bool=false;
    if(is_array($levels)):
        foreach($levels as $item):
            if($this->userlevel($item)==true $bool=true;
        endforeach;
    else:
        foreach(func_get_args() as $arg):
            if($this->userlevel($arg)==true $bool=true;
        endforeach;
    endif;
    return $bool;
}

所以,谢谢Yoshi

1 个答案:

答案 0 :(得分:1)

以下是将功能(或对象)添加到视图的一些方法。

  

免责声明:我认为设置树枝的做法非常糟糕   View的静态方法中的环境。我只是一起去   有了它,所以不要在这里复杂化。但如果你对此感兴趣   在如何做得更好。阅读dependency injection

<?php

require_once dirname(__DIR__).'/vendor/Twig/vendor/autoload.php';

// only as an example example
class AccessChecker
{
    public function user_access(...$levels)
    {
        return true;
    }
}

class YourTwigExtension extends \Twig_Extension
{
    /**
     * @var AccessChecker
     */
    private $logon;

    /**
     * @param AccessChecker $logon
     */
    public function __construct(AccessChecker $logon)
    {
        $this->logon = $logon;
    }

    /**
     * @inheritdoc
     */
    public function getFunctions()
    {
        return [
            new Twig_Function('user_access', [$this, 'checkUserAccess']),
        ];
    }

    /**
     * @param array ...$roles
     *
     * @return mixed
     */
    public function checkUserAccess(...$roles)
    {
        return $this->logon->user_access(...$roles);
    }
}

class View
{
    public static function renderTwig($template, $args =[])
    {
        static $twig = null;

        if($twig === null) {
            $loader = new \Twig_Loader_Filesystem('../App/Views');
            $twig = new \Twig_Environment($loader);

            // the extras:
            $logon = new AccessChecker();

            // with globals:
            $twig->addGlobal('logon', $logon);

            /*
             * {% if logon.user_access('purchase','accountant','poweruser') %}
             *   ...
             * {% endif %}
             */

            // with functions:
            $twig->addFunction(new Twig_Function('user_access', [$logon, 'user_access']));

            /*
             * {% if user_access('purchase','accountant','poweruser') %}
             *   ...
             * {% endif %}
             */

            // with an extension
            $twig->addExtension(new YourTwigExtension($logon));

            /*
             * {% if checkUserAccess('purchase','accountant','poweruser') %}
             *   ...
             * {% endif %}
             */
        }

        echo $twig->render($template, $args);
    }
}

注意:您显然只需要选择一种添加功能的方法。我建议去扩展。这样,以后的添加可以在同一个地方发生,而无需更改接线代码。