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

让Twig仅显示页面或菜单的授权部分,twig,Twig,我计划将一个网站转换为使用MVC和php。 我计划使用Twig模板引擎,以便从页面模板中删除所有代码,但我遇到了一个问题,那就是我的菜单。我只希望某个级别的用户访问每个菜单项 我调用了一个函数,如果允许某个级别,它将返回true。 因此,例如,如果您有一个购买级别,您将被允许查看菜单项1,但不允许查看菜单项2。例如,销售人员将无法看到前两个菜单项 我知道你不能在Twig中调用函数或类 我的函数在一个名为logon的类中,但这不重要 <?php if ($logon->user_acc

我计划将一个网站转换为使用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;?>
然后,每当我想要呈现页面时,我都会从核心/视图调用一个函数

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']
        ]);
我从一个名为“从头开始创建php mvc项目”的教程中设置了这一切

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

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

{% if user_access('sales','purchase') %}Do something{% endif %}
问题是我不知道要输入的项的数量,所以我需要使用args,这导致了一个小问题,因为下面的行将字符串发送给了我的函数,但只发送了一项

return $this->logon->user_access($roles);
func_get_参数的问题是无法将其传递给其他函数。它只能在发送给的函数中读取。所以我的小修正案是这样的

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,这里有一些方法可以将函数或对象添加到视图中

免责声明:我认为设置树枝是非常糟糕的做法 静态视图方法中的环境。我只是随大流 有了它,这里的事情就不会太复杂了。但是如果你感兴趣的话 如何做得更好。仔细阅读


注意:您显然只需要选择一种添加功能的方法。我建议延期。这样,以后的添加可以在同一个位置进行,而无需更改连接代码。

只需将函数添加为。或将$logon变量传递给templateTrue,但对于此类通用功能,这有点不方便。在每次渲染时,必须记住始终获取$logon并将其传递给视图。$logon不是变量。它是一个类,而user_access是该类中的一个函数,只有在级别正确时才返回true。@显然,它是一个存储该类实例的变量。但这真的不重要。无论是对对象的方法调用,还是静态类调用,要将其传输到twig视图,您都需要在每个渲染上向视图传递一个扩展名或可调用的内容。好的,我想我明白了,如果我没有使用扩展名,我只需要更改renderTwig,对吗?如果我正在使用分机,我应该把分机放在哪里?我可以从任何地方运行该类,还是应该将该类放在供应商/twig文件夹的某个地方,因为它是twig的扩展。之所以使用静态函数,是因为我在学习一个教程,不知道还有什么更好的方法。@ThomasWilliams,没关系,真的。看来你还在学习,很难决定把东西放在哪里。回答:不,不要把你的小枝扩展放到供应商目录中。那个目录是禁止进入的。按照惯例使用您自己的源目录/src。您可能需要设置自动加载。如果您正在使用,那只是一个问题。我已经编写php很多年了。两年前才开始使用php类,所以还在学习。不过,我有一个领先的开端,因为我已经知道C++,所以它帮助与面向对象的东西。然而,我只学习了两周的MVC php,同时也学习了asp.net。当我在大约8小时后到家时,我将尝试你的代码,并让你知道它是否有效。我现在不能调查此事,因为我还得完成老板要我做的其他工作LOL@ThomasWilliams如果你有问题,请留下评论。我终于让它工作了问题是你把return$this->logon->check_access…$roles;但是$logon中的函数名为user\u access,所以一旦我更改了函数名,它就可以工作了。
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;
}
<?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);
    }
}