Completed
Push — master ( b24ad0...a8933b )
by Woody
02:02
created

Functions::p()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 11
ccs 7
cts 7
cp 1
rs 9.4285
cc 2
eloc 6
nc 2
nop 0
crap 2
1
<?php
2
3
namespace Underscore;
4
5
class Functions
6
{
7
    /**
8
     * Creates a function that memoizes the result of the $payload
9
     *
10
     * @param callable $payload
11
     *
12
     * @return \Closure
13
     */
14 1
    public static function memoize($payload)
15
    {
16
        $function = function () use ($payload) {
17 1
            static $cache = [];
18 1
            $args = func_get_args();
19 1
            $hash = md5(serialize($args));
20
21 1
            if (!array_key_exists($hash, $cache)) {
22 1
                $cache[$hash] = call_user_func_array($payload, $args);
23 1
            }
24
25 1
            return $cache[$hash];
26 1
        };
27
28 1
        return $function;
29
    }
30
31
    /**
32
     * Creates function that simply returns given argument
33
     *
34
     * @return \Closure
35
     */
36 2
    public static function nop()
37
    {
38
        return function ($item) {
39 2
            return $item;
40 2
        };
41
    }
42
43
    /**
44
     * Creates a version of the function that can only be called one time.
45
     *
46
     * Repeated calls to the modified function will have no effect, returning
47
     * the value from the original call. Useful for initialization functions,
48
     * instead of having to set a boolean flag and then check it later.
49
     *
50
     * @param callable $function
51
     * @return \Closure
52
     */
53 1
    public static function once($function)
54
    {
55 1
        $called = false;
56 1
        $value = null;
57
58
        return function () use ($function, &$called, &$value) {
59 1
            if (!$called) {
60 1
                $args = func_get_args();
61 1
                $value = call_user_func_array($function, $args);
62 1
                $called = true;
63 1
            }
64
65 1
            return $value;
66 1
        };
67
    }
68
69
    /**
70
     * Provides a constant value that is only used for partial().
71
     *
72
     * @return \Closure
73
     */
74 1
    public static function p()
75
    {
76 1
        static $function;
77 1
        if (!$function) {
78
            $function = function () {
79 1
                return 'placeholder for partial';
80 1
            };
81 1
        }
82
83 1
        return $function;
84
    }
85
86
    /**
87
     * Partially apply a function by filling in any number of its arguments.
88
     *
89
     * You may pass p() in your list of arguments to specify an argument that
90
     * should not be pre-filled, but left open to supply at call-time.
91
     *
92
     * @param callable $function
93
     * @param mixed    $arg
94
     * @param          mixed ...
95
     * @return \Closure
96
     */
97 1
    public static function partial($function, $arg)
0 ignored issues
show
Unused Code introduced by
The parameter $arg is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
98
    {
99 1
        $bound = func_get_args();
100 1
        array_shift($bound); // remove $function
101
102 1
        $placeholder = static::p();
103
104
        return function () use ($function, $bound, $placeholder) {
105 1
            $inject = func_get_args();
106
107 1
            $args = [];
108 1
            foreach ($bound as $value) {
109 1
                if ($value === $placeholder) {
110 1
                    $args[] = array_shift($inject);
111 1
                } else {
112 1
                    $args[] = $value;
113
                }
114 1
            }
115
116
            // Append any remaining arguments
117 1
            $args = array_merge($args, $inject);
118
119 1
            return call_user_func_array($function, $args);
120 1
        };
121
    }
122
123
    /**
124
     * Returns the composition of a list of functions.
125
     *
126
     * Each function consumes the return value of the function that follows.
127
     * In math terms, composing the functions f(), g(), and h() produces f(g(h())).
128
     *
129
     * @param callable $function
130
     * @param          callable ...
131
     * @return \Closure
132
     */
133 1
    public static function compose($function)
0 ignored issues
show
Unused Code introduced by
The parameter $function is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
134
    {
135 1
        $functions = array_reverse(func_get_args());
136
137
        return function ($value) use ($functions) {
138 1
            foreach ($functions as $function) {
139 1
                $value = $function($value);
140 1
            }
141
142 1
            return $value;
143 1
        };
144
    }
145
146
    /**
147
     * Wraps the first function inside of the wrapper function, passing it as the first argument.
148
     *
149
     * This allows the wrapper to execute code before and after the function runs,
150
     * adjust the arguments, and execute it conditionally.
151
     *
152
     * @param callable $function
153
     * @param callable $wrapper
154
     * @return \Closure
155
     */
156 1
    public static function wrap($function, $wrapper)
157
    {
158
        return function () use ($function, $wrapper) {
159 1
            $args = func_get_args();
160 1
            array_unshift($args, $function); // make $function the first argument
161 1
            return call_user_func_array($wrapper, $args);
162 1
        };
163
    }
164
165
    /**
166
     * Creates and returns a new, throttled version of the passed function.
167
     *
168
     * When invoked repeatedly, will only actually call the original function at
169
     * most once per every wait milliseconds. Useful for rate-limiting events that
170
     * occur faster than you can keep up with.
171
     *
172
     * By default, throttle will execute the function as soon as you call it
173
     * for the first time, and, if you call it again any number of times during
174
     * the wait period, as soon as that period is over. If you'd like to disable
175
     * the leading-edge call, pass `leading => false`.
176
     *
177
     * NOTE: Does not support the `trailing` option because there is no timeout
178
     * functionality in PHP (without using threads).
179
     *
180
     * NOTE: No arguments are passed to the function on the leading edge call!
181
     *
182
     * @param callable $function
183
     * @param integer  $wait
184
     * @param array    $options
185
     * @return \Closure
186
     */
187 1
    public static function throttle($function, $wait, array $options = [])
188
    {
189
        $options += [
190 1
            'leading' => true,
191
        ]; // @codeCoverageIgnore
192
193 1
        $previous = 0;
194
195
        $callback = function () use ($function, $wait, &$previous) {
196 1
            $now = floor(microtime(true) * 1000); // convert float to integer
197
198 1
            if (($wait - ($now - $previous)) <= 0) {
199 1
                $args = func_get_args();
200 1
                call_user_func_array($function, $args);
201 1
                $previous = $now;
202 1
            }
203 1
        };
204
205 1
        if ($options['leading'] !== false) {
206 1
            $callback();
207 1
        }
208
209 1
        return $callback;
210
    }
211
212
    /**
213
     * Creates a version of the function that will only be run after first being called count times.
214
     *
215
     * Useful for grouping asynchronous responses, where you want to be sure that
216
     * all the async calls have finished, before proceeding.
217
     *
218
     * @param integer  $count
219
     * @param callable $function
220
     * @return \Closure
221
     */
222 1
    public static function after($count, $function)
223
    {
224
        return function () use ($function, &$count) {
225 1
            if (--$count < 1) {
226 1
                $args = func_get_args();
227
228 1
                return call_user_func_array($function, $args);
229
            }
230 1
        };
231
    }
232
233
    /**
234
     * Creates a version of the function that can be called no more than count times.
235
     *
236
     * The result of the last function call is memoized and returned when count has been reached.
237
     *
238
     * @param integer  $count
239
     * @param callable $function
240
     * @return \Closure
241
     */
242 1
    public static function before($count, $function)
243
    {
244 1
        $memo = null;
245
246 1
        return function () use ($function, &$count, &$memo) {
247 1
            if (--$count > 0) {
248 1
                $args = func_get_args();
249 1
                $memo = call_user_func_array($function, $args);
250 1
            }
251
252 1
            return $memo;
253 1
        };
254
    }
255
}
256