GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

FunctionsMethods::after()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 20
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 20
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 1
nop 2
crap 2
1
<?php
2
declare(strict_types=1);
3
4
/*
5
 * This file is part of Underscore.php
6
 *
7
 * (c) Maxime Fabre <[email protected]>
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace Underscore\Methods;
14
15
use Closure;
16
use Exception;
17
18
/**
19
 * Methods to manage functions.
20
 */
21
class FunctionsMethods
22
{
23
24
    /**
25
     * An array of functions to be called X times.
26
     */
27
    public static array $canBeCalledTimes = [];
28
29
    /**
30
     * An array of cached function results.
31
     */
32
    public static array $cached = [];
33
34
    /**
35
     * An array tracking the last time a function was called.
36
     */
37
    public static array $throttle = [];
38
39
    ////////////////////////////////////////////////////////////////////
40
    ////////////////////////////// LIMITERS ////////////////////////////
41
    ////////////////////////////////////////////////////////////////////
42
43
    /**
44
     * Create a function that can only be called once.
45
     *
46
     * @param  callable  $function  The function
47
     *
48
     * @return Closure
49
     * @throws Exception
50
     */
51
    public static function once(callable $function) : callable
52
    {
53
        return static::only($function, 1);
54 1
    }
55
56 1
    /**
57
     * Create a function that can only be called $times times.
58
     *
59
     * @param  int  $canBeCalledTimes  $times    The number of times
60
     *
61
     * @return Closure
62
     * @throws Exception
63
     */
64
    public static function only(callable $function, int $canBeCalledTimes) : callable
65
    {
66
        $unique = random_int(0, mt_getrandmax());
67 2
68
        // Create a closure that check if the function was already called
69 2
        return function (...$arguments) use ($function, $canBeCalledTimes, $unique) {
70
71
            $signature = FunctionsMethods::getSignature((string) $unique, $function, $arguments);
72
73
            // Get counter
74
            $numberOfTimesCalled = FunctionsMethods::hasBeenCalledTimes($signature);
75 2
76 2
            // If the function has been called too many times, cancel
77
            // Else, increment the count
78
            if ($numberOfTimesCalled >= $canBeCalledTimes) {
79 2
                return false;
80
            }
81
82
            ++FunctionsMethods::$canBeCalledTimes[$signature];
83 2
84 2
            return \call_user_func_array($function, $arguments);
85
        };
86
    }
87 2
88
    /**
89 2
     * Create a function that can only be called after $times times.
90 2
     *
91
     *
92
     * @return Closure
93
     * @throws Exception
94
     */
95
    public static function after(callable $function, int $times) : callable
96
    {
97
        $unique = random_int(0, mt_getrandmax());
98
99
        // Create a closure that check if the function was already called
100
        return function (...$arguments) use ($function, $times, $unique) {
101 1
102
            $signature = FunctionsMethods::getSignature((string) $unique, $function, $arguments);
103 1
104
            // Get counter
105
            $called = FunctionsMethods::hasBeenCalledTimes($signature);
106
107
            // Prevent calling before a certain number
108
            if ($called < $times) {
109 1
                ++FunctionsMethods::$canBeCalledTimes[$signature];
110 1
111
                return false;
112
            }
113 1
114
            return \call_user_func_array($function, $arguments);
115
        };
116 1
    }
117 1
118
    /**
119 1
     * Caches the result of a function and refer to it ever after.
120
     *
121
     *
122 1
     * @return Closure
123 1
     * @throws Exception
124
     */
125
    public static function cache(callable $function) : callable
126
    {
127
        $unique = random_int(0, mt_getrandmax());
128
129
        return function (...$arguments) use ($function, $unique) {
130
131
            $signature = FunctionsMethods::getSignature((string) $unique, $function, $arguments);
132
133 1
            if (isset(FunctionsMethods::$cached[$signature])) {
134
                return FunctionsMethods::$cached[$signature];
135 1
            }
136
137
            $result                               = \call_user_func_array($function, $arguments);
138
            FunctionsMethods::$cached[$signature] = $result;
139
140 1
            return $result;
141 1
        };
142
    }
143 1
144 1
    /**
145
     * Only allow a function to be called every X ms.
146
     *
147 1
     *
148 1
     * @return Closure
149
     * @throws Exception
150 1
     */
151 1
    public static function throttle(callable $function, int $ms) : callable
152
    {
153
        $unique = random_int(0, mt_getrandmax());
154
155
        return function (...$arguments) use ($function, $ms, $unique) {
156
157
            $signature = FunctionsMethods::getSignature((string) $unique, $function, $arguments);
158
159
            // Check last called time and update it if necessary
160
            $last       = FunctionsMethods::getLastCalledTime($signature);
161
            $difference = time() - $last;
162 1
163
            // Execute the function if the conditions are here
164 1
            if ($last === time() || $difference > $ms) {
165
                FunctionsMethods::$throttle[$signature] = time();
166
167
                return \call_user_func_array($function, $arguments);
168
            }
169 1
170 1
            return false;
171
        };
172
    }
173 1
174 1
    /**
175
     * Prefill function arguments.
176
     *
177 1
     * @return Closure
178 1
     * @author Jeremy Ashkenas
179
     */
180 1
    public static function partial(callable $func) : callable
181
    {
182
        $boundArgs = \array_slice(\func_get_args(), 1);
183 1
184 1
        return function(...$calledArgs) use ($boundArgs, $func) {
185
            $args       = [];
186
            $position   = 0;
187
188
            foreach ($boundArgs as $iValue) {
189
                $args[] = $iValue ?? $calledArgs[$position++];
190
            }
191
192
            return \call_user_func_array($func, array_merge($args, \array_slice($calledArgs, $position)));
193
        };
194
    }
195
196 1
    ////////////////////////////////////////////////////////////////////
197
    ////////////////////////////// HELPERS /////////////////////////////
198 1
    ////////////////////////////////////////////////////////////////////
199
    /**
200
     * Get the last time a function was called.
201 1
     *
202 1
     * @param  string  $unique  The function unique ID
203 1
     */
204
    public static function getLastCalledTime(string $unique) : int
205 1
    {
206 1
        return ArraysMethods::setAndGet(static::$canBeCalledTimes, $unique, time());
207
    }
208
209 1
    /**
210 1
     * Get the number of times a function has been called.
211
     *
212
     * @param  string  $unique  The function unique ID
213
     */
214
    public static function hasBeenCalledTimes(string $unique) : int
215
    {
216
        return ArraysMethods::setAndGet(static::$canBeCalledTimes, $unique, 0);
217
    }
218
219
    /**
220
     * Get a function's signature.
221
     *
222
     * @param         $unique
223
     * @param  Closure  $function  The function
224 1
     * @param  array  $arguments  Its arguments
225
     *
226 1
     * @return string The unique id
227
     */
228
    public static function getSignature(string $unique, Closure $function, array $arguments) : string
229
    {
230
        $function  = var_export($function, true);
231
        $argumentsStr = var_export($arguments, true);
232
233
        return md5($unique.'_'.$function.'_'.$argumentsStr);
234
    }
235
}
236