• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stripe / stripe-php / 6471862601

10 Oct 2023 04:02PM UTC coverage: 69.665% (-0.5%) from 70.141%
6471862601

push

github

web-flow
Merge pull request #1570 from localheinz/feature/coveralls

Enhancement: Use `coverallsapp/github-action` to report code coverage

2393 of 3435 relevant lines covered (69.67%)

3.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.35
/lib/Util/Util.php
1
<?php
2

3
namespace Stripe\Util;
4

5
use Stripe\StripeObject;
6

7
abstract class Util
8
{
9
    private static $isMbstringAvailable = null;
10
    private static $isHashEqualsAvailable = null;
11

12
    /**
13
     * Whether the provided array (or other) is a list rather than a dictionary.
14
     * A list is defined as an array for which all the keys are consecutive
15
     * integers starting at 0. Empty arrays are considered to be lists.
16
     *
17
     * @param array|mixed $array
18
     *
19
     * @return bool true if the given object is a list
20
     */
21
    public static function isList($array)
5✔
22
    {
23
        if (!\is_array($array)) {
5✔
24
            return false;
4✔
25
        }
26
        if ([] === $array) {
5✔
27
            return true;
1✔
28
        }
29
        if (\array_keys($array) !== \range(0, \count($array) - 1)) {
5✔
30
            return false;
5✔
31
        }
32

33
        return true;
3✔
34
    }
35

36
    /**
37
     * Converts a response from the Stripe API to the corresponding PHP object.
38
     *
39
     * @param array $resp the response from the Stripe API
40
     * @param array $opts
41
     *
42
     * @return array|StripeObject
43
     */
44
    public static function convertToStripeObject($resp, $opts)
2✔
45
    {
46
        $types = \Stripe\Util\ObjectTypes::mapping;
2✔
47
        if (self::isList($resp)) {
2✔
48
            $mapped = [];
×
49
            foreach ($resp as $i) {
×
50
                $mapped[] = self::convertToStripeObject($i, $opts);
×
51
            }
52

53
            return $mapped;
×
54
        }
55
        if (\is_array($resp)) {
2✔
56
            if (isset($resp['object']) && \is_string($resp['object']) && isset($types[$resp['object']])) {
2✔
57
                $class = $types[$resp['object']];
2✔
58
            } else {
59
                $class = \Stripe\StripeObject::class;
×
60
            }
61

62
            return $class::constructFrom($resp, $opts);
2✔
63
        }
64

65
        return $resp;
2✔
66
    }
67

68
    /**
69
     * @param mixed|string $value a string to UTF8-encode
70
     *
71
     * @return mixed|string the UTF8-encoded string, or the object passed in if
72
     *    it wasn't a string
73
     */
74
    public static function utf8($value)
1✔
75
    {
76
        if (null === self::$isMbstringAvailable) {
1✔
77
            self::$isMbstringAvailable = \function_exists('mb_detect_encoding') && \function_exists('mb_convert_encoding');
×
78

79
            if (!self::$isMbstringAvailable) {
×
80
                \trigger_error('It looks like the mbstring extension is not enabled. ' .
×
81
                    'UTF-8 strings will not properly be encoded. Ask your system ' .
×
82
                    'administrator to enable the mbstring extension, or write to ' .
×
83
                    'support@stripe.com if you have any questions.', \E_USER_WARNING);
×
84
            }
85
        }
86

87
        if (\is_string($value) && self::$isMbstringAvailable && 'UTF-8' !== \mb_detect_encoding($value, 'UTF-8', true)) {
1✔
88
            return mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1');
1✔
89
        }
90

91
        return $value;
1✔
92
    }
93

94
    /**
95
     * Compares two strings for equality. The time taken is independent of the
96
     * number of characters that match.
97
     *
98
     * @param string $a one of the strings to compare
99
     * @param string $b the other string to compare
100
     *
101
     * @return bool true if the strings are equal, false otherwise
102
     */
103
    public static function secureCompare($a, $b)
×
104
    {
105
        if (null === self::$isHashEqualsAvailable) {
×
106
            self::$isHashEqualsAvailable = \function_exists('hash_equals');
×
107
        }
108

109
        if (self::$isHashEqualsAvailable) {
×
110
            return \hash_equals($a, $b);
×
111
        }
112
        if (\strlen($a) !== \strlen($b)) {
×
113
            return false;
×
114
        }
115

116
        $result = 0;
×
117
        for ($i = 0; $i < \strlen($a); ++$i) {
×
118
            $result |= \ord($a[$i]) ^ \ord($b[$i]);
×
119
        }
120

121
        return 0 === $result;
×
122
    }
123

124
    /**
125
     * Recursively goes through an array of parameters. If a parameter is an instance of
126
     * ApiResource, then it is replaced by the resource's ID.
127
     * Also clears out null values.
128
     *
129
     * @param mixed $h
130
     *
131
     * @return mixed
132
     */
133
    public static function objectsToIds($h)
1✔
134
    {
135
        if ($h instanceof \Stripe\ApiResource) {
1✔
136
            return $h->id;
1✔
137
        }
138
        if (static::isList($h)) {
1✔
139
            $results = [];
×
140
            foreach ($h as $v) {
×
141
                $results[] = static::objectsToIds($v);
×
142
            }
143

144
            return $results;
×
145
        }
146
        if (\is_array($h)) {
1✔
147
            $results = [];
1✔
148
            foreach ($h as $k => $v) {
1✔
149
                if (null === $v) {
1✔
150
                    continue;
1✔
151
                }
152
                $results[$k] = static::objectsToIds($v);
1✔
153
            }
154

155
            return $results;
1✔
156
        }
157

158
        return $h;
1✔
159
    }
160

161
    /**
162
     * @param array $params
163
     *
164
     * @return string
165
     */
166
    public static function encodeParameters($params)
1✔
167
    {
168
        $flattenedParams = self::flattenParams($params);
1✔
169
        $pieces = [];
1✔
170
        foreach ($flattenedParams as $param) {
1✔
171
            list($k, $v) = $param;
1✔
172
            $pieces[] = self::urlEncode($k) . '=' . self::urlEncode($v);
1✔
173
        }
174

175
        return \implode('&', $pieces);
1✔
176
    }
177

178
    /**
179
     * @param array $params
180
     * @param null|string $parentKey
181
     *
182
     * @return array
183
     */
184
    public static function flattenParams($params, $parentKey = null)
2✔
185
    {
186
        $result = [];
2✔
187

188
        foreach ($params as $key => $value) {
2✔
189
            $calculatedKey = $parentKey ? "{$parentKey}[{$key}]" : $key;
2✔
190

191
            if (self::isList($value)) {
2✔
192
                $result = \array_merge($result, self::flattenParamsList($value, $calculatedKey));
2✔
193
            } elseif (\is_array($value)) {
2✔
194
                $result = \array_merge($result, self::flattenParams($value, $calculatedKey));
2✔
195
            } else {
196
                \array_push($result, [$calculatedKey, $value]);
2✔
197
            }
198
        }
199

200
        return $result;
2✔
201
    }
202

203
    /**
204
     * @param array $value
205
     * @param string $calculatedKey
206
     *
207
     * @return array
208
     */
209
    public static function flattenParamsList($value, $calculatedKey)
2✔
210
    {
211
        $result = [];
2✔
212

213
        foreach ($value as $i => $elem) {
2✔
214
            if (self::isList($elem)) {
2✔
215
                $result = \array_merge($result, self::flattenParamsList($elem, $calculatedKey));
×
216
            } elseif (\is_array($elem)) {
2✔
217
                $result = \array_merge($result, self::flattenParams($elem, "{$calculatedKey}[{$i}]"));
1✔
218
            } else {
219
                \array_push($result, ["{$calculatedKey}[{$i}]", $elem]);
2✔
220
            }
221
        }
222

223
        return $result;
2✔
224
    }
225

226
    /**
227
     * @param string $key a string to URL-encode
228
     *
229
     * @return string the URL-encoded string
230
     */
231
    public static function urlEncode($key)
2✔
232
    {
233
        $s = \urlencode((string) $key);
2✔
234

235
        // Don't use strict form encoding by changing the square bracket control
236
        // characters back to their literals. This is fine by the server, and
237
        // makes these parameter strings easier to read.
238
        $s = \str_replace('%5B', '[', $s);
2✔
239

240
        return \str_replace('%5D', ']', $s);
2✔
241
    }
242

243
    public static function normalizeId($id)
2✔
244
    {
245
        if (\is_array($id)) {
2✔
246
            $params = $id;
×
247
            $id = $params['id'];
×
248
            unset($params['id']);
×
249
        } else {
250
            $params = [];
2✔
251
        }
252

253
        return [$id, $params];
2✔
254
    }
255

256
    /**
257
     * Returns UNIX timestamp in milliseconds.
258
     *
259
     * @return int current time in millis
260
     */
261
    public static function currentTimeMillis()
×
262
    {
263
        return (int) \round(\microtime(true) * 1000);
×
264
    }
265
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc