WebContextParamInterceptor::getParam()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 9.4285
cc 2
eloc 6
nc 2
nop 2
crap 2
1
<?php
2
/**
3
 * This file is part of the Ray.WebContextParam.
4
 *
5
 * @license http://opensource.org/licenses/bsd-license.php MIT
6
 */
7
namespace Ray\WebContextParam;
8
9
use Doctrine\Common\Annotations\Reader;
10
use Doctrine\Common\Cache\Cache;
11
use Ray\Aop\Arguments;
12
use Ray\Aop\MethodInterceptor;
13
use Ray\Aop\MethodInvocation;
14
use Ray\WebContextParam\Annotation\AbstractWebContextParam;
15
use Ray\WebContextParam\Exception\NotFoundArgumentException;
16
17
class WebContextParamInterceptor implements MethodInterceptor
18
{
19
    /**
20
     * @var Reader
21
     */
22
    private $reader;
23
24
    /**
25
     * @var Cache
26
     */
27
    private $cache;
28
29
    /**
30
     * @var
31
     */
32
    private $webContext;
33
34 7
    public function __construct(
35
        Reader $reader,
36
        Cache $cache,
37
        WebContext $webContext
38
    ) {
39 7
        $this->reader = $reader;
40 7
        $this->cache = $cache;
41 7
        $this->webContext = $webContext;
42 7
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 7
    public function invoke(MethodInvocation $invocation)
48
    {
49 7
        $method = $invocation->getMethod();
50 7
        $args = $invocation->getArguments();
51 7
        $id = __CLASS__ . $invocation->getMethod();
52 7
        $meta = $this->cache->fetch($id);
53 7
        if (! $meta) {
54 7
            $meta = $this->getMeta($method);
55 6
            $this->cache->save($id, $meta);
56 6
        }
57 6
        $parameters = $invocation->getMethod()->getParameters();
58 6
        $cnt = count($parameters);
59 6
        for ($i = 0; $i < $cnt; $i++) {
60 6
            $this->setArg($args, $meta, $i);
0 ignored issues
show
Compatibility introduced by
$args of type object<ArrayObject> is not a sub-type of object<Ray\Aop\Arguments>. It seems like you assume a child class of the class ArrayObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
Documentation introduced by
$i is of type integer, but the function expects a object<Ray\WebContextParam\in>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Unused Code introduced by
The call to the method Ray\WebContextParam\WebC...amInterceptor::setArg() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
61 6
        }
62
63 6
        return $invocation->proceed();
64
    }
65
66 7
    private function getMeta(\ReflectionMethod $method)
67
    {
68 7
        $meta = [];
69 7
        $annotations = $this->reader->getMethodAnnotations($method);
70
        /* @var $annotation AbstractWebContextParam */
71 7
        foreach ($annotations as $annotation) {
72 7
            if ($annotation instanceof AbstractWebContextParam) {
73 7
                $pos = $this->getPos($annotation, $method);
74 6
                $meta[$pos] = [$annotation::GLOBAL_KEY, $annotation->key, $annotation->default];
75 6
            }
76 6
        }
77
78 6
        return $meta;
79
    }
80
81
    /**
82
     * @param AbstractWebContextParam $annotation
83
     * @param \ReflectionMethod       $method
84
     *
85
     * @return int
86
     */
87 7
    private function getPos(AbstractWebContextParam $annotation, \ReflectionMethod $method)
88
    {
89 7
        $parameters = $method->getParameters();
90 7
        $param = $annotation->param ? $annotation->param : $annotation->key;
91 7
        foreach ($parameters as $parameter) {
92 7
            if ($parameter->name == $param) {
93 6
                $pos = $parameter->getPosition();
94
95 6
                return $pos;
96
            }
97 1
        }
98 1
        $msg = sprintf("parameter %s of method %s in %s Not Found", $param, $method->name, $method->getFileName());
99 1
        throw new NotFoundArgumentException($msg);
100
    }
101
102
    /**
103
     * @param Arguments $args
104
     * @param array     $meta
105
     * @param in        $i
106
     */
107 6
    private function setArg(Arguments $args, array $meta, $i)
108
    {
109 6
        if (isset($meta[$i]) && (! isset($args[$i]))) {
110 4
            list($hasParam, $param, $default) = $this->getParam($meta, $i);
111 4
            if ($hasParam) {
112 2
                $args[$i] = $param;
113 2
            }
114 4
            if ($default) {
115 1
                $args[$i] = $default;
116 1
            }
117 4
        }
118 6
    }
119
120
    /**
121
     * @param array $meta
122
     * @param int   $i
123
     *
124
     * @return array
125
     */
126 4
    private function getParam(array $meta, $i)
127
    {
128 4
        list($globalKey, $key, $default) = $meta[$i];
129 4
        $webContext = $this->webContext->get($globalKey);
130 4
        if (isset($webContext[$key])) {
131 2
            return [true, $webContext[$key], $default];
132
        }
133
134 2
        return [false, null, $default];
135
    }
136
}
137