Completed
Push — develop ( e653e2...0197dd )
by
unknown
06:51
created

HelperProxy::doStackedCalls()   C

Complexity

Conditions 8
Paths 27

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 30
rs 5.3846
cc 8
eloc 17
nc 27
nop 3
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license MIT
7
 * @copyright  2013 - 2017 Cross Solution <http://cross-solution.de>
8
 */
9
  
10
/** */
11
namespace Core\View\Helper\Proxy;
12
13
use Zend\View\Helper\AbstractHelper;
14
15
/**
16
 * Proxies to a view helper which may or may not exists.
17
 *
18
 * @author Mathias Gelhausen <[email protected]>
19
 * @since 0.29
20
 */
21
class HelperProxy 
22
{
23
    /**#@+
24
     * Special expected result types.
25
     * @var string
26
     */
27
    const EXPECT_SELF = '__SELF__';
28
    const EXPECT_ARRAY = '__ARRAY__';
29
    const EXPECT_ITERATOR = '__ITERATOR__';
30
    /**#@-*/
31
32
    /**
33
     * The helper instance.
34
     *
35
     * @var false|AbstractHelper
36
     */
37
    private $helper;
38
39
    /**
40
     * @param false|AbstractHelper $helper
41
     */
42
    public function __construct($helper)
43
    {
44
        $this->helper = $helper;
45
    }
46
47
    /**
48
     * Proxy invokation to the helper.
49
     *
50
     * @return mixed
51
     */
52
    public function __invoke()
53
    {
54
        $args = func_get_args();
55
56
        return $this->call('__invoke', $args);
57
    }
58
59
    /**
60
     * Proxy all methods calls to the helper.
61
     *
62
     * @param $method
63
     * @param $args
64
     *
65
     * @return self
66
     */
67
    public function __call($method, $args)
68
    {
69
        return $this->call($method, $args);
70
    }
71
72
    /**
73
     * Get the helper instance.
74
     *
75
     * @return false|AbstractHelper
76
     */
77
    public function helper()
78
    {
79
        return $this->helper;
80
    }
81
82
    /**
83
     * Call a method on the proxied plugin.
84
     *
85
     * If a helper instance exists, the returned value from the method call is returned,
86
     * otherwise the $expect value is returned,
87
     *
88
     * If the $args is no array, it is used as $expect.
89
     *
90
     * If you need to expect an array, you must pass in an empty array for $args and
91
     * specify your expected array in the $expect variable, however if you expect an
92
     * empty array, you can pass {@link EXPECT_ARRAY}.
93
     *
94
     * @param string $method
95
     * @param array|mixed  $args
96
     * @param mixed $expect
97
     *
98
     * @return mixed
99
     */
100
    public function call($method, $args = [], $expect = self::EXPECT_SELF)
101
    {
102
        if (!is_array($args)) {
103
            $expect = $args;
104
            $args   = [];
105
        }
106
107
        if (!$this->helper) {
108
            return $this->expected($expect);
109
        }
110
111
        return call_user_func_array([$this->helper, $method], $args);
112
    }
113
114
    /**
115
     * Call consecutive methods on this proxied helper.
116
     *
117
     * This means, every specified method is called on this
118
     * proxy instance (which proxies further to the helper)
119
     * and this proxy is returned.
120
     *
121
     * If no helper instance exists, this is a noop and this proxy instance is returned.
122
     *
123
     * <pre>
124
     * $methods = [
125
     *      'methodName',                   // <=> 'methodName' => []
126
     *      'methodName' => [arguments,...],
127
     *      ['invokeArg',...]               // omitting method name, but provide arguments will call "__invoke"
128
     * ];
129
     * </pre>
130
     *
131
     * @param array $methods
132
     *
133
     * @return self
134
     */
135
    public function consecutive($methods)
136
    {
137
        return $this->doStackedCalls($methods, self::EXPECT_SELF, 'consecutive');
138
    }
139
140
    /**
141
     * Chain method calls on this proxied helper.
142
     *
143
     * This means, every method in the stack is called on
144
     * the return value ofthe previous method and the returned value
145
     * from the last method is returned.
146
     *
147
     * If no helper instance exists, the $expect value is returned.
148
     *
149
     * <pre>
150
     * $stack = [
151
     *      'methodName',                   // <=> 'methodName' => []
152
     *      'methodName' => [arguments,...]
153
     *      ['invokeArg',...]               // omitting method name but provide arguments, will call "__invoke"
154
     * ];
155
     * </pre>
156
     *
157
     * @param array $methods
158
     * @param mixed $expect
159
     *
160
     * @return mixed
161
     */
162
    public function chain($methods, $expect = self::EXPECT_SELF)
163
    {
164
        return $this->doStackedCalls($methods, $expect, 'chain');
165
    }
166
167
    private function doStackedCalls($methods, $expect, $mode)
168
    {
169
        if (!$this->helper) {
170
            return $this->expected($expect);
171
        }
172
173
        $plugin = $result = $this->helper;
174
        foreach ($methods as $method => $args) {
175
            if (is_numeric($method)) {
176
                if (is_array($args)) {
177
                    $method = '__invoke';
178
                } else {
179
                    $method = $args;
180
                    $args   = [];
181
                }
182
            }
183
184
            if (!is_array($args)) {
185
                $args = [$args];
186
            }
187
188
            $result = call_user_func_array([$plugin, $method], $args);
189
190
            if ('chain' == $mode) {
191
                $plugin = $result;
192
            }
193
        }
194
195
        return 'consecutive' == $mode ? $this : $result;
196
    }
197
198
    private function expected($expect)
199
    {
200
        if (self::EXPECT_SELF == $expect) {
201
            return $this;
202
        }
203
204
        if (self::EXPECT_ARRAY == $expect) {
205
            return [];
206
        }
207
208
        if (self::EXPECT_ITERATOR == $expect) {
209
            return new \ArrayIterator();
210
        }
211
212
        return $expect;
213
    }
214
}