ArrayEntryToken   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 2
dl 0
loc 123
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B scoreArgument() 0 22 7
A isLast() 0 4 1
A __toString() 0 4 1
A getKey() 0 4 1
A getValue() 0 4 1
A wrapIntoExactValueToken() 0 4 2
A convertArrayAccessToEntry() 0 14 3
1
<?php
2
3
/*
4
 * This file is part of the Prophecy.
5
 * (c) Konstantin Kudryashov <[email protected]>
6
 *     Marcello Duarte <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Prophecy\Argument\Token;
13
14
use Prophecy\Exception\InvalidArgumentException;
15
16
/**
17
 * Array entry token.
18
 *
19
 * @author Boris Mikhaylov <[email protected]>
20
 */
21
class ArrayEntryToken implements TokenInterface
22
{
23
    /** @var \Prophecy\Argument\Token\TokenInterface */
24
    private $key;
25
    /** @var \Prophecy\Argument\Token\TokenInterface */
26
    private $value;
27
28
    /**
29
     * @param mixed $key   exact value or token
30
     * @param mixed $value exact value or token
31
     */
32
    public function __construct($key, $value)
33
    {
34
        $this->key = $this->wrapIntoExactValueToken($key);
35
        $this->value = $this->wrapIntoExactValueToken($value);
36
    }
37
38
    /**
39
     * Scores half of combined scores from key and value tokens for same entry. Capped at 8.
40
     * If argument implements \ArrayAccess without \Traversable, then key token is restricted to ExactValueToken.
41
     *
42
     * @param array|\ArrayAccess|\Traversable $argument
43
     *
44
     * @throws \Prophecy\Exception\InvalidArgumentException
45
     * @return bool|int
46
     */
47
    public function scoreArgument($argument)
48
    {
49
        if ($argument instanceof \Traversable) {
50
            $argument = iterator_to_array($argument);
51
        }
52
53
        if ($argument instanceof \ArrayAccess) {
54
            $argument = $this->convertArrayAccessToEntry($argument);
55
        }
56
57
        if (!is_array($argument) || empty($argument)) {
58
            return false;
59
        }
60
61
        $keyScores = array_map(array($this->key,'scoreArgument'), array_keys($argument));
62
        $valueScores = array_map(array($this->value,'scoreArgument'), $argument);
63
        $scoreEntry = function ($value, $key) {
64
            return $value && $key ? min(8, ($key + $value) / 2) : false;
65
        };
66
67
        return max(array_map($scoreEntry, $valueScores, $keyScores));
68
    }
69
70
    /**
71
     * Returns false.
72
     *
73
     * @return boolean
74
     */
75
    public function isLast()
76
    {
77
        return false;
78
    }
79
80
    /**
81
     * Returns string representation for token.
82
     *
83
     * @return string
84
     */
85
    public function __toString()
86
    {
87
        return sprintf('[..., %s => %s, ...]', $this->key, $this->value);
88
    }
89
90
    /**
91
     * Returns key
92
     *
93
     * @return TokenInterface
94
     */
95
    public function getKey()
96
    {
97
        return $this->key;
98
    }
99
100
    /**
101
     * Returns value
102
     *
103
     * @return TokenInterface
104
     */
105
    public function getValue()
106
    {
107
        return $this->value;
108
    }
109
110
    /**
111
     * Wraps non token $value into ExactValueToken
112
     *
113
     * @param $value
114
     * @return TokenInterface
115
     */
116
    private function wrapIntoExactValueToken($value)
117
    {
118
        return $value instanceof TokenInterface ? $value : new ExactValueToken($value);
119
    }
120
121
    /**
122
     * Converts instance of \ArrayAccess to key => value array entry
123
     *
124
     * @param \ArrayAccess $object
125
     *
126
     * @return array|null
127
     * @throws \Prophecy\Exception\InvalidArgumentException
128
     */
129
    private function convertArrayAccessToEntry(\ArrayAccess $object)
130
    {
131
        if (!$this->key instanceof ExactValueToken) {
132
            throw new InvalidArgumentException(sprintf(
133
                'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL.
134
                'But you used `%s`.',
135
                $this->key
136
            ));
137
        }
138
139
        $key = $this->key->getValue();
140
141
        return $object->offsetExists($key) ? array($key => $object[$key]) : array();
142
    }
143
}
144