UAgent::generate_platform()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 5
nop 0
dl 0
loc 28
rs 9.1608
c 0
b 0
f 0
1
<?php
2
/**
3
 * User Agent Generator
4
 * @version 1.0
5
 * @link https://github.com/Dreyer/random-uagent
6
 * @author Dreyer
7
 */
8
9
class UAgent
10
{
11
    // General token that says the browser is Mozilla compatible, 
12
    // and is common to almost every browser today.
13
    const MOZILLA = 'Mozilla/5.0 ';
14
15
    /**
16
     * Processors by Arch.
17
     */
18
    public static $processors = array(
19
        'lin' => array( 'i686', 'x86_64' ),
20
        'mac' => array( 'Intel', 'PPC', 'U; Intel', 'U; PPC' ),
21
        'win' => array( 'foo' )
22
    );
23
24
    /**
25
     * Browsers
26
     * 
27
     * Weighting is based on market share to determine frequency.
28
     */
29
    public static $browsers = array(
30
        34 => array(
31
            89 => array( 'chrome', 'win' ),
32
            9  => array( 'chrome', 'mac' ),
33
            2  => array( 'chrome', 'lin' )
34
        ),
35
        32 => array(
36
            100 => array( 'iexplorer', 'win' )
37
        ),
38
        25 => array(
39
            83 => array( 'firefox', 'win' ),
40
            16 => array( 'firefox', 'mac' ),
41
            1  => array( 'firefox', 'lin' )
42
        ),
43
        7 => array(
44
            95 => array( 'safari', 'mac' ),
45
            4  => array( 'safari', 'win' ),
46
            1  => array( 'safari', 'lin' )
47
        ),
48
        2 => array(
49
            91 => array( 'opera', 'win' ),
50
            6  => array( 'opera', 'lin' ),
51
            3  => array( 'opera', 'mac' )
52
        )
53
    );
54
55
    /**
56
     * List of Lanuge Culture Codes (ISO 639-1)
57
     *
58
     * @see: http://msdn.microsoft.com/en-gb/library/ee825488(v=cs.20).aspx
59
     */
60
    public static $languages = array(
61
        'af-ZA', 'ar-AE', 'ar-BH', 'ar-DZ', 'ar-EG', 'ar-IQ', 'ar-JO', 'ar-KW', 'ar-LB',
62
        'ar-LY', 'ar-MA', 'ar-OM', 'ar-QA', 'ar-SA', 'ar-SY', 'ar-TN', 'ar-YE', 'be-BY',
63
        'bg-BG', 'ca-ES', 'cs-CZ', 'Cy-az-AZ', 'Cy-sr-SP', 'Cy-uz-UZ', 'da-DK', 'de-AT',
64
        'de-CH', 'de-DE', 'de-LI', 'de-LU', 'div-MV', 'el-GR', 'en-AU', 'en-BZ', 'en-CA', 
65
        'en-CB', 'en-GB', 'en-IE', 'en-JM', 'en-NZ', 'en-PH', 'en-TT', 'en-US', 'en-ZA', 
66
        'en-ZW', 'es-AR', 'es-BO', 'es-CL', 'es-CO',  'es-CR', 'es-DO', 'es-EC', 'es-ES',
67
        'es-GT', 'es-HN', 'es-MX', 'es-NI', 'es-PA', 'es-PE', 'es-PR', 'es-PY', 'es-SV',
68
        'es-UY', 'es-VE', 'et-EE', 'eu-ES', 'fa-IR', 'fi-FI', 'fo-FO', 'fr-BE', 'fr-CA',
69
        'fr-CH', 'fr-FR', 'fr-LU', 'fr-MC', 'gl-ES', 'gu-IN', 'he-IL', 'hi-IN', 'hr-HR', 
70
        'hu-HU', 'hy-AM', 'id-ID', 'is-IS', 'it-CH', 'it-IT', 'ja-JP', 'ka-GE', 'kk-KZ',
71
        'kn-IN', 'kok-IN', 'ko-KR', 'ky-KZ', 'Lt-az-AZ', 'lt-LT', 'Lt-sr-SP', 'Lt-uz-UZ', 
72
        'lv-LV', 'mk-MK', 'mn-MN', 'mr-IN', 'ms-BN', 'ms-MY', 'nb-NO', 'nl-BE', 'nl-NL', 
73
        'nn-NO', 'pa-IN', 'pl-PL', 'pt-BR', 'pt-PT', 'ro-RO', 'ru-RU', 'sa-IN', 'sk-SK', 
74
        'sl-SI', 'sq-AL', 'sv-FI', 'sv-SE', 'sw-KE', 'syr-SY', 'ta-IN', 'te-IN', 'th-TH', 
75
        'tr-TR', 'tt-RU', 'uk-UA', 'ur-PK', 'vi-VN', 'zh-CHS', 'zh-CHT', 'zh-CN', 'zh-HK', 
76
        'zh-MO', 'zh-SG', 'zh-TW',   
77
    );    
78
79
    /**
80
     * Generate Device Platform
81
     *
82
     * Uses a random result with a weighting related to frequencies.
83
     */
84
    public static function generate_platform()
85
    {
86
        $rand = mt_rand( 1, 100 );
87
        $sum = 0;
88
89
        foreach ( self::$browsers as $share => $freq_os )
90
        {
91
            $sum += $share;
92
93
            if ( $rand <= $sum )
94
            {
95
                $rand = mt_rand( 1, 100 );
96
                $sum = 0;
97
98
                foreach ( $freq_os as $share => $choice )
99
                {
100
                    $sum += $share;
101
102
                    if ( $rand <= $sum )
103
                    {
104
                        return $choice;
105
                    }
106
                }
107
            }
108
        }
109
110
        throw new Exception( 'Sum of $browsers frequency is not 100.' );
111
    }
112
113
    private static function array_random( $array )
114
    {
115
        $i = array_rand( $array, 1 );
116
117
        return $array[$i];
118
    }
119
120
    private static function get_language( $lang = array() )
121
    {
122
        return self::array_random( empty( $lang ) ? self::$languages : $lang );
123
    }
124
125
    private static function get_processor( $os )
126
    {
127
        return self::array_random( self::$processors[$os] );
128
    }
129
130
    private static function get_version_nt()
131
    {   
132
        // Win2k (5.0) to Win 7 (6.1).
133
        return mt_rand( 5, 6 ) . '.' . mt_rand( 0, 1 );
134
    }
135
136
    private static function get_version_osx()
137
    {
138
        return '10_' . mt_rand( 5, 7 ) . '_' . mt_rand( 0, 9 );
139
    }
140
141
    private static function get_version_webkit()
142
    {
143
        return mt_rand( 531, 536 ) . mt_rand( 0, 2 );
144
    }
145
146
    private static function get_verison_chrome()
147
    {
148
        return mt_rand( 13, 15 ) . '.0.' . mt_rand( 800, 899 ) . '.0';
149
    }
150
151
    private static function get_version_gecko()
152
    {
153
        return mt_rand( 17, 31 ) . '.0';
154
    }
155
156
    private static function get_version_ie()
157
    {
158
        return mt_rand( 7, 9 ) . '.0';
159
    }
160
161
    private static function get_version_trident()
162
    {
163
        // IE8 (4.0) to IE11 (7.0).
164
        return mt_rand( 4, 7 ) . '.0';
165
    }
166
167
    private static function get_version_net()
168
    {
169
        // generic .NET Framework common language run time (CLR) version numbers.
170
        $frameworks = array(
171
            '2.0.50727',
172
            '3.0.4506',
173
            '3.5.30729',
174
        );
175
176
        $rev = '.' . mt_rand( 26, 648 );
177
178
        return self::array_random( $frameworks ) . $rev;
179
    }
180
181
    private static function get_version_safari()
182
    {
183
        if ( mt_rand( 0, 1 ) == 0 )
184
        {
185
            $ver = mt_rand( 4, 5 ) . '.' . mt_rand( 0, 1 );
186
        }
187
        else
188
        {
189
            $ver = mt_rand( 4, 5 ) . '.0.' . mt_rand( 1, 5 );
190
        }
191
192
        return $ver;
193
    }
194
195
    private static function get_version_opera()
196
    {
197
        return mt_rand( 15, 19 ) . '.0.' . mt_rand( 1147, 1284 ) . mt_rand( 49, 100 );
198
    }
199
200
    /**
201
     * Opera
202
     * 
203
     * @see: http://dev.opera.com/blog/opera-user-agent-strings-opera-15-and-beyond/
204
     */
205
    public static function opera( $arch )
206
    {
207
        $opera = ' OPR/' . self::get_version_opera();
208
209
        // WebKit Rendering Engine (WebKit = Backend, Safari = Frontend).
210
        $engine = self::get_version_webkit();
211
        $webkit = ' AppleWebKit/' . $engine . ' (KHTML, like Gecko)';
212
        $chrome = ' Chrome/' . self::get_verison_chrome();
213
        $safari = ' Safari/' . $engine;
214
215
        switch ( $arch )
216
        {
217
            case 'lin':
218
                return '(X11; Linux {proc}) ' . $webkit . $chrome . $safari . $opera;
219
            case 'mac':
220
                $osx = self::get_version_osx();
221
                return '(Macintosh; U; {proc} Mac OS X ' . $osx . ')' . $webkit . $chrome . $safari . $opera;
222
            case 'win':
223
                // fall through.
224
            default:
225
                $nt = self::get_version_nt();
226
                return '(Windows NT ' . $nt . '; WOW64) ' . $webkit . $chrome . $safari . $opera;
227
        }
228
    }    
229
230
    /**
231
     * Safari
232
     *
233
     */
234
    public static function safari( $arch )
235
    {
236
        $version = ' Version/' . self::get_version_safari();
237
238
        // WebKit Rendering Engine (WebKit = Backend, Safari = Frontend).
239
        $engine = self::get_version_webkit();
240
        $webkit = ' AppleWebKit/' . $engine . ' (KHTML, like Gecko)';
241
        $safari = ' Safari/' . $engine;
242
243
        switch ( $arch )
244
        {
245
            case 'mac':
246
                $osx = self::get_version_osx();
247
                return '(Macintosh; U; {proc} Mac OS X ' . $osx . '; {lang})' . $webkit . $version . $safari;
248
            case 'win':
249
                // fall through.
250
            default:
251
                $nt = self::get_version_nt();
252
                return '(Windows; U; Windows NT ' . $nt . ')' . $webkit . $version . $safari;
253
        }
254
255
    }
256
257
    /**
258
     * Internet Explorer
259
     * 
260
     * @see: http://msdn.microsoft.com/en-gb/library/ms537503(v=vs.85).aspx
261
     */
262
    public static function iexplorer( $arch )
0 ignored issues
show
Unused Code introduced by
The parameter $arch 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...
263
    {
264
        $nt = self::get_version_nt();
265
        $ie = self::get_version_ie();
266
        $trident = self::get_version_trident();
267
        $net = self::get_version_net();
268
269
        return '(compatible' 
270
            . '; MSIE ' . $ie 
271
            . '; Windows NT ' . $nt 
272
            . '; WOW64' // A 32-bit version of Internet Explorer is running on a 64-bit processor.
273
            . '; Trident/' . $trident 
274
            . '; .NET CLR ' . $net
275
            . ')';
276
    }
277
278
    /**
279
     * Firefox User-Agent
280
     *
281
     * @see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Gecko_user_agent_string_reference
282
     */
283
    public static function firefox( $arch )
284
    {
285
        // The release version of Gecko. 
286
        $gecko = self::get_version_gecko();
287
288
        // On desktop, the gecko trail is fixed.
289
        $trail = '20100101';
290
291
        $release = 'rv:' . $gecko;
292
        $version = 'Gecko/' . $trail . ' Firefox/' . $gecko;
293
294
        switch ( $arch )
295
        {
296
            case 'lin':
297
                return '(X11; Linux {proc}; ' . $release . ') ' . $version;
298
            case 'mac':
299
                $osx = self::get_version_osx();
300
                return '(Macintosh; {proc} Mac OS X ' . $osx . '; ' . $release . ') ' . $version;
301
            case 'win':
302
                // fall through.
303
            default:
304
                $nt = self::get_version_nt();
305
                return '(Windows NT ' . $nt . '; {lang}; ' . $release . ') ' . $version;
306
        }
307
    }
308
309
    public static function chrome( $arch )
310
    {
311
        $chrome = ' Chrome/' . self::get_verison_chrome();
312
313
        // WebKit Rendering Engine (WebKit = Backend, Safari = Frontend).
314
        $engine = self::get_version_webkit();
315
        $webkit = ' AppleWebKit/' . $engine . ' (KHTML, like Gecko)';
316
        $safari = ' Safari/' . $engine;
317
318
        switch ( $arch )
319
        {
320
            case 'lin':
321
                return '(X11; Linux {proc}) ' . $webkit . $chrome . $safari;
322
            case 'mac':
323
                $osx = self::get_version_osx();
324
                return '(Macintosh; U; {proc} Mac OS X ' . $osx . ')' . $webkit . $chrome . $safari;
325
            case 'win':
326
                // fall through.
327
            default:
328
                $nt = self::get_version_nt();
329
                return '(Windows NT ' . $nt . ') ' . $webkit . $chrome . $safari;
330
        }
331
    }
332
333
    public static function random( $lang = array( 'en-US' ) )
334
    {
335
        list( $browser, $os ) = self::generate_platform();
336
337
        return self::generate( $browser, $os, $lang );
338
    }
339
340
    public static function generate( $browser = 'chrome', $os = 'win', $lang = array( 'en-US' ) )
341
    {
342
        $ua = self::MOZILLA . call_user_func( 'UAgent::' . $browser, $os );
343
344
        $tags = array(
345
            '{proc}' => self::get_processor( $os ),
346
            '{lang}' => self::get_language( $lang ),
347
        );
348
349
        $ua = str_replace( array_keys( $tags ), array_values( $tags ), $ua );
350
351
        return $ua;
352
    }
353
}
354
?>
355