Completed
Push — master ( 16692c...50a383 )
by Jean
02:47
created

DeferredCallChain::offsetGet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * DeferredCallChain
4
 *
5
 * @package php-deferred-callchain
6
 * @author  Jean Claveau
7
 */
8
namespace JClaveau\Async;
9
10
/**
11
 */
12
class DeferredCallChain implements \JsonSerializable, \ArrayAccess
13
{
14
    /** @var */
15
    protected $stack = [];
16
17
    /**
18
     */
19
    public static function new_()
20
    {
21
        return new static;
22
    }
23
24
    /**
25
     * ArrayAccess interface
26
     */
27
    public function &offsetGet($key)
28
    {
29
        $this->stack[] = [
30
            'entry' => $key,
31
        ];
32
33
        return $this;
34
    }
35
36
    /**
37
     * @param  string $method
38
     * @param  array  $arguments
39
     *
40
     * @return $this
41
     */
42
    public final function __call($method, array $arguments)
43
    {
44
        $this->stack[] = [
45
            'method'    => $method,
46
            'arguments' => $arguments,
47
        ];
48
49
        return $this;
50
    }
51
52
    /**
53
     * For implementing JsonSerializable interface.
54
     *
55
     * @see https://secure.php.net/manual/en/jsonserializable.jsonserialize.php
56
     */
57
    public function jsonSerialize()
58
    {
59
        return $this->stack;
60
    }
61
62
    /**
63
     */
64
    public function __toString()
65
    {
66
        $string = '(new ' . get_called_class() . ')';
67
68
        foreach ($this->stack as $i => $call) {
69
            if (isset($call['method'])) {
70
                $string .= '->';
71
                $string .= $call['method'].'(';
72
                $string .= implode(', ', array_map(function($argument) {
73
                    return var_export($argument, true);
74
                }, $call['arguments']));
75
                $string .= ')';
76
            }
77
            else {
78
                $string .= '[' . var_export($call['entry'], true) . ']';
79
            }
80
        }
81
82
        return $string;
83
    }
84
85
    /**
86
     * Invoking the instance produces the call of the stack
87
     */
88
    public function __invoke($target)
89
    {
90
        $out = $target;
91
        foreach ($this->stack as $i => $call) {
92
            try {
93
                if (isset($call['method'])) {
94
                    $out = call_user_func_array([$out, $call['method']], $call['arguments']);
95
                }
96
                else {
97
                    $out = $out[ $call['entry'] ];
98
                }
99
            }
100
            catch (\Exception $e) {
101
                // Throw $e with the good stack (usage exception)
102
                throw $e;
103
            }
104
        }
105
106
        return $out;
107
    }
108
109
    /**
110
     * ArrayAccess interface
111
     */
112
    public function offsetSet($offset, $value)
113
    {
114
        throw new BadMethodCallException(
0 ignored issues
show
Bug introduced by
The type JClaveau\Async\BadMethodCallException was not found. Did you mean BadMethodCallException? If so, make sure to prefix the type with \.
Loading history...
115
            "not implemented"
116
        );
117
    }
118
119
    /**
120
     * ArrayAccess interface
121
     */
122
    public function offsetExists($offset)
123
    {
124
        throw new BadMethodCallException(
125
            "not implemented"
126
        );
127
    }
128
129
    /**
130
     * ArrayAccess interface
131
     */
132
    public function offsetUnset($offset)
133
    {
134
        throw new BadMethodCallException(
135
            "not implemented"
136
        );
137
    }
138
139
    /**/
140
}
141