Completed
Branch develop (51c2e3)
by Anton
03:56 queued 01:52
created

Vault::uri()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 5
nop 2
dl 0
loc 21
rs 9.0534
c 0
b 0
f 0
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
9
namespace Spiral\Vault;
10
11
use Psr\Http\Message\UriInterface;
12
use Spiral\Core\Component;
13
use Spiral\Core\Container\SingletonInterface;
14
use Spiral\Core\Exceptions\ControllerException;
15
use Spiral\Core\HMVC\CoreInterface;
16
use Spiral\Security\Traits\GuardedTrait;
17
use Spiral\Translator\Traits\TranslatorTrait;
18
use Spiral\Vault\Configs\VaultConfig;
19
use Spiral\Vault\Exceptions\VaultException;
20
21
/**
22
 * Vault Core provides ability to whitelist controllers, map their short names and aliases into
23
 * specific class and automatically check Actor permission to execute any of controller actions.
24
 */
25
class Vault extends Component implements CoreInterface, SingletonInterface
26
{
27
    use GuardedTrait, TranslatorTrait;
28
29
    /**
30
     * @var VaultConfig
31
     */
32
    private $config = null;
33
34
    /**
35
     * @var VaultRoute
36
     */
37
    private $route;
38
39
    /**
40
     * @var CoreInterface
41
     */
42
    protected $app = null;
43
44
    /**
45
     * @param VaultConfig   $config
46
     * @param VaultRoute    $route
47
     * @param CoreInterface $app User application.
48
     */
49
    public function __construct(VaultConfig $config, VaultRoute $route, CoreInterface $app)
50
    {
51
        $this->config = $config;
52
        $this->route = $route;
53
        $this->app = $app;
54
    }
55
56
    /**
57
     * @return VaultRoute
58
     */
59
    public function getRoute()
60
    {
61
        return $this->route;
62
    }
63
64
    /**
65
     * @return VaultConfig
66
     */
67
    public function getConfig(): VaultConfig
68
    {
69
        return $this->config;
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function callAction(
76
        string $controller,
77
        string $action = null,
78
        array $parameters = [],
79
        array $scope = []
80
    ) {
81
        if (!$this->config->hasController($controller)) {
82
            throw new ControllerException(
83
                "Undefined vault controller '{$controller}'",
84
                ControllerException::NOT_FOUND
85
            );
86
        }
87
88
        $actionPermission = "{$this->config->guardNamespace()}.{$controller}";
89
90
        if (!$this->getGuard()->allows($actionPermission, compact('action'))) {
91
            throw new ControllerException(
92
                "Unreachable vault controller '{$controller}'",
93
                ControllerException::FORBIDDEN
94
            );
95
        }
96
97
        //Delegate controller call to real application
98
        return $this->app->callAction(
99
            $this->config->controllerClass($controller),
100
            $action,
101
            $parameters,
102
            $scope + [Vault::class => $this]
103
        );
104
    }
105
106
    /**
107
     * Get vault specific uri.
108
     *
109
     * @param string      $target Target controller and action in a form of "controller::action" or
110
     *                            "controller:action" or "controller".
111
     * @param array|mixed $parameters
112
     *
113
     * @return UriInterface
114
     *
115
     * @throws VaultException
116
     */
117
    public function uri(string $target, $parameters = []): UriInterface
118
    {
119
        $controller = $action = '';
120
        if (strpos($target, ':') !== false) {
121
            list($controller, $action) = explode(':', $target);
122
        } else {
123
            $controller = $target;
124
125
            if (!empty($parameters)) {
126
                throw new VaultException(
127
                    "Unable to generate uri with empty controller action and not empty parameters."
128
                );
129
            }
130
        }
131
132
        if ($this->config->hasController($controller)) {
133
            throw new VaultException("Unable to generate uri, undefined controller '{$controller}'");
134
        }
135
136
        return $this->route->withDefaults(compact('controller', 'action'))->uri($parameters);
137
    }
138
}