Completed
Push — master ( f12285...016462 )
by Anton
09:53 queued 07:39
created

Vault::callAction()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

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