Completed
Branch 1.x (2c7718)
by Akihito
01:38
created

EmbedInterceptor::invoke()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2.004

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 9
cts 10
cp 0.9
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 10
nc 2
nop 1
crap 2.004
1
<?php
2
/**
3
 * This file is part of the BEAR.Resource package.
4
 *
5
 * @license http://opensource.org/licenses/MIT MIT
6
 */
7
namespace BEAR\Resource;
8
9
use BEAR\Resource\Annotation\Embed;
10
use BEAR\Resource\Exception\BadRequestException;
11
use BEAR\Resource\Exception\EmbedException;
12
use Doctrine\Common\Annotations\Reader;
13
use Ray\Aop\MethodInterceptor;
14
use Ray\Aop\MethodInvocation;
15
16
final class EmbedInterceptor implements MethodInterceptor
17
{
18
    /**
19
     * @var \BEAR\Resource\ResourceInterface
20
     */
21
    private $resource;
22
23
    /**
24
     * @var Reader
25
     */
26
    private $reader;
27
28
    /**
29
     * @param ResourceInterface $resource
30
     * @param Reader            $reader
31
     */
32 9
    public function __construct(ResourceInterface $resource, Reader $reader)
33
    {
34 9
        $this->resource = clone $resource;
35 9
        $this->reader = $reader;
36 9
    }
37
38
    /**
39
     * {@inheritdoc}
40
     *
41
     * @throws \BEAR\Resource\Exception\EmbedException
42
     */
43 9
    public function invoke(MethodInvocation $invocation)
44
    {
45 9
        $resourceObject = $invocation->getThis();
46 9
        if (! $resourceObject instanceof ResourceObject) {
47
            throw new EmbedException(get_class($resourceObject));
48
        }
49 9
        $method = $invocation->getMethod();
50 9
        $query = $this->getArgsByInvocation($invocation);
51 9
        $embeds = $this->reader->getMethodAnnotations($method);
52
        // embedding resource
53 9
        $this->embedResource($embeds, $resourceObject, $query);
54
        // request (method can modify embedded resource)
55 7
        $result = $invocation->proceed();
56
57 7
        return $result;
58
    }
59
60
    /**
61
     * @param Embed[]        $embeds
62
     * @param ResourceObject $resourceObject
63
     * @param array          $query
64
     *
65
     * @throws EmbedException
66
     */
67 9
    private function embedResource(array $embeds, ResourceObject $resourceObject, array $query)
68
    {
69 9
        foreach ($embeds as $embed) {
70
            /* @var $embed Embed */
71 9
            if (! $embed instanceof Embed) {
72 5
                continue;
73
            }
74
            try {
75 9
                $templateUri = $this->getFullUri($embed->src, $resourceObject);
76 9
                $uri = uri_template($templateUri, $query);
77 9
                $resourceObject->body[$embed->rel] = clone $this->resource->get->uri($uri);
78 2
            } catch (BadRequestException $e) {
79
                // wrap ResourceNotFound or Uri exception
80 9
                throw new EmbedException($embed->src, 500, $e);
81
            }
82
        }
83 7
    }
84
85 9
    private function getFullUri(string $uri, ResourceObject $resourceObject) : string
86
    {
87 9
        if ($uri[0] === '/') {
88 1
            $uri = "{$resourceObject->uri->scheme}://{$resourceObject->uri->host}" . $uri;
89
        }
90
91 9
        return $uri;
92
    }
93
94 9
    private function getArgsByInvocation(MethodInvocation $invocation) : array
95
    {
96 9
        $args = $invocation->getArguments()->getArrayCopy();
97 9
        $params = $invocation->getMethod()->getParameters();
98 9
        $namedParameters = [];
99 9
        foreach ($params as $param) {
100 9
            $namedParameters[$param->name] = array_shift($args);
101
        }
102
103 9
        return $namedParameters;
104
    }
105
}
106