Passed
Push — master ( f9ddfc...58c2fa )
by Jean
02:06
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(
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