Passed
Push — master ( 371fc8...7c0cfc )
by Anton
03:02
created

CycleInterceptor::getDeclaredEntities()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 25
rs 9.2222
cc 6
nc 6
nop 2
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
declare(strict_types=1);
9
10
namespace Spiral\Domain;
11
12
use Cycle\ORM\ORMInterface;
13
use Spiral\Core\CoreInterceptorInterface;
14
use Spiral\Core\CoreInterface;
15
use Spiral\Core\Exception\ControllerException;
16
17
/**
18
 * Automatically resolves cycle entities based on given parameter.
19
 */
20
final class CycleInterceptor implements CoreInterceptorInterface
21
{
22
    /** @var ORMInterface */
23
    private $orm;
24
25
    /** @var array */
26
    private $entityCache = [];
27
28
    /**
29
     * @param ORMInterface $orm
30
     */
31
    public function __construct(ORMInterface $orm)
32
    {
33
        $this->orm = $orm;
34
    }
35
36
    /**
37
     * @inheritDoc
38
     */
39
    public function process(string $controller, string $action, array $parameters, CoreInterface $core)
40
    {
41
        // todo: support singular ID
42
        foreach ($this->getDeclaredEntities($controller, $action) as $parameter => $role) {
43
            if (!isset($parameters[$parameter])) {
44
                throw new ControllerException(
45
                    "Entity `{$role}` can not be found",
46
                    ControllerException::NOT_FOUND
47
                );
48
            }
49
50
            $entity = $this->orm->getRepository($role)->findByPK($parameters[$parameter]);
51
            if ($entity === null) {
52
                throw new ControllerException(
53
                    "Entity `{$role}` can not be found",
54
                    ControllerException::NOT_FOUND
55
                );
56
            }
57
58
            $parameters[$parameter] = $entity;
59
        }
60
61
        return $core->callAction($controller, $action, $parameters);
62
    }
63
64
    /**
65
     * @param string $controller
66
     * @param string $action
67
     * @return array
68
     */
69
    private function getDeclaredEntities(string $controller, string $action): array
70
    {
71
        $key = sprintf("%s:%s", $controller, $action);
72
        if (array_key_exists($key, $this->entityCache)) {
73
            return $this->entityCache[$key];
74
        }
75
76
        $this->entityCache[$key] = [];
77
        try {
78
            $method = new \ReflectionMethod($controller, $action);
79
        } catch (\ReflectionException $e) {
80
            return [];
81
        }
82
83
        foreach ($method->getParameters() as $parameter) {
84
            if ($parameter->getClass() === null) {
85
                continue;
86
            }
87
88
            if ($this->orm->getSchema()->defines($parameter->getClass()->getName())) {
89
                $this->entityCache[$key][$parameter->getName()] = $parameter->getClass()->getName();
90
            }
91
        }
92
93
        return $this->entityCache[$key];
94
    }
95
}