Completed
Push — master ( b5c42c...32df1f )
by Elf
01:59
created

Support   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 331
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 4

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 32
lcom 0
cbo 4
dl 0
loc 331
ccs 0
cts 211
cp 0
rs 9.6
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C extension() 0 24 9
A extensionForMime() 0 4 1
B iDeviceModel() 0 87 2
B mailHomepage() 0 33 3
A sampleEncrypt() 0 20 2
A sampleDecrypt() 0 15 3
B sampleEncryption() 0 28 4
A fakeAppClient() 0 14 2
B fakeApiToken() 0 14 5
1
<?php
2
3
namespace ElfSundae\Laravel\Support;
4
5
use SplFileInfo;
6
use Illuminate\Support\Str;
7
use Intervention\Image\File as ImageFile;
8
use Illuminate\Foundation\Application;
9
use Illuminate\Support\Traits\Macroable;
10
use Symfony\Component\HttpFoundation\File\File as SymfonyFile;
11
use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
12
13
class Support
14
{
15
    use Macroable;
16
17
    /**
18
     * The application instance.
19
     *
20
     * @var \Illuminate\Foundation\Application
21
     */
22
    protected $app;
23
24
    /**
25
     * Create a new Support instance.
26
     *
27
     * @param  \Illuminate\Foundation\Application  $app
28
     */
29
    public function __construct(Application $app)
30
    {
31
        $this->app = $app;
32
    }
33
34
    /**
35
     * Get the file extension.
36
     *
37
     * @param  mixed  $file
38
     * @param  string  $prefix
39
     * @return string|null
40
     */
41
    public function extension($file, $prefix = '')
42
    {
43
        if (is_string($file)) {
44
            if (substr_count($file, '/') === 1) {
45
                $ext = $this->extensionForMime($file);
46
            } else {
47
                $ext = pathinfo($file, PATHINFO_EXTENSION);
48
            }
49
        } elseif ($file instanceof SymfonyFile) {
50
            $ext = $file->guessExtension();
51
        } elseif ($file instanceof SplFileInfo) {
52
            $ext = $file->getExtension();
53
        } elseif ($file instanceof ImageFile) {
1 ignored issue
show
Bug introduced by
The class Intervention\Image\File does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
54
            $ext = $file->extension ?: $this->extensionForMime($file->mime);
55
        }
56
57
        if (! empty($ext)) {
58
            if ($ext == 'jpeg') {
59
                $ext = 'jpg';
60
            }
61
62
            return $prefix.$ext;
63
        }
64
    }
65
66
    /**
67
     * Get the file extension for the given MIME type.
68
     *
69
     * @param  string  $mimeType
70
     * @return string|null
71
     */
72
    public function extensionForMime($mimeType)
73
    {
74
        return ExtensionGuesser::getInstance()->guess($mimeType);
75
    }
76
77
    /**
78
     * Convert an iOS platform to the device model name.
79
     *
80
     * @see https://www.theiphonewiki.com/wiki/Models
81
     * @see https://support.hockeyapp.net/kb/client-integration-ios-mac-os-x-tvos/ios-device-types
82
     *
83
     * @param  string  $platform
84
     * @return string
85
     */
86
    public function iDeviceModel($platform)
87
    {
88
        static $iDeviceModels = null;
89
90
        if (is_null($iDeviceModels)) {
91
            $iDeviceModels = [
92
                'i386' => 'Simulator',
93
                'x86_64' => 'Simulator',
94
95
                'iPhone1,1' => 'iPhone',
96
                'iPhone1,2' => 'iPhone 3G',
97
                'iPhone2,1' => 'iPhone 3GS',
98
                'iPhone3,1' => 'iPhone 4',
99
                'iPhone3,2' => 'iPhone 4',
100
                'iPhone3,3' => 'iPhone 4',
101
                'iPhone4,1' => 'iPhone 4S',
102
                'iPhone5,1' => 'iPhone 5',
103
                'iPhone5,2' => 'iPhone 5',
104
                'iPhone5,3' => 'iPhone 5c',
105
                'iPhone5,4' => 'iPhone 5c',
106
                'iPhone6,1' => 'iPhone 5s',
107
                'iPhone6,2' => 'iPhone 5s',
108
                'iPhone7,1' => 'iPhone 6 Plus',
109
                'iPhone7,2' => 'iPhone 6',
110
                'iPhone8,1' => 'iPhone 6s',
111
                'iPhone8,2' => 'iPhone 6s Plus',
112
                'iPhone8,4' => 'iPhone SE',
113
                'iPhone9,1' => 'iPhone 7',
114
                'iPhone9,2' => 'iPhone 7 Plus',
115
                'iPhone9,3' => 'iPhone 7',
116
                'iPhone9,4' => 'iPhone 7 Plus',
117
118
                'iPod1,1' => 'iPod touch',
119
                'iPod2,1' => 'iPod touch 2G',
120
                'iPod3,1' => 'iPod touch 3G',
121
                'iPod4,1' => 'iPod touch 4G',
122
                'iPod5,1' => 'iPod touch 5G',
123
                'iPod7,1' => 'iPod touch 6G',
124
125
                'iPad1,1' => 'iPad',
126
                'iPad2,1' => 'iPad 2',
127
                'iPad2,2' => 'iPad 2',
128
                'iPad2,3' => 'iPad 2',
129
                'iPad2,4' => 'iPad 2',
130
                'iPad2,5' => 'iPad mini',
131
                'iPad2,6' => 'iPad mini',
132
                'iPad2,7' => 'iPad mini',
133
                'iPad3,1' => 'iPad 3',
134
                'iPad3,2' => 'iPad 3',
135
                'iPad3,3' => 'iPad 3',
136
                'iPad3,4' => 'iPad 4',
137
                'iPad3,5' => 'iPad 4',
138
                'iPad3,6' => 'iPad 4',
139
                'iPad4,1' => 'iPad Air',
140
                'iPad4,2' => 'iPad Air',
141
                'iPad4,3' => 'iPad Air',
142
                'iPad4,4' => 'iPad mini 2',
143
                'iPad4,5' => 'iPad mini 2',
144
                'iPad4,6' => 'iPad mini 2',
145
                'iPad4,7' => 'iPad mini 3',
146
                'iPad4,8' => 'iPad mini 3',
147
                'iPad4,9' => 'iPad mini 3',
148
                'iPad5,1' => 'iPad mini 4',
149
                'iPad5,2' => 'iPad mini 4',
150
                'iPad5,3' => 'iPad Air 2',
151
                'iPad5,4' => 'iPad Air 2',
152
                'iPad6,3' => 'iPad Pro',
153
                'iPad6,4' => 'iPad Pro',
154
                'iPad6,7' => 'iPad Pro',
155
                'iPad6,8' => 'iPad Pro',
156
157
                'AppleTV2,1' => 'Apple TV 2G',
158
                'AppleTV3,1' => 'Apple TV 3G',
159
                'AppleTV3,2' => 'Apple TV 3G',
160
                'AppleTV5,3' => 'Apple TV 4G',
161
162
                'Watch1,1' => 'Apple Watch',
163
                'Watch1,2' => 'Apple Watch',
164
                'Watch2,6' => 'Apple Watch Series 1',
165
                'Watch2,7' => 'Apple Watch Series 1',
166
                'Watch2,3' => 'Apple Watch Series 2',
167
                'Watch2,4' => 'Apple Watch Series 2',
168
            ];
169
        }
170
171
        return $iDeviceModels[$platform] ?? $platform;
172
    }
173
174
    /**
175
     * Get the mail homepage.
176
     *
177
     * @param  string  $address
178
     * @return string|null
179
     */
180
    public function mailHomepage($address)
181
    {
182
        static $mailHomepages = null;
183
184
        if (filter_var($address, FILTER_VALIDATE_EMAIL)) {
185
            if (is_null($mailHomepages)) {
186
                $mailHomepages = [
187
                    'gmail.com' => 'https://mail.google.com',
188
                    'yahoo.com' => 'https://mail.yahoo.com',
189
                    'outlook.com' => 'https://outlook.live.com',
190
                    'qq.com' => 'https://mail.qq.com',
191
                    'vip.qq.com' => 'https://mail.qq.com',
192
                    '163.com' => 'http://mail.163.com',
193
                    '126.com' => 'http://www.126.com',
194
                    'yeah.net' => 'http://www.yeah.net',
195
                    'sina.com' => 'https://mail.sina.com.cn',
196
                    'sina.cn' => 'https://mail.sina.com.cn',
197
                    'vip.sina.com' => 'https://mail.sina.com.cn',
198
                    'sohu.com' => 'https://mail.sohu.com',
199
                    'vip.sohu.com' => 'https://vip.sohu.com',
200
                    'aliyun.com' => 'https://mail.aliyun.com',
201
                    'tom.com' => 'http://mail.tom.com',
202
                    '139.com' => 'http://mail.10086.cn',
203
                    'wo.cn' => 'https://mail.wo.cn',
204
                    '189.cn' => 'https://mail.189.cn',
205
                ];
206
            }
207
208
            $domain = strtolower(Str::after($address, '@'));
209
210
            return $mailHomepages[$domain] ?? 'http://'.$domain;
211
        }
212
    }
213
214
    /**
215
     * Encrypt ASCII string via XOR.
216
     *
217
     * @param  string  $text
218
     * @param  string|null  $key
219
     * @return string
220
     */
221
    public function sampleEncrypt($text, $key = null)
222
    {
223
        $text = (string) $text;
224
        if (is_null($key)) {
225
            $key = app('encrypter')->getKey();
226
        }
227
228
        // 生成随机字符串
229
        $random = str_random(strlen($text));
230
231
        // 按字符拼接:随机字符串 + 随机字符串异或原文
232
        $tmp = static::sampleEncryption($text, $random, function ($a, $b) {
233
            return $b.($a ^ $b);
234
        });
235
236
        // 异或 $tmp 和 $key
237
        $result = static::sampleEncryption($tmp, $key);
238
239
        return urlsafe_base64_encode($result);
240
    }
241
242
    /**
243
     * Decrypt string via XOR.
244
     *
245
     * @param  string  $text
246
     * @param  string|null  $key
247
     * @return string
248
     */
249
    public function sampleDecrypt($text, $key = null)
250
    {
251
        if (is_null($key)) {
252
            $key = app('encrypter')->getKey();
253
        }
254
255
        $tmp = static::sampleEncryption(urlsafe_base64_decode($text), $key);
256
        $tmpLength = strlen($tmp);
257
        $result = '';
258
        for ($i = 0; $i < $tmpLength, ($i + 1) < $tmpLength; $i += 2) {
259
            $result .= $tmp[$i] ^ $tmp[$i + 1];
260
        }
261
262
        return $result;
263
    }
264
265
    /**
266
     * Do a sample XOR encryption.
267
     *
268
     * @param  string  $text
269
     * @param  string  $key
270
     * @param  \Closure|null  $callback `($a, $b, $index)`
271
     * @return string
272
     */
273
    protected static function sampleEncryption($text, $key, $callback = null)
274
    {
275
        // 对 $text 和 $key 的每个字符进行运算。
276
        // $callback 为 null 时默认进行异或运算。
277
        // $callback 参数: 第 i 位 $text, 第 i 位 $key, 下标 i
278
        // $callback 返回 false 时,结束字符循环.
279
280
        $text = (string) $text;
281
        $key = (string) $key;
282
        $keyLength = strlen($key);
283
        if (is_null($callback)) {
284
            $callback = function ($a, $b) {
285
                return $a ^ $b;
286
            };
287
        }
288
289
        $result = '';
290
        $textLength = strlen($text);
291
        for ($i = 0; $i < $textLength; $i++) {
292
            $tmp = $callback($text[$i], $key[$i % $keyLength], $i);
293
            if (false === $tmp) {
294
                break;
295
            }
296
            $result .= $tmp;
297
        }
298
299
        return $result;
300
    }
301
302
    /**
303
     * Fake current agent client to an app client.
304
     *
305
     * @param  array  $client
306
     * @return void
307
     */
308
    public function fakeAppClient(array $client)
309
    {
310
        app()->resolving('agent.client', function ($agent, $app) use ($client) {
311
            if ($agent->is('AppClient')) {
312
                return;
313
            }
314
315
            $client = urlsafe_base64_encode(json_encode($client));
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $client, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
316
317
            $agent->setUserAgent(
318
                $app['request']->header('User-Agent')." client($client)"
319
            );
320
        });
321
    }
322
323
    /**
324
     * Set faked api token for the current request.
325
     *
326
     * @param  string|null  $appKey
327
     * @return void
328
     */
329
    public function fakeApiToken($appKey = null)
330
    {
331
        app()->rebinding('request', function ($app, $request) use ($appKey) {
332
            if ($request->hasHeader('X-API-TOKEN') || $request->has('_token')) {
333
                return;
334
            }
335
336
            $appKey = $appKey ?: app('api.client')->defaultAppKey();
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $appKey, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
337
338
            foreach (app('api.token')->generateDataForKey($appKey) as $key => $value) {
339
                $request->headers->set('X-API-'.strtoupper($key), $value);
340
            }
341
        });
342
    }
343
}
344