Navigation.php 3.26 KB
Newer Older
1 2
<?php
/**
3
 * gredu_labs.
4 5
 * 
 * @link https://github.com/eellak/gredu_labs for the canonical source repository
6
 *
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
 * @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
 * @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
 */

namespace GrEduLabs\Application\Twig\Extension;

use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\RouterInterface;
use Twig_Extension;
use Twig_SimpleFunction;
use Zend\Permissions\Acl\AclInterface;

class Navigation extends Twig_Extension
{
    /**
     * @var RouterInterface
     */
    private $router;

    /**
     * @var array
     */
    private $navigation;

    /**
     * @var ServerRequestInterface
     */
    private $request;

    /**
     * @var AclInterface
     */
    private $acl;

    /**
     * @var string
     */
    private $currentRole;

    public function __construct(
        array $navigation,
        RouterInterface $router,
        ServerRequestInterface $request,
        AclInterface $acl = null,
        $currentRole = null
    ) {
        $this->navigation  = $navigation;
        $this->router      = $router;
        $this->request     = $request;
        $this->acl         = $acl;
        $this->currentRole = $currentRole;
    }

60
    /**
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
     * Extension name.
     *
     * @return string
     */
    public function getName()
    {
        return 'slim-navigation';
    }

    /**
     * Callback for twig.
     *
     * @return array
     */
    public function getFunctions()
    {
        return [
            new Twig_SimpleFunction('nav', [$this, 'nav']),
        ];
    }

82 83 84 85 86 87 88 89 90 91 92 93 94 95
    public function setAcl(AclInterface $acl)
    {
        $this->acl = $acl;

        return $this;
    }

    public function setCurrentRole($role)
    {
        $this->currentRole = $role;

        return $this;
    }

96 97 98
    /**
     *
     */
99
    public function nav($root)
100
    {
101 102 103 104 105
        if (!isset($this->navigation[$root]) || !is_array($this->navigation[$root])) {
            return [];
        }

        $navigation = $this->navigation[$root];
106 107 108 109 110 111 112

        $aclFilter = function ($page) {
            if (!$this->acl) {
                return true;
            }

            $path = parse_url($page['href'], PHP_URL_PATH);
113 114 115
            if (isset($page['external'])) {
                return true;
            }
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
            $resource = 'route' . $path;

            return $this->acl->isAllowed($this->currentRole, $resource, 'get');
        };
        $prepare = function ($page) use (&$prepare, &$aclFilter) {

            if (isset($page['route'])) {
                $routeData    = isset($page['route_data']) ? $page['route_data'] : [];
                $query        = isset($page['query']) ? $page['query'] : [];
                $page['href'] = $this->router->pathFor($page['route'], $routeData, $query);
            }

            $path           = parse_url($page['href'], PHP_URL_PATH);
            $page['active'] = ($path !== '/' && 0 === strpos($this->request->getUri()->getPath(), $path));

            if (isset($page['pages']) && is_array($page['pages'])) {
                $page['pages'] = array_filter(array_map($prepare, $page['pages']), $aclFilter);
            }

            return $page;
        };

        return array_filter(array_map($prepare, $navigation), $aclFilter);
    }
}