Completed
Push — master ( ca7ebd...ffd42a )
by Nikolas
03:40
created

Executor::execute()   C

Complexity

Conditions 7
Paths 15

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 31
rs 6.7272
cc 7
eloc 19
nc 15
nop 1
1
<?php
2
namespace rtens\domin;
3
4
use rtens\domin\delivery\FieldRegistry;
5
use rtens\domin\delivery\ParameterReader;
6
use rtens\domin\execution\access\AccessControl;
7
use rtens\domin\execution\ExecutionResult;
8
use rtens\domin\execution\FailedResult;
9
use rtens\domin\execution\MissingParametersResult;
10
use rtens\domin\execution\NoResult;
11
use rtens\domin\execution\NotPermittedResult;
12
use rtens\domin\execution\ValueResult;
13
14
class Executor {
15
16
    /** @var ActionRegistry */
17
    private $actions;
18
19
    /** @var FieldRegistry */
20
    private $fields;
21
22
    /** @var ParameterReader */
23
    private $paramReader;
24
25
    /** @var AccessControl */
26
    private $access;
27
28
    public function __construct(ActionRegistry $actions, FieldRegistry $fields, ParameterReader $reader, AccessControl $access) {
29
        $this->actions = $actions;
30
        $this->fields = $fields;
31
        $this->paramReader = $reader;
32
        $this->access = $access;
33
    }
34
35
    /**
36
     * @param $id
37
     * @return ExecutionResult
38
     */
39
    public function execute($id) {
40
        if (!$this->access->isPermitted($id)) {
41
            return new NotPermittedResult();
42
        }
43
44
        try {
45
            $action = $this->actions->getAction($id);
46
47
            list($params, $missing) = $this->readParameters($action);
48
49
            if (!empty($missing)) {
50
                return new MissingParametersResult($missing);
51
            }
52
53
            if (!$this->access->isExecutionPermitted($id, $params)) {
54
                return new NotPermittedResult();
55
            }
56
57
            $returned = $action->execute($params);
58
59
            if (is_null($returned)) {
60
                return new NoResult();
61
            } else if ($returned instanceof ExecutionResult) {
62
                return $returned;
63
            } else {
64
                return new ValueResult($returned);
65
            }
66
        } catch (\Exception $e) {
67
            return new FailedResult($e);
68
        }
69
    }
70
71
    private function readParameters(Action $action) {
72
        $failed = [];
73
        $params = [];
74
        foreach ($action->parameters() as $parameter) {
75
            try {
76
                $params[$parameter->getName()] = $this->inflate($parameter);
77
            } catch (\Exception $e) {
78
                $failed[$parameter->getName()] = $e;
79
            }
80
        }
81
82
        return [$params, $failed];
83
    }
84
85
    private function inflate(Parameter $parameter) {
86
        if ($this->paramReader->has($parameter)) {
87
            $inflated = $this->fields->getField($parameter)
88
                ->inflate($parameter, $this->paramReader->read($parameter));
89
90
            if ($parameter->getType()->is($inflated)) {
91
                return $inflated;
92
            }
93
        }
94
95
        if ($parameter->isRequired()) {
96
            throw new \Exception("[{$parameter->getName()}] is required.");
97
        }
98
99
        return null;
100
    }
101
}