We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Show volt links based on role

Hei.

I am using a Vokuro instance to play around with Phalcon. Vokuro delivers 3 roles (Admin, User and Guest).

I would like to display links within my volt-template based upon those roles. (f.ex. show links to administration only to users with the administrator role)

So in Acl.php I included:


//check if user is admin, return true/false
public function isAdmin(){
    return ( $this->auth->getIdentity()['profile'] == 'Administrators' ? true : false );
}

I added a new volt function to services.php


/**
 * Setting up the view component
 */
$di->set('view', function () use ($config) {

    $view = new View();

    $view->setViewsDir($config->application->viewsDir);

    $view->registerEngines(array(
        '.volt' => function ($view, $di) use ($config) {

            $volt = new VoltEngine($view, $di);

            $volt->setOptions(array(
                'compiledPath' => $config->application->cacheDir . 'volt/',
                'compiledSeparator' => '_'
            ));

            $compiler = $volt->getCompiler();

            $compiler->addFunction('isAdmin', function() {
                $acl = new Acl();
                return $acl->isAdmin();
            });

            return $volt;
        }
    ));

    return $view;
}, true);

Finally I changed my menu in the volt template to this:


{% if isAdmin() %}
    {% set menus = [
        'Profile': 'users/changePassword',
        'Administration': 'administration',
        'Logout': 'session/logout'
    ] %}
{% else %}
    {% set menus = [
        'Profile': 'users/changePassword',
        'Logout': 'session/logout'
    ] %}
{% endif %}

So far so good. But now I encounter this behavior: I use Chrome and Firefox side by side with 2 users. Chrome with my administrator account, FF with a user account. When I log into the user-account with FF, the user sees his own menu without the admin-link. When I log into the admin account afterwards with Chrome, I see the usermenu aswell!? Now, when I log off all accounts, login into the admin-account first, and into the user-account afterwards, the user sees the administration-menu.

Do you have an idea what is happening and/or a more nice solution to devide admin-views from user-views?

thanks in advance, greetings

//edit: I have to delete the metaData in order to "reset" the view before I can login with the other account to make the opposite view available.

Using PHP inside the volt-template works flawless.

<?php if( $this->auth->getIdentity()['profile'] == 'Administrators' ) { ?>
    {% set menus = [
        'Profile': 'users/changePassword',
        'Administration': 'administration',
        'Logout': 'session/logout'
    ] %}
<?php } else { ?>
    {% set menus = [
        'Profile': 'users/changePassword',
        'Logout': 'session/logout'
    ] %}
<?php } ?>

But I want to try to keep my templates without PHP as far as possible. :/



6.6k
Accepted
answer

You have to use additional volt compiler functions as the example from the documentation shows:

<?php

$compiler->addFunction('widget', function($resolvedArgs, $exprArgs) {
    return 'MyLibrary\Widgets::get(' . $resolvedArgs . ')';
});

This means that volt compiler parses your template and simply performs textual replacements with plain PHP code. So maybe its a good idea to create a static function inside Acl class public static function isAdmin(). Then you can do the following:

<?php

$compiler->addFunction('isAdmin', function() {
    return 'ACLNamespace\Acl::isAdmin()';
});

I hope this helps! :)

Then I have to make the session within the static function static aswell, right?

Fatal error: Using $this when not in object context in ...


6.6k

You can access the current di in a static way: \Phalcon\DI::getDefault()->get(...);

Thank you for the hints! :)

But I think I'll try another approach aswell, as I will fetch the links from the DB soon. Then I can apply the roles at this stage already. :)