Completed
Branch EDTR/wp-i18n (4ed58a)
by
unknown
28:52 queued 17:14
created
composer-setup.php 3 patches
Doc Comments   +14 added lines, -4 removed lines patch added patch discarded remove patch
@@ -148,7 +148,7 @@  discard block
 block discarded – undo
148 148
  *
149 149
  * @param string $opt The command-line option to check
150 150
  * @param array $argv Command-line arguments
151
- * @param mixed $default Default value to be returned
151
+ * @param false|string $default Default value to be returned
152 152
  *
153 153
  * @return mixed The command-line value or the default
154 154
  */
@@ -491,6 +491,7 @@  discard block
 block discarded – undo
491 491
 
492 492
 /**
493 493
  * colorize output
494
+ * @param string $color
494 495
  */
495 496
 function out($text, $color = null, $newLine = true)
496 497
 {
@@ -573,6 +574,9 @@  discard block
 block discarded – undo
573 574
     return false;
574 575
 }
575 576
 
577
+/**
578
+ * @param string $contents
579
+ */
576 580
 function validateCaFile($contents)
577 581
 {
578 582
     // assume the CA is valid if php is vulnerable to
@@ -608,7 +612,7 @@  discard block
 block discarded – undo
608 612
      *
609 613
      * @param bool $quiet Quiet mode
610 614
      * @param bool $disableTls Bypass tls
611
-     * @param mixed $cafile Path to CA bundle, or false
615
+     * @param mixed $caFile Path to CA bundle, or false
612 616
      */
613 617
     public function __construct($quiet, $disableTls, $caFile)
614 618
     {
@@ -946,9 +950,9 @@  discard block
 block discarded – undo
946 950
      * Parses an array of version data to match the required channel
947 951
      *
948 952
      * @param array $data Downloaded version data
949
-     * @param mixed $channel Version channel to use
953
+     * @param string $channel Version channel to use
950 954
      * @param false|string $version Set by method
951
-     * @param mixed $url The versioned url, set by method
955
+     * @param null|string $url The versioned url, set by method
952 956
      */
953 957
     protected function parseVersionData(array $data, $channel, &$version, &$url)
954 958
     {
@@ -1276,6 +1280,9 @@  discard block
 block discarded – undo
1276 1280
         }
1277 1281
     }
1278 1282
 
1283
+    /**
1284
+     * @param string $url
1285
+     */
1279 1286
     public function get($url)
1280 1287
     {
1281 1288
         $context = $this->getStreamContext($url);
@@ -1320,6 +1327,9 @@  discard block
 block discarded – undo
1320 1327
         return $this->getMergedStreamContext($url);
1321 1328
     }
1322 1329
 
1330
+    /**
1331
+     * @param boolean $cafile
1332
+     */
1323 1333
     protected function getTlsStreamContextDefaults($cafile)
1324 1334
     {
1325 1335
         $ciphers = implode(':', array(
Please login to merge, or discard this patch.
Indentation   +1373 added lines, -1373 removed lines patch added patch discarded remove patch
@@ -20,26 +20,26 @@  discard block
 block discarded – undo
20 20
  */
21 21
 function setupEnvironment()
22 22
 {
23
-    ini_set('display_errors', 1);
24
-
25
-    if (extension_loaded('uopz') && !(ini_get('uopz.disable') || ini_get('uopz.exit'))) {
26
-        // uopz works at opcode level and disables exit calls
27
-        if (function_exists('uopz_allow_exit')) {
28
-            @uopz_allow_exit(true);
29
-        } else {
30
-            throw new RuntimeException('The uopz extension ignores exit calls and breaks this installer.');
31
-        }
32
-    }
33
-
34
-    $installer = 'Composer Installer';
35
-
36
-    if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
37
-        if ($version = getenv('COMPOSERSETUP')) {
38
-            $installer = sprintf('Composer-Setup.exe %s', $version);
39
-        }
40
-    }
41
-
42
-    define('COMPOSER_INSTALLER', $installer);
23
+	ini_set('display_errors', 1);
24
+
25
+	if (extension_loaded('uopz') && !(ini_get('uopz.disable') || ini_get('uopz.exit'))) {
26
+		// uopz works at opcode level and disables exit calls
27
+		if (function_exists('uopz_allow_exit')) {
28
+			@uopz_allow_exit(true);
29
+		} else {
30
+			throw new RuntimeException('The uopz extension ignores exit calls and breaks this installer.');
31
+		}
32
+	}
33
+
34
+	$installer = 'Composer Installer';
35
+
36
+	if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
37
+		if ($version = getenv('COMPOSERSETUP')) {
38
+			$installer = sprintf('Composer-Setup.exe %s', $version);
39
+		}
40
+	}
41
+
42
+	define('COMPOSER_INSTALLER', $installer);
43 43
 }
44 44
 
45 45
 /**
@@ -47,50 +47,50 @@  discard block
 block discarded – undo
47 47
  */
48 48
 function process($argv)
49 49
 {
50
-    // Determine ANSI output from --ansi and --no-ansi flags
51
-    setUseAnsi($argv);
52
-
53
-    if (in_array('--help', $argv)) {
54
-        displayHelp();
55
-        exit(0);
56
-    }
57
-
58
-    $check      = in_array('--check', $argv);
59
-    $help       = in_array('--help', $argv);
60
-    $force      = in_array('--force', $argv);
61
-    $quiet      = in_array('--quiet', $argv);
62
-    $channel    = in_array('--snapshot', $argv) ? 'snapshot' : (in_array('--preview', $argv) ? 'preview' : 'stable');
63
-    $disableTls = in_array('--disable-tls', $argv);
64
-    $installDir = getOptValue('--install-dir', $argv, false);
65
-    $version    = getOptValue('--version', $argv, false);
66
-    $filename   = getOptValue('--filename', $argv, 'composer.phar');
67
-    $cafile     = getOptValue('--cafile', $argv, false);
68
-
69
-    if (!checkParams($installDir, $version, $cafile)) {
70
-        exit(1);
71
-    }
72
-
73
-    $ok = checkPlatform($warnings, $quiet, $disableTls, true);
74
-
75
-    if ($check) {
76
-        // Only show warnings if we haven't output any errors
77
-        if ($ok) {
78
-            showWarnings($warnings);
79
-            showSecurityWarning($disableTls);
80
-        }
81
-        exit($ok ? 0 : 1);
82
-    }
83
-
84
-    if ($ok || $force) {
85
-        $installer = new Installer($quiet, $disableTls, $cafile);
86
-        if ($installer->run($version, $installDir, $filename, $channel)) {
87
-            showWarnings($warnings);
88
-            showSecurityWarning($disableTls);
89
-            exit(0);
90
-        }
91
-    }
92
-
93
-    exit(1);
50
+	// Determine ANSI output from --ansi and --no-ansi flags
51
+	setUseAnsi($argv);
52
+
53
+	if (in_array('--help', $argv)) {
54
+		displayHelp();
55
+		exit(0);
56
+	}
57
+
58
+	$check      = in_array('--check', $argv);
59
+	$help       = in_array('--help', $argv);
60
+	$force      = in_array('--force', $argv);
61
+	$quiet      = in_array('--quiet', $argv);
62
+	$channel    = in_array('--snapshot', $argv) ? 'snapshot' : (in_array('--preview', $argv) ? 'preview' : 'stable');
63
+	$disableTls = in_array('--disable-tls', $argv);
64
+	$installDir = getOptValue('--install-dir', $argv, false);
65
+	$version    = getOptValue('--version', $argv, false);
66
+	$filename   = getOptValue('--filename', $argv, 'composer.phar');
67
+	$cafile     = getOptValue('--cafile', $argv, false);
68
+
69
+	if (!checkParams($installDir, $version, $cafile)) {
70
+		exit(1);
71
+	}
72
+
73
+	$ok = checkPlatform($warnings, $quiet, $disableTls, true);
74
+
75
+	if ($check) {
76
+		// Only show warnings if we haven't output any errors
77
+		if ($ok) {
78
+			showWarnings($warnings);
79
+			showSecurityWarning($disableTls);
80
+		}
81
+		exit($ok ? 0 : 1);
82
+	}
83
+
84
+	if ($ok || $force) {
85
+		$installer = new Installer($quiet, $disableTls, $cafile);
86
+		if ($installer->run($version, $installDir, $filename, $channel)) {
87
+			showWarnings($warnings);
88
+			showSecurityWarning($disableTls);
89
+			exit(0);
90
+		}
91
+	}
92
+
93
+	exit(1);
94 94
 }
95 95
 
96 96
 /**
@@ -98,7 +98,7 @@  discard block
 block discarded – undo
98 98
  */
99 99
 function displayHelp()
100 100
 {
101
-    echo <<<EOF
101
+	echo <<<EOF
102 102
 Composer Installer
103 103
 ------------------
104 104
 Options
@@ -126,21 +126,21 @@  discard block
 block discarded – undo
126 126
  */
127 127
 function setUseAnsi($argv)
128 128
 {
129
-    // --no-ansi wins over --ansi
130
-    if (in_array('--no-ansi', $argv)) {
131
-        define('USE_ANSI', false);
132
-    } elseif (in_array('--ansi', $argv)) {
133
-        define('USE_ANSI', true);
134
-    } else {
135
-        // On Windows, default to no ANSI, except in ANSICON and ConEmu.
136
-        // Everywhere else, default to ANSI if stdout is a terminal.
137
-        define(
138
-            'USE_ANSI',
139
-            (DIRECTORY_SEPARATOR == '\\')
140
-                ? (false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'))
141
-                : (function_exists('posix_isatty') && posix_isatty(1))
142
-        );
143
-    }
129
+	// --no-ansi wins over --ansi
130
+	if (in_array('--no-ansi', $argv)) {
131
+		define('USE_ANSI', false);
132
+	} elseif (in_array('--ansi', $argv)) {
133
+		define('USE_ANSI', true);
134
+	} else {
135
+		// On Windows, default to no ANSI, except in ANSICON and ConEmu.
136
+		// Everywhere else, default to ANSI if stdout is a terminal.
137
+		define(
138
+			'USE_ANSI',
139
+			(DIRECTORY_SEPARATOR == '\\')
140
+				? (false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'))
141
+				: (function_exists('posix_isatty') && posix_isatty(1))
142
+		);
143
+	}
144 144
 }
145 145
 
146 146
 /**
@@ -154,20 +154,20 @@  discard block
 block discarded – undo
154 154
  */
155 155
 function getOptValue($opt, $argv, $default)
156 156
 {
157
-    $optLength = strlen($opt);
158
-
159
-    foreach ($argv as $key => $value) {
160
-        $next = $key + 1;
161
-        if (0 === strpos($value, $opt)) {
162
-            if ($optLength === strlen($value) && isset($argv[$next])) {
163
-                return trim($argv[$next]);
164
-            } else {
165
-                return trim(substr($value, $optLength + 1));
166
-            }
167
-        }
168
-    }
169
-
170
-    return $default;
157
+	$optLength = strlen($opt);
158
+
159
+	foreach ($argv as $key => $value) {
160
+		$next = $key + 1;
161
+		if (0 === strpos($value, $opt)) {
162
+			if ($optLength === strlen($value) && isset($argv[$next])) {
163
+				return trim($argv[$next]);
164
+			} else {
165
+				return trim(substr($value, $optLength + 1));
166
+			}
167
+		}
168
+	}
169
+
170
+	return $default;
171 171
 }
172 172
 
173 173
 /**
@@ -181,23 +181,23 @@  discard block
 block discarded – undo
181 181
  */
182 182
 function checkParams($installDir, $version, $cafile)
183 183
 {
184
-    $result = true;
185
-
186
-    if (false !== $installDir && !is_dir($installDir)) {
187
-        out("The defined install dir ({$installDir}) does not exist.", 'info');
188
-        $result = false;
189
-    }
190
-
191
-    if (false !== $version && 1 !== preg_match('/^\d+\.\d+\.\d+(\-(alpha|beta|RC)\d*)*$/', $version)) {
192
-        out("The defined install version ({$version}) does not match release pattern.", 'info');
193
-        $result = false;
194
-    }
195
-
196
-    if (false !== $cafile && (!file_exists($cafile) || !is_readable($cafile))) {
197
-        out("The defined Certificate Authority (CA) cert file ({$cafile}) does not exist or is not readable.", 'info');
198
-        $result = false;
199
-    }
200
-    return $result;
184
+	$result = true;
185
+
186
+	if (false !== $installDir && !is_dir($installDir)) {
187
+		out("The defined install dir ({$installDir}) does not exist.", 'info');
188
+		$result = false;
189
+	}
190
+
191
+	if (false !== $version && 1 !== preg_match('/^\d+\.\d+\.\d+(\-(alpha|beta|RC)\d*)*$/', $version)) {
192
+		out("The defined install version ({$version}) does not match release pattern.", 'info');
193
+		$result = false;
194
+	}
195
+
196
+	if (false !== $cafile && (!file_exists($cafile) || !is_readable($cafile))) {
197
+		out("The defined Certificate Authority (CA) cert file ({$cafile}) does not exist or is not readable.", 'info');
198
+		$result = false;
199
+	}
200
+	return $result;
201 201
 }
202 202
 
203 203
 /**
@@ -214,25 +214,25 @@  discard block
 block discarded – undo
214 214
  */
215 215
 function checkPlatform(&$warnings, $quiet, $disableTls, $install)
216 216
 {
217
-    getPlatformIssues($errors, $warnings, $install);
218
-
219
-    // Make openssl warning an error if tls has not been specifically disabled
220
-    if (isset($warnings['openssl']) && !$disableTls) {
221
-        $errors['openssl'] = $warnings['openssl'];
222
-        unset($warnings['openssl']);
223
-    }
224
-
225
-    if (!empty($errors)) {
226
-        out('Some settings on your machine make Composer unable to work properly.', 'error');
227
-        out('Make sure that you fix the issues listed below and run this script again:', 'error');
228
-        outputIssues($errors);
229
-        return false;
230
-    }
231
-
232
-    if (empty($warnings) && !$quiet) {
233
-        out('All settings correct for using Composer', 'success');
234
-    }
235
-    return true;
217
+	getPlatformIssues($errors, $warnings, $install);
218
+
219
+	// Make openssl warning an error if tls has not been specifically disabled
220
+	if (isset($warnings['openssl']) && !$disableTls) {
221
+		$errors['openssl'] = $warnings['openssl'];
222
+		unset($warnings['openssl']);
223
+	}
224
+
225
+	if (!empty($errors)) {
226
+		out('Some settings on your machine make Composer unable to work properly.', 'error');
227
+		out('Make sure that you fix the issues listed below and run this script again:', 'error');
228
+		outputIssues($errors);
229
+		return false;
230
+	}
231
+
232
+	if (empty($warnings) && !$quiet) {
233
+		out('All settings correct for using Composer', 'success');
234
+	}
235
+	return true;
236 236
 }
237 237
 
238 238
 /**
@@ -246,206 +246,206 @@  discard block
 block discarded – undo
246 246
  */
247 247
 function getPlatformIssues(&$errors, &$warnings, $install)
248 248
 {
249
-    $errors = array();
250
-    $warnings = array();
251
-
252
-    if ($iniPath = php_ini_loaded_file()) {
253
-        $iniMessage = PHP_EOL.'The php.ini used by your command-line PHP is: ' . $iniPath;
254
-    } else {
255
-        $iniMessage = PHP_EOL.'A php.ini file does not exist. You will have to create one.';
256
-    }
257
-    $iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.';
258
-
259
-    if (ini_get('detect_unicode')) {
260
-        $errors['unicode'] = array(
261
-            'The detect_unicode setting must be disabled.',
262
-            'Add the following to the end of your `php.ini`:',
263
-            '    detect_unicode = Off',
264
-            $iniMessage
265
-        );
266
-    }
267
-
268
-    if (extension_loaded('suhosin')) {
269
-        $suhosin = ini_get('suhosin.executor.include.whitelist');
270
-        $suhosinBlacklist = ini_get('suhosin.executor.include.blacklist');
271
-        if (false === stripos($suhosin, 'phar') && (!$suhosinBlacklist || false !== stripos($suhosinBlacklist, 'phar'))) {
272
-            $errors['suhosin'] = array(
273
-                'The suhosin.executor.include.whitelist setting is incorrect.',
274
-                'Add the following to the end of your `php.ini` or suhosin.ini (Example path [for Debian]: /etc/php5/cli/conf.d/suhosin.ini):',
275
-                '    suhosin.executor.include.whitelist = phar '.$suhosin,
276
-                $iniMessage
277
-            );
278
-        }
279
-    }
280
-
281
-    if (!function_exists('json_decode')) {
282
-        $errors['json'] = array(
283
-            'The json extension is missing.',
284
-            'Install it or recompile php without --disable-json'
285
-        );
286
-    }
287
-
288
-    if (!extension_loaded('Phar')) {
289
-        $errors['phar'] = array(
290
-            'The phar extension is missing.',
291
-            'Install it or recompile php without --disable-phar'
292
-        );
293
-    }
294
-
295
-    if (!extension_loaded('filter')) {
296
-        $errors['filter'] = array(
297
-            'The filter extension is missing.',
298
-            'Install it or recompile php without --disable-filter'
299
-        );
300
-    }
301
-
302
-    if (!extension_loaded('hash')) {
303
-        $errors['hash'] = array(
304
-            'The hash extension is missing.',
305
-            'Install it or recompile php without --disable-hash'
306
-        );
307
-    }
308
-
309
-    if (!extension_loaded('iconv') && !extension_loaded('mbstring')) {
310
-        $errors['iconv_mbstring'] = array(
311
-            'The iconv OR mbstring extension is required and both are missing.',
312
-            'Install either of them or recompile php without --disable-iconv'
313
-        );
314
-    }
315
-
316
-    if (!ini_get('allow_url_fopen')) {
317
-        $errors['allow_url_fopen'] = array(
318
-            'The allow_url_fopen setting is incorrect.',
319
-            'Add the following to the end of your `php.ini`:',
320
-            '    allow_url_fopen = On',
321
-            $iniMessage
322
-        );
323
-    }
324
-
325
-    if (extension_loaded('ionCube Loader') && ioncube_loader_iversion() < 40009) {
326
-        $ioncube = ioncube_loader_version();
327
-        $errors['ioncube'] = array(
328
-            'Your ionCube Loader extension ('.$ioncube.') is incompatible with Phar files.',
329
-            'Upgrade to ionCube 4.0.9 or higher or remove this line (path may be different) from your `php.ini` to disable it:',
330
-            '    zend_extension = /usr/lib/php5/20090626+lfs/ioncube_loader_lin_5.3.so',
331
-            $iniMessage
332
-        );
333
-    }
334
-
335
-    if (version_compare(PHP_VERSION, '5.3.2', '<')) {
336
-        $errors['php'] = array(
337
-            'Your PHP ('.PHP_VERSION.') is too old, you must upgrade to PHP 5.3.2 or higher.'
338
-        );
339
-    }
340
-
341
-    if (version_compare(PHP_VERSION, '5.3.4', '<')) {
342
-        $warnings['php'] = array(
343
-            'Your PHP ('.PHP_VERSION.') is quite old, upgrading to PHP 5.3.4 or higher is recommended.',
344
-            'Composer works with 5.3.2+ for most people, but there might be edge case issues.'
345
-        );
346
-    }
347
-
348
-    if (!extension_loaded('openssl')) {
349
-        $warnings['openssl'] = array(
350
-            'The openssl extension is missing, which means that secure HTTPS transfers are impossible.',
351
-            'If possible you should enable it or recompile php with --with-openssl'
352
-        );
353
-    }
354
-
355
-    if (extension_loaded('openssl') && OPENSSL_VERSION_NUMBER < 0x1000100f) {
356
-        // Attempt to parse version number out, fallback to whole string value.
357
-        $opensslVersion = trim(strstr(OPENSSL_VERSION_TEXT, ' '));
358
-        $opensslVersion = substr($opensslVersion, 0, strpos($opensslVersion, ' '));
359
-        $opensslVersion = $opensslVersion ? $opensslVersion : OPENSSL_VERSION_TEXT;
360
-
361
-        $warnings['openssl_version'] = array(
362
-            'The OpenSSL library ('.$opensslVersion.') used by PHP does not support TLSv1.2 or TLSv1.1.',
363
-            'If possible you should upgrade OpenSSL to version 1.0.1 or above.'
364
-        );
365
-    }
366
-
367
-    if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) {
368
-        $warnings['apc_cli'] = array(
369
-            'The apc.enable_cli setting is incorrect.',
370
-            'Add the following to the end of your `php.ini`:',
371
-            '    apc.enable_cli = Off',
372
-            $iniMessage
373
-        );
374
-    }
375
-
376
-    if (!$install && extension_loaded('xdebug')) {
377
-        $warnings['xdebug_loaded'] = array(
378
-            'The xdebug extension is loaded, this can slow down Composer a little.',
379
-            'Disabling it when using Composer is recommended.'
380
-        );
381
-
382
-        if (ini_get('xdebug.profiler_enabled')) {
383
-            $warnings['xdebug_profile'] = array(
384
-                'The xdebug.profiler_enabled setting is enabled, this can slow down Composer a lot.',
385
-                'Add the following to the end of your `php.ini` to disable it:',
386
-                '    xdebug.profiler_enabled = 0',
387
-                $iniMessage
388
-            );
389
-        }
390
-    }
391
-
392
-    if (!extension_loaded('zlib')) {
393
-        $warnings['zlib'] = array(
394
-            'The zlib extension is not loaded, this can slow down Composer a lot.',
395
-            'If possible, install it or recompile php with --with-zlib',
396
-            $iniMessage
397
-        );
398
-    }
399
-
400
-    if (defined('PHP_WINDOWS_VERSION_BUILD')
401
-        && (version_compare(PHP_VERSION, '7.2.23', '<')
402
-        || (version_compare(PHP_VERSION, '7.3.0', '>=')
403
-        && version_compare(PHP_VERSION, '7.3.10', '<')))) {
404
-        $warnings['onedrive'] = array(
405
-            'The Windows OneDrive folder is not supported on PHP versions below 7.2.23 and 7.3.10.',
406
-            'Upgrade your PHP ('.PHP_VERSION.') to use this location with Composer.'
407
-        );
408
-    }
409
-
410
-    if (extension_loaded('uopz') && !(ini_get('uopz.disable') || ini_get('uopz.exit'))) {
411
-        $warnings['uopz'] = array(
412
-            'The uopz extension ignores exit calls and may not work with all Composer commands.',
413
-            'Disabling it when using Composer is recommended.'
414
-        );
415
-    }
416
-
417
-    ob_start();
418
-    phpinfo(INFO_GENERAL);
419
-    $phpinfo = ob_get_clean();
420
-    if (preg_match('{Configure Command(?: *</td><td class="v">| *=> *)(.*?)(?:</td>|$)}m', $phpinfo, $match)) {
421
-        $configure = $match[1];
422
-
423
-        if (false !== strpos($configure, '--enable-sigchild')) {
424
-            $warnings['sigchild'] = array(
425
-                'PHP was compiled with --enable-sigchild which can cause issues on some platforms.',
426
-                'Recompile it without this flag if possible, see also:',
427
-                '    https://bugs.php.net/bug.php?id=22999'
428
-            );
429
-        }
430
-
431
-        if (false !== strpos($configure, '--with-curlwrappers')) {
432
-            $warnings['curlwrappers'] = array(
433
-                'PHP was compiled with --with-curlwrappers which will cause issues with HTTP authentication and GitHub.',
434
-                'Recompile it without this flag if possible'
435
-            );
436
-        }
437
-    }
438
-
439
-    // Stringify the message arrays
440
-    foreach ($errors as $key => $value) {
441
-        $errors[$key] = PHP_EOL.implode(PHP_EOL, $value);
442
-    }
443
-
444
-    foreach ($warnings as $key => $value) {
445
-        $warnings[$key] = PHP_EOL.implode(PHP_EOL, $value);
446
-    }
447
-
448
-    return !empty($errors) || !empty($warnings);
249
+	$errors = array();
250
+	$warnings = array();
251
+
252
+	if ($iniPath = php_ini_loaded_file()) {
253
+		$iniMessage = PHP_EOL.'The php.ini used by your command-line PHP is: ' . $iniPath;
254
+	} else {
255
+		$iniMessage = PHP_EOL.'A php.ini file does not exist. You will have to create one.';
256
+	}
257
+	$iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.';
258
+
259
+	if (ini_get('detect_unicode')) {
260
+		$errors['unicode'] = array(
261
+			'The detect_unicode setting must be disabled.',
262
+			'Add the following to the end of your `php.ini`:',
263
+			'    detect_unicode = Off',
264
+			$iniMessage
265
+		);
266
+	}
267
+
268
+	if (extension_loaded('suhosin')) {
269
+		$suhosin = ini_get('suhosin.executor.include.whitelist');
270
+		$suhosinBlacklist = ini_get('suhosin.executor.include.blacklist');
271
+		if (false === stripos($suhosin, 'phar') && (!$suhosinBlacklist || false !== stripos($suhosinBlacklist, 'phar'))) {
272
+			$errors['suhosin'] = array(
273
+				'The suhosin.executor.include.whitelist setting is incorrect.',
274
+				'Add the following to the end of your `php.ini` or suhosin.ini (Example path [for Debian]: /etc/php5/cli/conf.d/suhosin.ini):',
275
+				'    suhosin.executor.include.whitelist = phar '.$suhosin,
276
+				$iniMessage
277
+			);
278
+		}
279
+	}
280
+
281
+	if (!function_exists('json_decode')) {
282
+		$errors['json'] = array(
283
+			'The json extension is missing.',
284
+			'Install it or recompile php without --disable-json'
285
+		);
286
+	}
287
+
288
+	if (!extension_loaded('Phar')) {
289
+		$errors['phar'] = array(
290
+			'The phar extension is missing.',
291
+			'Install it or recompile php without --disable-phar'
292
+		);
293
+	}
294
+
295
+	if (!extension_loaded('filter')) {
296
+		$errors['filter'] = array(
297
+			'The filter extension is missing.',
298
+			'Install it or recompile php without --disable-filter'
299
+		);
300
+	}
301
+
302
+	if (!extension_loaded('hash')) {
303
+		$errors['hash'] = array(
304
+			'The hash extension is missing.',
305
+			'Install it or recompile php without --disable-hash'
306
+		);
307
+	}
308
+
309
+	if (!extension_loaded('iconv') && !extension_loaded('mbstring')) {
310
+		$errors['iconv_mbstring'] = array(
311
+			'The iconv OR mbstring extension is required and both are missing.',
312
+			'Install either of them or recompile php without --disable-iconv'
313
+		);
314
+	}
315
+
316
+	if (!ini_get('allow_url_fopen')) {
317
+		$errors['allow_url_fopen'] = array(
318
+			'The allow_url_fopen setting is incorrect.',
319
+			'Add the following to the end of your `php.ini`:',
320
+			'    allow_url_fopen = On',
321
+			$iniMessage
322
+		);
323
+	}
324
+
325
+	if (extension_loaded('ionCube Loader') && ioncube_loader_iversion() < 40009) {
326
+		$ioncube = ioncube_loader_version();
327
+		$errors['ioncube'] = array(
328
+			'Your ionCube Loader extension ('.$ioncube.') is incompatible with Phar files.',
329
+			'Upgrade to ionCube 4.0.9 or higher or remove this line (path may be different) from your `php.ini` to disable it:',
330
+			'    zend_extension = /usr/lib/php5/20090626+lfs/ioncube_loader_lin_5.3.so',
331
+			$iniMessage
332
+		);
333
+	}
334
+
335
+	if (version_compare(PHP_VERSION, '5.3.2', '<')) {
336
+		$errors['php'] = array(
337
+			'Your PHP ('.PHP_VERSION.') is too old, you must upgrade to PHP 5.3.2 or higher.'
338
+		);
339
+	}
340
+
341
+	if (version_compare(PHP_VERSION, '5.3.4', '<')) {
342
+		$warnings['php'] = array(
343
+			'Your PHP ('.PHP_VERSION.') is quite old, upgrading to PHP 5.3.4 or higher is recommended.',
344
+			'Composer works with 5.3.2+ for most people, but there might be edge case issues.'
345
+		);
346
+	}
347
+
348
+	if (!extension_loaded('openssl')) {
349
+		$warnings['openssl'] = array(
350
+			'The openssl extension is missing, which means that secure HTTPS transfers are impossible.',
351
+			'If possible you should enable it or recompile php with --with-openssl'
352
+		);
353
+	}
354
+
355
+	if (extension_loaded('openssl') && OPENSSL_VERSION_NUMBER < 0x1000100f) {
356
+		// Attempt to parse version number out, fallback to whole string value.
357
+		$opensslVersion = trim(strstr(OPENSSL_VERSION_TEXT, ' '));
358
+		$opensslVersion = substr($opensslVersion, 0, strpos($opensslVersion, ' '));
359
+		$opensslVersion = $opensslVersion ? $opensslVersion : OPENSSL_VERSION_TEXT;
360
+
361
+		$warnings['openssl_version'] = array(
362
+			'The OpenSSL library ('.$opensslVersion.') used by PHP does not support TLSv1.2 or TLSv1.1.',
363
+			'If possible you should upgrade OpenSSL to version 1.0.1 or above.'
364
+		);
365
+	}
366
+
367
+	if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) {
368
+		$warnings['apc_cli'] = array(
369
+			'The apc.enable_cli setting is incorrect.',
370
+			'Add the following to the end of your `php.ini`:',
371
+			'    apc.enable_cli = Off',
372
+			$iniMessage
373
+		);
374
+	}
375
+
376
+	if (!$install && extension_loaded('xdebug')) {
377
+		$warnings['xdebug_loaded'] = array(
378
+			'The xdebug extension is loaded, this can slow down Composer a little.',
379
+			'Disabling it when using Composer is recommended.'
380
+		);
381
+
382
+		if (ini_get('xdebug.profiler_enabled')) {
383
+			$warnings['xdebug_profile'] = array(
384
+				'The xdebug.profiler_enabled setting is enabled, this can slow down Composer a lot.',
385
+				'Add the following to the end of your `php.ini` to disable it:',
386
+				'    xdebug.profiler_enabled = 0',
387
+				$iniMessage
388
+			);
389
+		}
390
+	}
391
+
392
+	if (!extension_loaded('zlib')) {
393
+		$warnings['zlib'] = array(
394
+			'The zlib extension is not loaded, this can slow down Composer a lot.',
395
+			'If possible, install it or recompile php with --with-zlib',
396
+			$iniMessage
397
+		);
398
+	}
399
+
400
+	if (defined('PHP_WINDOWS_VERSION_BUILD')
401
+		&& (version_compare(PHP_VERSION, '7.2.23', '<')
402
+		|| (version_compare(PHP_VERSION, '7.3.0', '>=')
403
+		&& version_compare(PHP_VERSION, '7.3.10', '<')))) {
404
+		$warnings['onedrive'] = array(
405
+			'The Windows OneDrive folder is not supported on PHP versions below 7.2.23 and 7.3.10.',
406
+			'Upgrade your PHP ('.PHP_VERSION.') to use this location with Composer.'
407
+		);
408
+	}
409
+
410
+	if (extension_loaded('uopz') && !(ini_get('uopz.disable') || ini_get('uopz.exit'))) {
411
+		$warnings['uopz'] = array(
412
+			'The uopz extension ignores exit calls and may not work with all Composer commands.',
413
+			'Disabling it when using Composer is recommended.'
414
+		);
415
+	}
416
+
417
+	ob_start();
418
+	phpinfo(INFO_GENERAL);
419
+	$phpinfo = ob_get_clean();
420
+	if (preg_match('{Configure Command(?: *</td><td class="v">| *=> *)(.*?)(?:</td>|$)}m', $phpinfo, $match)) {
421
+		$configure = $match[1];
422
+
423
+		if (false !== strpos($configure, '--enable-sigchild')) {
424
+			$warnings['sigchild'] = array(
425
+				'PHP was compiled with --enable-sigchild which can cause issues on some platforms.',
426
+				'Recompile it without this flag if possible, see also:',
427
+				'    https://bugs.php.net/bug.php?id=22999'
428
+			);
429
+		}
430
+
431
+		if (false !== strpos($configure, '--with-curlwrappers')) {
432
+			$warnings['curlwrappers'] = array(
433
+				'PHP was compiled with --with-curlwrappers which will cause issues with HTTP authentication and GitHub.',
434
+				'Recompile it without this flag if possible'
435
+			);
436
+		}
437
+	}
438
+
439
+	// Stringify the message arrays
440
+	foreach ($errors as $key => $value) {
441
+		$errors[$key] = PHP_EOL.implode(PHP_EOL, $value);
442
+	}
443
+
444
+	foreach ($warnings as $key => $value) {
445
+		$warnings[$key] = PHP_EOL.implode(PHP_EOL, $value);
446
+	}
447
+
448
+	return !empty($errors) || !empty($warnings);
449 449
 }
450 450
 
451 451
 
@@ -456,10 +456,10 @@  discard block
 block discarded – undo
456 456
  */
457 457
 function outputIssues($issues)
458 458
 {
459
-    foreach ($issues as $issue) {
460
-        out($issue, 'info');
461
-    }
462
-    out('');
459
+	foreach ($issues as $issue) {
460
+		out($issue, 'info');
461
+	}
462
+	out('');
463 463
 }
464 464
 
465 465
 /**
@@ -469,11 +469,11 @@  discard block
 block discarded – undo
469 469
  */
470 470
 function showWarnings($warnings)
471 471
 {
472
-    if (!empty($warnings)) {
473
-        out('Some settings on your machine may cause stability issues with Composer.', 'error');
474
-        out('If you encounter issues, try to change the following:', 'error');
475
-        outputIssues($warnings);
476
-    }
472
+	if (!empty($warnings)) {
473
+		out('Some settings on your machine may cause stability issues with Composer.', 'error');
474
+		out('If you encounter issues, try to change the following:', 'error');
475
+		outputIssues($warnings);
476
+	}
477 477
 }
478 478
 
479 479
 /**
@@ -483,10 +483,10 @@  discard block
 block discarded – undo
483 483
  */
484 484
 function showSecurityWarning($disableTls)
485 485
 {
486
-    if ($disableTls) {
487
-        out('You have instructed the Installer not to enforce SSL/TLS security on remote HTTPS requests.', 'info');
488
-        out('This will leave all downloads during installation vulnerable to Man-In-The-Middle (MITM) attacks', 'info');
489
-    }
486
+	if ($disableTls) {
487
+		out('You have instructed the Installer not to enforce SSL/TLS security on remote HTTPS requests.', 'info');
488
+		out('This will leave all downloads during installation vulnerable to Man-In-The-Middle (MITM) attacks', 'info');
489
+	}
490 490
 }
491 491
 
492 492
 /**
@@ -494,23 +494,23 @@  discard block
 block discarded – undo
494 494
  */
495 495
 function out($text, $color = null, $newLine = true)
496 496
 {
497
-    $styles = array(
498
-        'success' => "\033[0;32m%s\033[0m",
499
-        'error' => "\033[31;31m%s\033[0m",
500
-        'info' => "\033[33;33m%s\033[0m"
501
-    );
497
+	$styles = array(
498
+		'success' => "\033[0;32m%s\033[0m",
499
+		'error' => "\033[31;31m%s\033[0m",
500
+		'info' => "\033[33;33m%s\033[0m"
501
+	);
502 502
 
503
-    $format = '%s';
503
+	$format = '%s';
504 504
 
505
-    if (isset($styles[$color]) && USE_ANSI) {
506
-        $format = $styles[$color];
507
-    }
505
+	if (isset($styles[$color]) && USE_ANSI) {
506
+		$format = $styles[$color];
507
+	}
508 508
 
509
-    if ($newLine) {
510
-        $format .= PHP_EOL;
511
-    }
509
+	if ($newLine) {
510
+		$format .= PHP_EOL;
511
+	}
512 512
 
513
-    printf($format, $text);
513
+	printf($format, $text);
514 514
 }
515 515
 
516 516
 /**
@@ -520,26 +520,26 @@  discard block
 block discarded – undo
520 520
  */
521 521
 function getHomeDir()
522 522
 {
523
-    $home = getenv('COMPOSER_HOME');
524
-
525
-    if (!$home) {
526
-        $userDir = getUserDir();
527
-
528
-        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
529
-            $home = $userDir.'/Composer';
530
-        } else {
531
-            $home = $userDir.'/.composer';
532
-
533
-            if (!is_dir($home) && useXdg()) {
534
-                // XDG Base Directory Specifications
535
-                if (!($xdgConfig = getenv('XDG_CONFIG_HOME'))) {
536
-                    $xdgConfig = $userDir.'/.config';
537
-                }
538
-                $home = $xdgConfig.'/composer';
539
-            }
540
-        }
541
-    }
542
-    return $home;
523
+	$home = getenv('COMPOSER_HOME');
524
+
525
+	if (!$home) {
526
+		$userDir = getUserDir();
527
+
528
+		if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
529
+			$home = $userDir.'/Composer';
530
+		} else {
531
+			$home = $userDir.'/.composer';
532
+
533
+			if (!is_dir($home) && useXdg()) {
534
+				// XDG Base Directory Specifications
535
+				if (!($xdgConfig = getenv('XDG_CONFIG_HOME'))) {
536
+					$xdgConfig = $userDir.'/.config';
537
+				}
538
+				$home = $xdgConfig.'/composer';
539
+			}
540
+		}
541
+	}
542
+	return $home;
543 543
 }
544 544
 
545 545
 /**
@@ -550,14 +550,14 @@  discard block
 block discarded – undo
550 550
  */
551 551
 function getUserDir()
552 552
 {
553
-    $userEnv = defined('PHP_WINDOWS_VERSION_MAJOR') ? 'APPDATA' : 'HOME';
554
-    $userDir = getenv($userEnv);
553
+	$userEnv = defined('PHP_WINDOWS_VERSION_MAJOR') ? 'APPDATA' : 'HOME';
554
+	$userDir = getenv($userEnv);
555 555
 
556
-    if (!$userDir) {
557
-        throw new RuntimeException('The '.$userEnv.' or COMPOSER_HOME environment variable must be set for composer to run correctly');
558
-    }
556
+	if (!$userDir) {
557
+		throw new RuntimeException('The '.$userEnv.' or COMPOSER_HOME environment variable must be set for composer to run correctly');
558
+	}
559 559
 
560
-    return rtrim(strtr($userDir, '\\', '/'), '/');
560
+	return rtrim(strtr($userDir, '\\', '/'), '/');
561 561
 }
562 562
 
563 563
 /**
@@ -565,565 +565,565 @@  discard block
 block discarded – undo
565 565
  */
566 566
 function useXdg()
567 567
 {
568
-    foreach (array_keys($_SERVER) as $key) {
569
-        if (substr($key, 0, 4) === 'XDG_') {
570
-            return true;
571
-        }
572
-    }
573
-    return false;
568
+	foreach (array_keys($_SERVER) as $key) {
569
+		if (substr($key, 0, 4) === 'XDG_') {
570
+			return true;
571
+		}
572
+	}
573
+	return false;
574 574
 }
575 575
 
576 576
 function validateCaFile($contents)
577 577
 {
578
-    // assume the CA is valid if php is vulnerable to
579
-    // https://www.sektioneins.de/advisories/advisory-012013-php-openssl_x509_parse-memory-corruption-vulnerability.html
580
-    if (
581
-        PHP_VERSION_ID <= 50327
582
-        || (PHP_VERSION_ID >= 50400 && PHP_VERSION_ID < 50422)
583
-        || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50506)
584
-    ) {
585
-        return !empty($contents);
586
-    }
587
-
588
-    return (bool) openssl_x509_parse($contents);
578
+	// assume the CA is valid if php is vulnerable to
579
+	// https://www.sektioneins.de/advisories/advisory-012013-php-openssl_x509_parse-memory-corruption-vulnerability.html
580
+	if (
581
+		PHP_VERSION_ID <= 50327
582
+		|| (PHP_VERSION_ID >= 50400 && PHP_VERSION_ID < 50422)
583
+		|| (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50506)
584
+	) {
585
+		return !empty($contents);
586
+	}
587
+
588
+	return (bool) openssl_x509_parse($contents);
589 589
 }
590 590
 
591 591
 class Installer
592 592
 {
593
-    private $quiet;
594
-    private $disableTls;
595
-    private $cafile;
596
-    private $installPath;
597
-    private $target;
598
-    private $tmpFile;
599
-    private $baseUrl;
600
-    private $algo;
601
-    private $errHandler;
602
-    private $httpClient;
603
-    private $pubKeys = array();
604
-    private $installs = array();
605
-
606
-    /**
607
-     * Constructor - must not do anything that throws an exception
608
-     *
609
-     * @param bool $quiet Quiet mode
610
-     * @param bool $disableTls Bypass tls
611
-     * @param mixed $cafile Path to CA bundle, or false
612
-     */
613
-    public function __construct($quiet, $disableTls, $caFile)
614
-    {
615
-        if (($this->quiet = $quiet)) {
616
-            ob_start();
617
-        }
618
-        $this->disableTls = $disableTls;
619
-        $this->cafile = $caFile;
620
-        $this->errHandler = new ErrorHandler();
621
-    }
622
-
623
-    /**
624
-     * Runs the installer
625
-     *
626
-     * @param mixed $version Specific version to install, or false
627
-     * @param mixed $installDir Specific installation directory, or false
628
-     * @param string $filename Specific filename to save to, or composer.phar
629
-     * @param string $channel Specific version channel to use
630
-     * @throws Exception If anything other than a RuntimeException is caught
631
-     *
632
-     * @return bool If the installation succeeded
633
-     */
634
-    public function run($version, $installDir, $filename, $channel)
635
-    {
636
-        try {
637
-            $this->initTargets($installDir, $filename);
638
-            $this->initTls();
639
-            $this->httpClient = new HttpClient($this->disableTls, $this->cafile);
640
-            $result = $this->install($version, $channel);
641
-
642
-            if ($result && $channel !== 'stable' && !$version && defined('PHP_BINARY')) {
643
-                $null = (defined('PHP_WINDOWS_VERSION_MAJOR') ? 'NUL' : '/dev/null');
644
-                @exec(escapeshellarg(PHP_BINARY) .' '.escapeshellarg($this->target).' self-update --'.$channel.' --set-channel-only -q > '.$null.' 2> '.$null, $output);
645
-            }
646
-        } catch (Exception $e) {
647
-            $result = false;
648
-        }
649
-
650
-        // Always clean up
651
-        $this->cleanUp($result);
652
-
653
-        if (isset($e)) {
654
-            // Rethrow anything that is not a RuntimeException
655
-            if (!$e instanceof RuntimeException) {
656
-                throw $e;
657
-            }
658
-            out($e->getMessage(), 'error');
659
-        }
660
-        return $result;
661
-    }
662
-
663
-    /**
664
-     * Initialization methods to set the required filenames and composer url
665
-     *
666
-     * @param mixed $installDir Specific installation directory, or false
667
-     * @param string $filename Specific filename to save to, or composer.phar
668
-     * @throws RuntimeException If the installation directory is not writable
669
-     */
670
-    protected function initTargets($installDir, $filename)
671
-    {
672
-        $this->installPath = (is_dir($installDir) ? rtrim($installDir, '/').'/' : '').$filename;
673
-        $installDir = realpath($installDir) ? realpath($installDir) : getcwd();
674
-
675
-        if (!is_writeable($installDir)) {
676
-            throw new RuntimeException('The installation directory "'.$installDir.'" is not writable');
677
-        }
678
-
679
-        $this->target = $installDir.DIRECTORY_SEPARATOR.$filename;
680
-        $this->tmpFile = $installDir.DIRECTORY_SEPARATOR.basename($this->target, '.phar').'-temp.phar';
681
-
682
-        $uriScheme = $this->disableTls ? 'http' : 'https';
683
-        $this->baseUrl = $uriScheme.'://getcomposer.org';
684
-    }
685
-
686
-    /**
687
-     * A wrapper around methods to check tls and write public keys
688
-     * @throws RuntimeException If SHA384 is not supported
689
-     */
690
-    protected function initTls()
691
-    {
692
-        if ($this->disableTls) {
693
-            return;
694
-        }
695
-
696
-        if (!in_array('sha384', array_map('strtolower', openssl_get_md_methods()))) {
697
-            throw new RuntimeException('SHA384 is not supported by your openssl extension');
698
-        }
699
-
700
-        $this->algo = defined('OPENSSL_ALGO_SHA384') ? OPENSSL_ALGO_SHA384 : 'SHA384';
701
-        $home = $this->getComposerHome();
702
-
703
-        $this->pubKeys = array(
704
-            'dev' => $this->installKey(self::getPKDev(), $home, 'keys.dev.pub'),
705
-            'tags' => $this->installKey(self::getPKTags(), $home, 'keys.tags.pub')
706
-        );
707
-
708
-        if (empty($this->cafile) && !HttpClient::getSystemCaRootBundlePath()) {
709
-            $this->cafile = $this->installKey(HttpClient::getPackagedCaFile(), $home, 'cacert.pem');
710
-        }
711
-    }
712
-
713
-    /**
714
-     * Returns the Composer home directory, creating it if required
715
-     * @throws RuntimeException If the directory cannot be created
716
-     *
717
-     * @return string
718
-     */
719
-    protected function getComposerHome()
720
-    {
721
-        $home = getHomeDir();
722
-
723
-        if (!is_dir($home)) {
724
-            $this->errHandler->start();
725
-
726
-            if (!mkdir($home, 0777, true)) {
727
-                throw new RuntimeException(sprintf(
728
-                    'Unable to create Composer home directory "%s": %s',
729
-                    $home,
730
-                    $this->errHandler->message
731
-                ));
732
-            }
733
-            $this->installs[] = $home;
734
-            $this->errHandler->stop();
735
-        }
736
-        return $home;
737
-    }
738
-
739
-    /**
740
-     * Writes public key data to disc
741
-     *
742
-     * @param string $data The public key(s) in pem format
743
-     * @param string $path The directory to write to
744
-     * @param string $filename The name of the file
745
-     * @throws RuntimeException If the file cannot be written
746
-     *
747
-     * @return string The path to the saved data
748
-     */
749
-    protected function installKey($data, $path, $filename)
750
-    {
751
-        $this->errHandler->start();
752
-
753
-        $target = $path.DIRECTORY_SEPARATOR.$filename;
754
-        $installed = file_exists($target);
755
-        $write = file_put_contents($target, $data, LOCK_EX);
756
-        @chmod($target, 0644);
757
-
758
-        $this->errHandler->stop();
759
-
760
-        if (!$write) {
761
-            throw new RuntimeException(sprintf('Unable to write %s to: %s', $filename, $path));
762
-        }
763
-
764
-        if (!$installed) {
765
-            $this->installs[] = $target;
766
-        }
767
-
768
-        return $target;
769
-    }
770
-
771
-    /**
772
-     * The main install function
773
-     *
774
-     * @param mixed $version Specific version to install, or false
775
-     * @param string $channel Version channel to use
776
-     *
777
-     * @return bool If the installation succeeded
778
-     */
779
-    protected function install($version, $channel)
780
-    {
781
-        $retries = 3;
782
-        $result = false;
783
-        $infoMsg = 'Downloading...';
784
-        $infoType = 'info';
785
-
786
-        while ($retries--) {
787
-            if (!$this->quiet) {
788
-                out($infoMsg, $infoType);
789
-                $infoMsg = 'Retrying...';
790
-                $infoType = 'error';
791
-            }
792
-
793
-            if (!$this->getVersion($channel, $version, $url, $error)) {
794
-                out($error, 'error');
795
-                continue;
796
-            }
797
-
798
-            if (!$this->downloadToTmp($url, $signature, $error)) {
799
-                out($error, 'error');
800
-                continue;
801
-            }
802
-
803
-            if (!$this->verifyAndSave($version, $signature, $error)) {
804
-                out($error, 'error');
805
-                continue;
806
-            }
807
-
808
-            $result = true;
809
-            break;
810
-        }
811
-
812
-        if (!$this->quiet) {
813
-            if ($result) {
814
-                out(PHP_EOL."Composer (version {$version}) successfully installed to: {$this->target}", 'success');
815
-                out("Use it: php {$this->installPath}", 'info');
816
-                out('');
817
-            } else {
818
-                out('The download failed repeatedly, aborting.', 'error');
819
-            }
820
-        }
821
-        return $result;
822
-    }
823
-
824
-    /**
825
-     * Sets the version url, downloading version data if required
826
-     *
827
-     * @param string $channel Version channel to use
828
-     * @param false|string $version Version to install, or set by method
829
-     * @param null|string $url The versioned url, set by method
830
-     * @param null|string $error Set by method on failure
831
-     *
832
-     * @return bool If the operation succeeded
833
-     */
834
-    protected function getVersion($channel, &$version, &$url, &$error)
835
-    {
836
-        $error = '';
837
-
838
-        if ($version) {
839
-            if (empty($url)) {
840
-                $url = $this->baseUrl."/download/{$version}/composer.phar";
841
-            }
842
-            return true;
843
-        }
844
-
845
-        $this->errHandler->start();
846
-
847
-        if ($this->downloadVersionData($data, $error)) {
848
-            $this->parseVersionData($data, $channel, $version, $url);
849
-        }
850
-
851
-        $this->errHandler->stop();
852
-        return empty($error);
853
-    }
854
-
855
-    /**
856
-     * Downloads and json-decodes version data
857
-     *
858
-     * @param null|array $data Downloaded version data, set by method
859
-     * @param null|string $error Set by method on failure
860
-     *
861
-     * @return bool If the operation succeeded
862
-     */
863
-    protected function downloadVersionData(&$data, &$error)
864
-    {
865
-        $url = $this->baseUrl.'/versions';
866
-        $errFmt = 'The "%s" file could not be %s: %s';
867
-
868
-        if (!$json = $this->httpClient->get($url)) {
869
-            $error = sprintf($errFmt, $url, 'downloaded', $this->errHandler->message);
870
-            return false;
871
-        }
872
-
873
-        if (!$data = json_decode($json, true)) {
874
-            $error = sprintf($errFmt, $url, 'json-decoded', $this->getJsonError());
875
-            return false;
876
-        }
877
-        return true;
878
-    }
879
-
880
-    /**
881
-     * A wrapper around the methods needed to download and save the phar
882
-     *
883
-     * @param string $url The versioned download url
884
-     * @param null|string $signature Set by method on successful download
885
-     * @param null|string $error Set by method on failure
886
-     *
887
-     * @return bool If the operation succeeded
888
-     */
889
-    protected function downloadToTmp($url, &$signature, &$error)
890
-    {
891
-        $error = '';
892
-        $errFmt = 'The "%s" file could not be downloaded: %s';
893
-        $sigUrl = $url.'.sig';
894
-        $this->errHandler->start();
895
-
896
-        if (!$fh = fopen($this->tmpFile, 'w')) {
897
-            $error = sprintf('Could not create file "%s": %s', $this->tmpFile, $this->errHandler->message);
898
-
899
-        } elseif (!$this->getSignature($sigUrl, $signature)) {
900
-            $error = sprintf($errFmt, $sigUrl, $this->errHandler->message);
901
-
902
-        } elseif (!fwrite($fh, $this->httpClient->get($url))) {
903
-            $error = sprintf($errFmt, $url, $this->errHandler->message);
904
-        }
905
-
906
-        if (is_resource($fh)) {
907
-            fclose($fh);
908
-        }
909
-        $this->errHandler->stop();
910
-        return empty($error);
911
-    }
912
-
913
-    /**
914
-     * Verifies the downloaded file and saves it to the target location
915
-     *
916
-     * @param string $version The composer version downloaded
917
-     * @param string $signature The digital signature to check
918
-     * @param null|string $error Set by method on failure
919
-     *
920
-     * @return bool If the operation succeeded
921
-     */
922
-    protected function verifyAndSave($version, $signature, &$error)
923
-    {
924
-        $error = '';
925
-
926
-        if (!$this->validatePhar($this->tmpFile, $pharError)) {
927
-            $error = 'The download is corrupt: '.$pharError;
928
-
929
-        } elseif (!$this->verifySignature($version, $signature, $this->tmpFile)) {
930
-            $error = 'Signature mismatch, could not verify the phar file integrity';
931
-
932
-        } else {
933
-            $this->errHandler->start();
934
-
935
-            if (!rename($this->tmpFile, $this->target)) {
936
-                $error = sprintf('Could not write to file "%s": %s', $this->target, $this->errHandler->message);
937
-            }
938
-            chmod($this->target, 0755);
939
-            $this->errHandler->stop();
940
-        }
941
-
942
-        return empty($error);
943
-    }
944
-
945
-    /**
946
-     * Parses an array of version data to match the required channel
947
-     *
948
-     * @param array $data Downloaded version data
949
-     * @param mixed $channel Version channel to use
950
-     * @param false|string $version Set by method
951
-     * @param mixed $url The versioned url, set by method
952
-     */
953
-    protected function parseVersionData(array $data, $channel, &$version, &$url)
954
-    {
955
-        foreach ($data[$channel] as $candidate) {
956
-            if ($candidate['min-php'] <= PHP_VERSION_ID) {
957
-                $version = $candidate['version'];
958
-                $url = $this->baseUrl.$candidate['path'];
959
-                break;
960
-            }
961
-        }
962
-
963
-        if (!$version) {
964
-            $error = sprintf(
965
-                'None of the %d %s version(s) of Composer matches your PHP version (%s / ID: %d)',
966
-                count($data[$channel]),
967
-                $channel,
968
-                PHP_VERSION,
969
-                PHP_VERSION_ID
970
-            );
971
-            throw new RuntimeException($error);
972
-        }
973
-    }
974
-
975
-    /**
976
-     * Downloads the digital signature of required phar file
977
-     *
978
-     * @param string $url The signature url
979
-     * @param null|string $signature Set by method on success
980
-     *
981
-     * @return bool If the download succeeded
982
-     */
983
-    protected function getSignature($url, &$signature)
984
-    {
985
-        if (!$result = $this->disableTls) {
986
-            $signature = $this->httpClient->get($url);
987
-
988
-            if ($signature) {
989
-                $signature = json_decode($signature, true);
990
-                $signature = base64_decode($signature['sha384']);
991
-                $result = true;
992
-            }
993
-        }
994
-
995
-        return $result;
996
-    }
997
-
998
-    /**
999
-     * Verifies the signature of the downloaded phar
1000
-     *
1001
-     * @param string $version The composer versione
1002
-     * @param string $signature The downloaded digital signature
1003
-     * @param string $file The temp phar file
1004
-     *
1005
-     * @return bool If the operation succeeded
1006
-     */
1007
-    protected function verifySignature($version, $signature, $file)
1008
-    {
1009
-        if (!$result = $this->disableTls) {
1010
-            $path = preg_match('{^[0-9a-f]{40}$}', $version) ? $this->pubKeys['dev'] : $this->pubKeys['tags'];
1011
-            $pubkeyid = openssl_pkey_get_public('file://'.$path);
1012
-
1013
-            $result = 1 === openssl_verify(
1014
-                file_get_contents($file),
1015
-                $signature,
1016
-                $pubkeyid,
1017
-                $this->algo
1018
-            );
1019
-
1020
-            openssl_free_key($pubkeyid);
1021
-        }
1022
-
1023
-        return $result;
1024
-    }
1025
-
1026
-    /**
1027
-     * Validates the downloaded phar file
1028
-     *
1029
-     * @param string $pharFile The temp phar file
1030
-     * @param null|string $error Set by method on failure
1031
-     *
1032
-     * @return bool If the operation succeeded
1033
-     */
1034
-    protected function validatePhar($pharFile, &$error)
1035
-    {
1036
-        if (ini_get('phar.readonly')) {
1037
-            return true;
1038
-        }
1039
-
1040
-        try {
1041
-            // Test the phar validity
1042
-            $phar = new Phar($pharFile);
1043
-            // Free the variable to unlock the file
1044
-            unset($phar);
1045
-            $result = true;
1046
-
1047
-        } catch (Exception $e) {
1048
-            if (!$e instanceof UnexpectedValueException && !$e instanceof PharException) {
1049
-                throw $e;
1050
-            }
1051
-            $error = $e->getMessage();
1052
-            $result = false;
1053
-        }
1054
-        return $result;
1055
-    }
1056
-
1057
-    /**
1058
-     * Returns a string representation of the last json error
1059
-     *
1060
-     * @return string The error string or code
1061
-     */
1062
-    protected function getJsonError()
1063
-    {
1064
-        if (function_exists('json_last_error_msg')) {
1065
-            return json_last_error_msg();
1066
-        } else {
1067
-            return 'json_last_error = '.json_last_error();
1068
-        }
1069
-    }
1070
-
1071
-    /**
1072
-     * Cleans up resources at the end of the installation
1073
-     *
1074
-     * @param bool $result If the installation succeeded
1075
-     */
1076
-    protected function cleanUp($result)
1077
-    {
1078
-        if (!$result) {
1079
-            // Output buffered errors
1080
-            if ($this->quiet) {
1081
-                $this->outputErrors();
1082
-            }
1083
-            // Clean up stuff we created
1084
-            $this->uninstall();
1085
-        }
1086
-    }
1087
-
1088
-    /**
1089
-     * Outputs unique errors when in quiet mode
1090
-     *
1091
-     */
1092
-    protected function outputErrors()
1093
-    {
1094
-        $errors = explode(PHP_EOL, ob_get_clean());
1095
-        $shown = array();
1096
-
1097
-        foreach ($errors as $error) {
1098
-            if ($error && !in_array($error, $shown)) {
1099
-                out($error, 'error');
1100
-                $shown[] = $error;
1101
-            }
1102
-        }
1103
-    }
1104
-
1105
-    /**
1106
-     * Uninstalls newly-created files and directories on failure
1107
-     *
1108
-     */
1109
-    protected function uninstall()
1110
-    {
1111
-        foreach (array_reverse($this->installs) as $target) {
1112
-            if (is_file($target)) {
1113
-                @unlink($target);
1114
-            } elseif (is_dir($target)) {
1115
-                @rmdir($target);
1116
-            }
1117
-        }
1118
-
1119
-        if (file_exists($this->tmpFile)) {
1120
-            @unlink($this->tmpFile);
1121
-        }
1122
-    }
1123
-
1124
-    public static function getPKDev()
1125
-    {
1126
-        return <<<PKDEV
593
+	private $quiet;
594
+	private $disableTls;
595
+	private $cafile;
596
+	private $installPath;
597
+	private $target;
598
+	private $tmpFile;
599
+	private $baseUrl;
600
+	private $algo;
601
+	private $errHandler;
602
+	private $httpClient;
603
+	private $pubKeys = array();
604
+	private $installs = array();
605
+
606
+	/**
607
+	 * Constructor - must not do anything that throws an exception
608
+	 *
609
+	 * @param bool $quiet Quiet mode
610
+	 * @param bool $disableTls Bypass tls
611
+	 * @param mixed $cafile Path to CA bundle, or false
612
+	 */
613
+	public function __construct($quiet, $disableTls, $caFile)
614
+	{
615
+		if (($this->quiet = $quiet)) {
616
+			ob_start();
617
+		}
618
+		$this->disableTls = $disableTls;
619
+		$this->cafile = $caFile;
620
+		$this->errHandler = new ErrorHandler();
621
+	}
622
+
623
+	/**
624
+	 * Runs the installer
625
+	 *
626
+	 * @param mixed $version Specific version to install, or false
627
+	 * @param mixed $installDir Specific installation directory, or false
628
+	 * @param string $filename Specific filename to save to, or composer.phar
629
+	 * @param string $channel Specific version channel to use
630
+	 * @throws Exception If anything other than a RuntimeException is caught
631
+	 *
632
+	 * @return bool If the installation succeeded
633
+	 */
634
+	public function run($version, $installDir, $filename, $channel)
635
+	{
636
+		try {
637
+			$this->initTargets($installDir, $filename);
638
+			$this->initTls();
639
+			$this->httpClient = new HttpClient($this->disableTls, $this->cafile);
640
+			$result = $this->install($version, $channel);
641
+
642
+			if ($result && $channel !== 'stable' && !$version && defined('PHP_BINARY')) {
643
+				$null = (defined('PHP_WINDOWS_VERSION_MAJOR') ? 'NUL' : '/dev/null');
644
+				@exec(escapeshellarg(PHP_BINARY) .' '.escapeshellarg($this->target).' self-update --'.$channel.' --set-channel-only -q > '.$null.' 2> '.$null, $output);
645
+			}
646
+		} catch (Exception $e) {
647
+			$result = false;
648
+		}
649
+
650
+		// Always clean up
651
+		$this->cleanUp($result);
652
+
653
+		if (isset($e)) {
654
+			// Rethrow anything that is not a RuntimeException
655
+			if (!$e instanceof RuntimeException) {
656
+				throw $e;
657
+			}
658
+			out($e->getMessage(), 'error');
659
+		}
660
+		return $result;
661
+	}
662
+
663
+	/**
664
+	 * Initialization methods to set the required filenames and composer url
665
+	 *
666
+	 * @param mixed $installDir Specific installation directory, or false
667
+	 * @param string $filename Specific filename to save to, or composer.phar
668
+	 * @throws RuntimeException If the installation directory is not writable
669
+	 */
670
+	protected function initTargets($installDir, $filename)
671
+	{
672
+		$this->installPath = (is_dir($installDir) ? rtrim($installDir, '/').'/' : '').$filename;
673
+		$installDir = realpath($installDir) ? realpath($installDir) : getcwd();
674
+
675
+		if (!is_writeable($installDir)) {
676
+			throw new RuntimeException('The installation directory "'.$installDir.'" is not writable');
677
+		}
678
+
679
+		$this->target = $installDir.DIRECTORY_SEPARATOR.$filename;
680
+		$this->tmpFile = $installDir.DIRECTORY_SEPARATOR.basename($this->target, '.phar').'-temp.phar';
681
+
682
+		$uriScheme = $this->disableTls ? 'http' : 'https';
683
+		$this->baseUrl = $uriScheme.'://getcomposer.org';
684
+	}
685
+
686
+	/**
687
+	 * A wrapper around methods to check tls and write public keys
688
+	 * @throws RuntimeException If SHA384 is not supported
689
+	 */
690
+	protected function initTls()
691
+	{
692
+		if ($this->disableTls) {
693
+			return;
694
+		}
695
+
696
+		if (!in_array('sha384', array_map('strtolower', openssl_get_md_methods()))) {
697
+			throw new RuntimeException('SHA384 is not supported by your openssl extension');
698
+		}
699
+
700
+		$this->algo = defined('OPENSSL_ALGO_SHA384') ? OPENSSL_ALGO_SHA384 : 'SHA384';
701
+		$home = $this->getComposerHome();
702
+
703
+		$this->pubKeys = array(
704
+			'dev' => $this->installKey(self::getPKDev(), $home, 'keys.dev.pub'),
705
+			'tags' => $this->installKey(self::getPKTags(), $home, 'keys.tags.pub')
706
+		);
707
+
708
+		if (empty($this->cafile) && !HttpClient::getSystemCaRootBundlePath()) {
709
+			$this->cafile = $this->installKey(HttpClient::getPackagedCaFile(), $home, 'cacert.pem');
710
+		}
711
+	}
712
+
713
+	/**
714
+	 * Returns the Composer home directory, creating it if required
715
+	 * @throws RuntimeException If the directory cannot be created
716
+	 *
717
+	 * @return string
718
+	 */
719
+	protected function getComposerHome()
720
+	{
721
+		$home = getHomeDir();
722
+
723
+		if (!is_dir($home)) {
724
+			$this->errHandler->start();
725
+
726
+			if (!mkdir($home, 0777, true)) {
727
+				throw new RuntimeException(sprintf(
728
+					'Unable to create Composer home directory "%s": %s',
729
+					$home,
730
+					$this->errHandler->message
731
+				));
732
+			}
733
+			$this->installs[] = $home;
734
+			$this->errHandler->stop();
735
+		}
736
+		return $home;
737
+	}
738
+
739
+	/**
740
+	 * Writes public key data to disc
741
+	 *
742
+	 * @param string $data The public key(s) in pem format
743
+	 * @param string $path The directory to write to
744
+	 * @param string $filename The name of the file
745
+	 * @throws RuntimeException If the file cannot be written
746
+	 *
747
+	 * @return string The path to the saved data
748
+	 */
749
+	protected function installKey($data, $path, $filename)
750
+	{
751
+		$this->errHandler->start();
752
+
753
+		$target = $path.DIRECTORY_SEPARATOR.$filename;
754
+		$installed = file_exists($target);
755
+		$write = file_put_contents($target, $data, LOCK_EX);
756
+		@chmod($target, 0644);
757
+
758
+		$this->errHandler->stop();
759
+
760
+		if (!$write) {
761
+			throw new RuntimeException(sprintf('Unable to write %s to: %s', $filename, $path));
762
+		}
763
+
764
+		if (!$installed) {
765
+			$this->installs[] = $target;
766
+		}
767
+
768
+		return $target;
769
+	}
770
+
771
+	/**
772
+	 * The main install function
773
+	 *
774
+	 * @param mixed $version Specific version to install, or false
775
+	 * @param string $channel Version channel to use
776
+	 *
777
+	 * @return bool If the installation succeeded
778
+	 */
779
+	protected function install($version, $channel)
780
+	{
781
+		$retries = 3;
782
+		$result = false;
783
+		$infoMsg = 'Downloading...';
784
+		$infoType = 'info';
785
+
786
+		while ($retries--) {
787
+			if (!$this->quiet) {
788
+				out($infoMsg, $infoType);
789
+				$infoMsg = 'Retrying...';
790
+				$infoType = 'error';
791
+			}
792
+
793
+			if (!$this->getVersion($channel, $version, $url, $error)) {
794
+				out($error, 'error');
795
+				continue;
796
+			}
797
+
798
+			if (!$this->downloadToTmp($url, $signature, $error)) {
799
+				out($error, 'error');
800
+				continue;
801
+			}
802
+
803
+			if (!$this->verifyAndSave($version, $signature, $error)) {
804
+				out($error, 'error');
805
+				continue;
806
+			}
807
+
808
+			$result = true;
809
+			break;
810
+		}
811
+
812
+		if (!$this->quiet) {
813
+			if ($result) {
814
+				out(PHP_EOL."Composer (version {$version}) successfully installed to: {$this->target}", 'success');
815
+				out("Use it: php {$this->installPath}", 'info');
816
+				out('');
817
+			} else {
818
+				out('The download failed repeatedly, aborting.', 'error');
819
+			}
820
+		}
821
+		return $result;
822
+	}
823
+
824
+	/**
825
+	 * Sets the version url, downloading version data if required
826
+	 *
827
+	 * @param string $channel Version channel to use
828
+	 * @param false|string $version Version to install, or set by method
829
+	 * @param null|string $url The versioned url, set by method
830
+	 * @param null|string $error Set by method on failure
831
+	 *
832
+	 * @return bool If the operation succeeded
833
+	 */
834
+	protected function getVersion($channel, &$version, &$url, &$error)
835
+	{
836
+		$error = '';
837
+
838
+		if ($version) {
839
+			if (empty($url)) {
840
+				$url = $this->baseUrl."/download/{$version}/composer.phar";
841
+			}
842
+			return true;
843
+		}
844
+
845
+		$this->errHandler->start();
846
+
847
+		if ($this->downloadVersionData($data, $error)) {
848
+			$this->parseVersionData($data, $channel, $version, $url);
849
+		}
850
+
851
+		$this->errHandler->stop();
852
+		return empty($error);
853
+	}
854
+
855
+	/**
856
+	 * Downloads and json-decodes version data
857
+	 *
858
+	 * @param null|array $data Downloaded version data, set by method
859
+	 * @param null|string $error Set by method on failure
860
+	 *
861
+	 * @return bool If the operation succeeded
862
+	 */
863
+	protected function downloadVersionData(&$data, &$error)
864
+	{
865
+		$url = $this->baseUrl.'/versions';
866
+		$errFmt = 'The "%s" file could not be %s: %s';
867
+
868
+		if (!$json = $this->httpClient->get($url)) {
869
+			$error = sprintf($errFmt, $url, 'downloaded', $this->errHandler->message);
870
+			return false;
871
+		}
872
+
873
+		if (!$data = json_decode($json, true)) {
874
+			$error = sprintf($errFmt, $url, 'json-decoded', $this->getJsonError());
875
+			return false;
876
+		}
877
+		return true;
878
+	}
879
+
880
+	/**
881
+	 * A wrapper around the methods needed to download and save the phar
882
+	 *
883
+	 * @param string $url The versioned download url
884
+	 * @param null|string $signature Set by method on successful download
885
+	 * @param null|string $error Set by method on failure
886
+	 *
887
+	 * @return bool If the operation succeeded
888
+	 */
889
+	protected function downloadToTmp($url, &$signature, &$error)
890
+	{
891
+		$error = '';
892
+		$errFmt = 'The "%s" file could not be downloaded: %s';
893
+		$sigUrl = $url.'.sig';
894
+		$this->errHandler->start();
895
+
896
+		if (!$fh = fopen($this->tmpFile, 'w')) {
897
+			$error = sprintf('Could not create file "%s": %s', $this->tmpFile, $this->errHandler->message);
898
+
899
+		} elseif (!$this->getSignature($sigUrl, $signature)) {
900
+			$error = sprintf($errFmt, $sigUrl, $this->errHandler->message);
901
+
902
+		} elseif (!fwrite($fh, $this->httpClient->get($url))) {
903
+			$error = sprintf($errFmt, $url, $this->errHandler->message);
904
+		}
905
+
906
+		if (is_resource($fh)) {
907
+			fclose($fh);
908
+		}
909
+		$this->errHandler->stop();
910
+		return empty($error);
911
+	}
912
+
913
+	/**
914
+	 * Verifies the downloaded file and saves it to the target location
915
+	 *
916
+	 * @param string $version The composer version downloaded
917
+	 * @param string $signature The digital signature to check
918
+	 * @param null|string $error Set by method on failure
919
+	 *
920
+	 * @return bool If the operation succeeded
921
+	 */
922
+	protected function verifyAndSave($version, $signature, &$error)
923
+	{
924
+		$error = '';
925
+
926
+		if (!$this->validatePhar($this->tmpFile, $pharError)) {
927
+			$error = 'The download is corrupt: '.$pharError;
928
+
929
+		} elseif (!$this->verifySignature($version, $signature, $this->tmpFile)) {
930
+			$error = 'Signature mismatch, could not verify the phar file integrity';
931
+
932
+		} else {
933
+			$this->errHandler->start();
934
+
935
+			if (!rename($this->tmpFile, $this->target)) {
936
+				$error = sprintf('Could not write to file "%s": %s', $this->target, $this->errHandler->message);
937
+			}
938
+			chmod($this->target, 0755);
939
+			$this->errHandler->stop();
940
+		}
941
+
942
+		return empty($error);
943
+	}
944
+
945
+	/**
946
+	 * Parses an array of version data to match the required channel
947
+	 *
948
+	 * @param array $data Downloaded version data
949
+	 * @param mixed $channel Version channel to use
950
+	 * @param false|string $version Set by method
951
+	 * @param mixed $url The versioned url, set by method
952
+	 */
953
+	protected function parseVersionData(array $data, $channel, &$version, &$url)
954
+	{
955
+		foreach ($data[$channel] as $candidate) {
956
+			if ($candidate['min-php'] <= PHP_VERSION_ID) {
957
+				$version = $candidate['version'];
958
+				$url = $this->baseUrl.$candidate['path'];
959
+				break;
960
+			}
961
+		}
962
+
963
+		if (!$version) {
964
+			$error = sprintf(
965
+				'None of the %d %s version(s) of Composer matches your PHP version (%s / ID: %d)',
966
+				count($data[$channel]),
967
+				$channel,
968
+				PHP_VERSION,
969
+				PHP_VERSION_ID
970
+			);
971
+			throw new RuntimeException($error);
972
+		}
973
+	}
974
+
975
+	/**
976
+	 * Downloads the digital signature of required phar file
977
+	 *
978
+	 * @param string $url The signature url
979
+	 * @param null|string $signature Set by method on success
980
+	 *
981
+	 * @return bool If the download succeeded
982
+	 */
983
+	protected function getSignature($url, &$signature)
984
+	{
985
+		if (!$result = $this->disableTls) {
986
+			$signature = $this->httpClient->get($url);
987
+
988
+			if ($signature) {
989
+				$signature = json_decode($signature, true);
990
+				$signature = base64_decode($signature['sha384']);
991
+				$result = true;
992
+			}
993
+		}
994
+
995
+		return $result;
996
+	}
997
+
998
+	/**
999
+	 * Verifies the signature of the downloaded phar
1000
+	 *
1001
+	 * @param string $version The composer versione
1002
+	 * @param string $signature The downloaded digital signature
1003
+	 * @param string $file The temp phar file
1004
+	 *
1005
+	 * @return bool If the operation succeeded
1006
+	 */
1007
+	protected function verifySignature($version, $signature, $file)
1008
+	{
1009
+		if (!$result = $this->disableTls) {
1010
+			$path = preg_match('{^[0-9a-f]{40}$}', $version) ? $this->pubKeys['dev'] : $this->pubKeys['tags'];
1011
+			$pubkeyid = openssl_pkey_get_public('file://'.$path);
1012
+
1013
+			$result = 1 === openssl_verify(
1014
+				file_get_contents($file),
1015
+				$signature,
1016
+				$pubkeyid,
1017
+				$this->algo
1018
+			);
1019
+
1020
+			openssl_free_key($pubkeyid);
1021
+		}
1022
+
1023
+		return $result;
1024
+	}
1025
+
1026
+	/**
1027
+	 * Validates the downloaded phar file
1028
+	 *
1029
+	 * @param string $pharFile The temp phar file
1030
+	 * @param null|string $error Set by method on failure
1031
+	 *
1032
+	 * @return bool If the operation succeeded
1033
+	 */
1034
+	protected function validatePhar($pharFile, &$error)
1035
+	{
1036
+		if (ini_get('phar.readonly')) {
1037
+			return true;
1038
+		}
1039
+
1040
+		try {
1041
+			// Test the phar validity
1042
+			$phar = new Phar($pharFile);
1043
+			// Free the variable to unlock the file
1044
+			unset($phar);
1045
+			$result = true;
1046
+
1047
+		} catch (Exception $e) {
1048
+			if (!$e instanceof UnexpectedValueException && !$e instanceof PharException) {
1049
+				throw $e;
1050
+			}
1051
+			$error = $e->getMessage();
1052
+			$result = false;
1053
+		}
1054
+		return $result;
1055
+	}
1056
+
1057
+	/**
1058
+	 * Returns a string representation of the last json error
1059
+	 *
1060
+	 * @return string The error string or code
1061
+	 */
1062
+	protected function getJsonError()
1063
+	{
1064
+		if (function_exists('json_last_error_msg')) {
1065
+			return json_last_error_msg();
1066
+		} else {
1067
+			return 'json_last_error = '.json_last_error();
1068
+		}
1069
+	}
1070
+
1071
+	/**
1072
+	 * Cleans up resources at the end of the installation
1073
+	 *
1074
+	 * @param bool $result If the installation succeeded
1075
+	 */
1076
+	protected function cleanUp($result)
1077
+	{
1078
+		if (!$result) {
1079
+			// Output buffered errors
1080
+			if ($this->quiet) {
1081
+				$this->outputErrors();
1082
+			}
1083
+			// Clean up stuff we created
1084
+			$this->uninstall();
1085
+		}
1086
+	}
1087
+
1088
+	/**
1089
+	 * Outputs unique errors when in quiet mode
1090
+	 *
1091
+	 */
1092
+	protected function outputErrors()
1093
+	{
1094
+		$errors = explode(PHP_EOL, ob_get_clean());
1095
+		$shown = array();
1096
+
1097
+		foreach ($errors as $error) {
1098
+			if ($error && !in_array($error, $shown)) {
1099
+				out($error, 'error');
1100
+				$shown[] = $error;
1101
+			}
1102
+		}
1103
+	}
1104
+
1105
+	/**
1106
+	 * Uninstalls newly-created files and directories on failure
1107
+	 *
1108
+	 */
1109
+	protected function uninstall()
1110
+	{
1111
+		foreach (array_reverse($this->installs) as $target) {
1112
+			if (is_file($target)) {
1113
+				@unlink($target);
1114
+			} elseif (is_dir($target)) {
1115
+				@rmdir($target);
1116
+			}
1117
+		}
1118
+
1119
+		if (file_exists($this->tmpFile)) {
1120
+			@unlink($this->tmpFile);
1121
+		}
1122
+	}
1123
+
1124
+	public static function getPKDev()
1125
+	{
1126
+		return <<<PKDEV
1127 1127
 -----BEGIN PUBLIC KEY-----
1128 1128
 MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnBDHjZS6e0ZMoK3xTD7f
1129 1129
 FNCzlXjX/Aie2dit8QXA03pSrOTbaMnxON3hUL47Lz3g1SC6YJEMVHr0zYq4elWi
@@ -1139,11 +1139,11 @@  discard block
 block discarded – undo
1139 1139
 wSEuAuRm+pRqi8BRnQ/GKUcCAwEAAQ==
1140 1140
 -----END PUBLIC KEY-----
1141 1141
 PKDEV;
1142
-    }
1142
+	}
1143 1143
 
1144
-    public static function getPKTags()
1145
-    {
1146
-        return <<<PKTAGS
1144
+	public static function getPKTags()
1145
+	{
1146
+		return <<<PKTAGS
1147 1147
 -----BEGIN PUBLIC KEY-----
1148 1148
 MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0Vi/2K6apCVj76nCnCl2
1149 1149
 MQUPdK+A9eqkYBacXo2wQBYmyVlXm2/n/ZsX6pCLYPQTHyr5jXbkQzBw8SKqPdlh
@@ -1159,453 +1159,453 @@  discard block
 block discarded – undo
1159 1159
 RGv89BPD+2DLnJysngsvVaUCAwEAAQ==
1160 1160
 -----END PUBLIC KEY-----
1161 1161
 PKTAGS;
1162
-    }
1162
+	}
1163 1163
 }
1164 1164
 
1165 1165
 class ErrorHandler
1166 1166
 {
1167
-    public $message;
1168
-    protected $active;
1169
-
1170
-    /**
1171
-     * Handle php errors
1172
-     *
1173
-     * @param mixed $code The error code
1174
-     * @param mixed $msg The error message
1175
-     */
1176
-    public function handleError($code, $msg)
1177
-    {
1178
-        if ($this->message) {
1179
-            $this->message .= PHP_EOL;
1180
-        }
1181
-        $this->message .= preg_replace('{^file_get_contents\(.*?\): }', '', $msg);
1182
-    }
1183
-
1184
-    /**
1185
-     * Starts error-handling if not already active
1186
-     *
1187
-     * Any message is cleared
1188
-     */
1189
-    public function start()
1190
-    {
1191
-        if (!$this->active) {
1192
-            set_error_handler(array($this, 'handleError'));
1193
-            $this->active = true;
1194
-        }
1195
-        $this->message = '';
1196
-    }
1197
-
1198
-    /**
1199
-     * Stops error-handling if active
1200
-     *
1201
-     * Any message is preserved until the next call to start()
1202
-     */
1203
-    public function stop()
1204
-    {
1205
-        if ($this->active) {
1206
-            restore_error_handler();
1207
-            $this->active = false;
1208
-        }
1209
-    }
1167
+	public $message;
1168
+	protected $active;
1169
+
1170
+	/**
1171
+	 * Handle php errors
1172
+	 *
1173
+	 * @param mixed $code The error code
1174
+	 * @param mixed $msg The error message
1175
+	 */
1176
+	public function handleError($code, $msg)
1177
+	{
1178
+		if ($this->message) {
1179
+			$this->message .= PHP_EOL;
1180
+		}
1181
+		$this->message .= preg_replace('{^file_get_contents\(.*?\): }', '', $msg);
1182
+	}
1183
+
1184
+	/**
1185
+	 * Starts error-handling if not already active
1186
+	 *
1187
+	 * Any message is cleared
1188
+	 */
1189
+	public function start()
1190
+	{
1191
+		if (!$this->active) {
1192
+			set_error_handler(array($this, 'handleError'));
1193
+			$this->active = true;
1194
+		}
1195
+		$this->message = '';
1196
+	}
1197
+
1198
+	/**
1199
+	 * Stops error-handling if active
1200
+	 *
1201
+	 * Any message is preserved until the next call to start()
1202
+	 */
1203
+	public function stop()
1204
+	{
1205
+		if ($this->active) {
1206
+			restore_error_handler();
1207
+			$this->active = false;
1208
+		}
1209
+	}
1210 1210
 }
1211 1211
 
1212 1212
 class NoProxyPattern
1213 1213
 {
1214
-    private $composerInNoProxy = false;
1215
-    private $rulePorts = array();
1216
-
1217
-    public function __construct($pattern)
1218
-    {
1219
-        $rules = preg_split('{[\s,]+}', $pattern, null, PREG_SPLIT_NO_EMPTY);
1220
-
1221
-        if ($matches = preg_grep('{getcomposer\.org(?::\d+)?}i', $rules)) {
1222
-            $this->composerInNoProxy = true;
1223
-
1224
-            foreach ($matches as $match) {
1225
-                if (strpos($match, ':') !== false) {
1226
-                    list(, $port) = explode(':', $match);
1227
-                    $this->rulePorts[] = (int) $port;
1228
-                }
1229
-            }
1230
-        }
1231
-    }
1232
-
1233
-    /**
1234
-     * Returns true if NO_PROXY contains getcomposer.org
1235
-     *
1236
-     * @param string $url http(s)://getcomposer.org
1237
-     *
1238
-     * @return bool
1239
-     */
1240
-    public function test($url)
1241
-    {
1242
-        if (!$this->composerInNoProxy) {
1243
-            return false;
1244
-        }
1245
-
1246
-        if (empty($this->rulePorts)) {
1247
-            return true;
1248
-        }
1249
-
1250
-        if (strpos($url, 'http://') === 0) {
1251
-            $port = 80;
1252
-        } else {
1253
-            $port = 443;
1254
-        }
1255
-
1256
-        return in_array($port, $this->rulePorts);
1257
-    }
1214
+	private $composerInNoProxy = false;
1215
+	private $rulePorts = array();
1216
+
1217
+	public function __construct($pattern)
1218
+	{
1219
+		$rules = preg_split('{[\s,]+}', $pattern, null, PREG_SPLIT_NO_EMPTY);
1220
+
1221
+		if ($matches = preg_grep('{getcomposer\.org(?::\d+)?}i', $rules)) {
1222
+			$this->composerInNoProxy = true;
1223
+
1224
+			foreach ($matches as $match) {
1225
+				if (strpos($match, ':') !== false) {
1226
+					list(, $port) = explode(':', $match);
1227
+					$this->rulePorts[] = (int) $port;
1228
+				}
1229
+			}
1230
+		}
1231
+	}
1232
+
1233
+	/**
1234
+	 * Returns true if NO_PROXY contains getcomposer.org
1235
+	 *
1236
+	 * @param string $url http(s)://getcomposer.org
1237
+	 *
1238
+	 * @return bool
1239
+	 */
1240
+	public function test($url)
1241
+	{
1242
+		if (!$this->composerInNoProxy) {
1243
+			return false;
1244
+		}
1245
+
1246
+		if (empty($this->rulePorts)) {
1247
+			return true;
1248
+		}
1249
+
1250
+		if (strpos($url, 'http://') === 0) {
1251
+			$port = 80;
1252
+		} else {
1253
+			$port = 443;
1254
+		}
1255
+
1256
+		return in_array($port, $this->rulePorts);
1257
+	}
1258 1258
 }
1259 1259
 
1260 1260
 class HttpClient {
1261 1261
 
1262
-    private $options = array('http' => array());
1263
-    private $disableTls = false;
1264
-
1265
-    public function __construct($disableTls = false, $cafile = false)
1266
-    {
1267
-        $this->disableTls = $disableTls;
1268
-        if ($this->disableTls === false) {
1269
-            if (!empty($cafile) && !is_dir($cafile)) {
1270
-                if (!is_readable($cafile) || !validateCaFile(file_get_contents($cafile))) {
1271
-                    throw new RuntimeException('The configured cafile (' .$cafile. ') was not valid or could not be read.');
1272
-                }
1273
-            }
1274
-            $options = $this->getTlsStreamContextDefaults($cafile);
1275
-            $this->options = array_replace_recursive($this->options, $options);
1276
-        }
1277
-    }
1278
-
1279
-    public function get($url)
1280
-    {
1281
-        $context = $this->getStreamContext($url);
1282
-        $result = file_get_contents($url, false, $context);
1283
-
1284
-        if ($result && extension_loaded('zlib')) {
1285
-            $decode = false;
1286
-            foreach ($http_response_header as $header) {
1287
-                if (preg_match('{^content-encoding: *gzip *$}i', $header)) {
1288
-                    $decode = true;
1289
-                    continue;
1290
-                } elseif (preg_match('{^HTTP/}i', $header)) {
1291
-                    $decode = false;
1292
-                }
1293
-            }
1294
-
1295
-            if ($decode) {
1296
-                if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
1297
-                    $result = zlib_decode($result);
1298
-                } else {
1299
-                    // work around issue with gzuncompress & co that do not work with all gzip checksums
1300
-                    $result = file_get_contents('compress.zlib://data:application/octet-stream;base64,'.base64_encode($result));
1301
-                }
1302
-
1303
-                if (!$result) {
1304
-                    throw new RuntimeException('Failed to decode zlib stream');
1305
-                }
1306
-            }
1307
-        }
1308
-
1309
-        return $result;
1310
-    }
1311
-
1312
-    protected function getStreamContext($url)
1313
-    {
1314
-        if ($this->disableTls === false) {
1315
-            if (PHP_VERSION_ID < 50600) {
1316
-                $this->options['ssl']['SNI_server_name'] = parse_url($url, PHP_URL_HOST);
1317
-            }
1318
-        }
1319
-        // Keeping the above mostly isolated from the code copied from Composer.
1320
-        return $this->getMergedStreamContext($url);
1321
-    }
1322
-
1323
-    protected function getTlsStreamContextDefaults($cafile)
1324
-    {
1325
-        $ciphers = implode(':', array(
1326
-            'ECDHE-RSA-AES128-GCM-SHA256',
1327
-            'ECDHE-ECDSA-AES128-GCM-SHA256',
1328
-            'ECDHE-RSA-AES256-GCM-SHA384',
1329
-            'ECDHE-ECDSA-AES256-GCM-SHA384',
1330
-            'DHE-RSA-AES128-GCM-SHA256',
1331
-            'DHE-DSS-AES128-GCM-SHA256',
1332
-            'kEDH+AESGCM',
1333
-            'ECDHE-RSA-AES128-SHA256',
1334
-            'ECDHE-ECDSA-AES128-SHA256',
1335
-            'ECDHE-RSA-AES128-SHA',
1336
-            'ECDHE-ECDSA-AES128-SHA',
1337
-            'ECDHE-RSA-AES256-SHA384',
1338
-            'ECDHE-ECDSA-AES256-SHA384',
1339
-            'ECDHE-RSA-AES256-SHA',
1340
-            'ECDHE-ECDSA-AES256-SHA',
1341
-            'DHE-RSA-AES128-SHA256',
1342
-            'DHE-RSA-AES128-SHA',
1343
-            'DHE-DSS-AES128-SHA256',
1344
-            'DHE-RSA-AES256-SHA256',
1345
-            'DHE-DSS-AES256-SHA',
1346
-            'DHE-RSA-AES256-SHA',
1347
-            'AES128-GCM-SHA256',
1348
-            'AES256-GCM-SHA384',
1349
-            'AES128-SHA256',
1350
-            'AES256-SHA256',
1351
-            'AES128-SHA',
1352
-            'AES256-SHA',
1353
-            'AES',
1354
-            'CAMELLIA',
1355
-            'DES-CBC3-SHA',
1356
-            '!aNULL',
1357
-            '!eNULL',
1358
-            '!EXPORT',
1359
-            '!DES',
1360
-            '!RC4',
1361
-            '!MD5',
1362
-            '!PSK',
1363
-            '!aECDH',
1364
-            '!EDH-DSS-DES-CBC3-SHA',
1365
-            '!EDH-RSA-DES-CBC3-SHA',
1366
-            '!KRB5-DES-CBC3-SHA',
1367
-        ));
1368
-
1369
-        /**
1370
-         * CN_match and SNI_server_name are only known once a URL is passed.
1371
-         * They will be set in the getOptionsForUrl() method which receives a URL.
1372
-         *
1373
-         * cafile or capath can be overridden by passing in those options to constructor.
1374
-         */
1375
-        $options = array(
1376
-            'ssl' => array(
1377
-                'ciphers' => $ciphers,
1378
-                'verify_peer' => true,
1379
-                'verify_depth' => 7,
1380
-                'SNI_enabled' => true,
1381
-            )
1382
-        );
1383
-
1384
-        /**
1385
-         * Attempt to find a local cafile or throw an exception.
1386
-         * The user may go download one if this occurs.
1387
-         */
1388
-        if (!$cafile) {
1389
-            $cafile = self::getSystemCaRootBundlePath();
1390
-        }
1391
-        if (is_dir($cafile)) {
1392
-            $options['ssl']['capath'] = $cafile;
1393
-        } elseif ($cafile) {
1394
-            $options['ssl']['cafile'] = $cafile;
1395
-        } else {
1396
-            throw new RuntimeException('A valid cafile could not be located automatically.');
1397
-        }
1398
-
1399
-        /**
1400
-         * Disable TLS compression to prevent CRIME attacks where supported.
1401
-         */
1402
-        if (version_compare(PHP_VERSION, '5.4.13') >= 0) {
1403
-            $options['ssl']['disable_compression'] = true;
1404
-        }
1405
-
1406
-        return $options;
1407
-    }
1408
-
1409
-    /**
1410
-     * function copied from Composer\Util\StreamContextFactory::getContext
1411
-     *
1412
-     * Any changes should be applied there as well, or backported here.
1413
-     *
1414
-     * @param string $url URL the context is to be used for
1415
-     * @return resource Default context
1416
-     * @throws \RuntimeException if https proxy required and OpenSSL uninstalled
1417
-     */
1418
-    protected function getMergedStreamContext($url)
1419
-    {
1420
-        $options = $this->options;
1421
-
1422
-        // Handle HTTP_PROXY/http_proxy on CLI only for security reasons
1423
-        if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && (!empty($_SERVER['HTTP_PROXY']) || !empty($_SERVER['http_proxy']))) {
1424
-            $proxy = parse_url(!empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
1425
-        }
1426
-
1427
-        // Prefer CGI_HTTP_PROXY if available
1428
-        if (!empty($_SERVER['CGI_HTTP_PROXY'])) {
1429
-            $proxy = parse_url($_SERVER['CGI_HTTP_PROXY']);
1430
-        }
1431
-
1432
-        // Override with HTTPS proxy if present and URL is https
1433
-        if (preg_match('{^https://}i', $url) && (!empty($_SERVER['HTTPS_PROXY']) || !empty($_SERVER['https_proxy']))) {
1434
-            $proxy = parse_url(!empty($_SERVER['https_proxy']) ? $_SERVER['https_proxy'] : $_SERVER['HTTPS_PROXY']);
1435
-        }
1436
-
1437
-        // Remove proxy if URL matches no_proxy directive
1438
-        if (!empty($_SERVER['NO_PROXY']) || !empty($_SERVER['no_proxy']) && parse_url($url, PHP_URL_HOST)) {
1439
-            $pattern = new NoProxyPattern(!empty($_SERVER['no_proxy']) ? $_SERVER['no_proxy'] : $_SERVER['NO_PROXY']);
1440
-            if ($pattern->test($url)) {
1441
-                unset($proxy);
1442
-            }
1443
-        }
1444
-
1445
-        if (!empty($proxy)) {
1446
-            $proxyURL = isset($proxy['scheme']) ? $proxy['scheme'] . '://' : '';
1447
-            $proxyURL .= isset($proxy['host']) ? $proxy['host'] : '';
1448
-
1449
-            if (isset($proxy['port'])) {
1450
-                $proxyURL .= ":" . $proxy['port'];
1451
-            } elseif ('http://' == substr($proxyURL, 0, 7)) {
1452
-                $proxyURL .= ":80";
1453
-            } elseif ('https://' == substr($proxyURL, 0, 8)) {
1454
-                $proxyURL .= ":443";
1455
-            }
1456
-
1457
-            // http(s):// is not supported in proxy
1458
-            $proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL);
1459
-
1460
-            if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) {
1461
-                throw new RuntimeException('You must enable the openssl extension to use a proxy over https');
1462
-            }
1463
-
1464
-            $options['http'] = array(
1465
-                'proxy' => $proxyURL,
1466
-            );
1467
-
1468
-            // set request_fulluri, depending on default requirements and the environment
1469
-            switch (parse_url($url, PHP_URL_SCHEME)) {
1470
-                case 'http': // default is true for HTTP, check if explicitly disabled
1471
-                    $reqFullUriEnv = getenv('HTTP_PROXY_REQUEST_FULLURI');
1472
-                    if ($reqFullUriEnv === false || $reqFullUriEnv === '' || (strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv)) {
1473
-                        $options['http']['request_fulluri'] = true;
1474
-                    }
1475
-                    break;
1476
-                case 'https': // default is false for HTTPS, check if explicitly enabled
1477
-                    $reqFullUriEnv = getenv('HTTPS_PROXY_REQUEST_FULLURI');
1478
-                    if (strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv) {
1479
-                        $options['http']['request_fulluri'] = true;
1480
-                    }
1481
-                    break;
1482
-            }
1483
-
1484
-            // handle proxy auth if present
1485
-            if (isset($proxy['user'])) {
1486
-                $auth = rawurldecode($proxy['user']);
1487
-                if (isset($proxy['pass'])) {
1488
-                    $auth .= ':' . rawurldecode($proxy['pass']);
1489
-                }
1490
-                $auth = base64_encode($auth);
1491
-
1492
-                $options['http']['header'] = "Proxy-Authorization: Basic {$auth}\r\n";
1493
-            }
1494
-        }
1495
-
1496
-        if (isset($options['http']['header'])) {
1497
-            $options['http']['header'] .= "Connection: close\r\n";
1498
-        } else {
1499
-            $options['http']['header'] = "Connection: close\r\n";
1500
-        }
1501
-        if (extension_loaded('zlib')) {
1502
-            $options['http']['header'] .= "Accept-Encoding: gzip\r\n";
1503
-        }
1504
-        $options['http']['header'] .= "User-Agent: ".COMPOSER_INSTALLER."\r\n";
1505
-        $options['http']['protocol_version'] = 1.1;
1506
-        $options['http']['timeout'] = 600;
1507
-
1508
-        return stream_context_create($options);
1509
-    }
1510
-
1511
-    /**
1512
-    * This method was adapted from Sslurp.
1513
-    * https://github.com/EvanDotPro/Sslurp
1514
-    *
1515
-    * (c) Evan Coury <[email protected]>
1516
-    *
1517
-    * For the full copyright and license information, please see below:
1518
-    *
1519
-    * Copyright (c) 2013, Evan Coury
1520
-    * All rights reserved.
1521
-    *
1522
-    * Redistribution and use in source and binary forms, with or without modification,
1523
-    * are permitted provided that the following conditions are met:
1524
-    *
1525
-    *     * Redistributions of source code must retain the above copyright notice,
1526
-    *       this list of conditions and the following disclaimer.
1527
-    *
1528
-    *     * Redistributions in binary form must reproduce the above copyright notice,
1529
-    *       this list of conditions and the following disclaimer in the documentation
1530
-    *       and/or other materials provided with the distribution.
1531
-    *
1532
-    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1533
-    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1534
-    * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1535
-    * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
1536
-    * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1537
-    * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1538
-    * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1539
-    * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1540
-    * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1541
-    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1542
-    */
1543
-    public static function getSystemCaRootBundlePath()
1544
-    {
1545
-        static $caPath = null;
1546
-
1547
-        if ($caPath !== null) {
1548
-            return $caPath;
1549
-        }
1550
-
1551
-        // If SSL_CERT_FILE env variable points to a valid certificate/bundle, use that.
1552
-        // This mimics how OpenSSL uses the SSL_CERT_FILE env variable.
1553
-        $envCertFile = getenv('SSL_CERT_FILE');
1554
-        if ($envCertFile && is_readable($envCertFile) && validateCaFile(file_get_contents($envCertFile))) {
1555
-            return $caPath = $envCertFile;
1556
-        }
1557
-
1558
-        // If SSL_CERT_DIR env variable points to a valid certificate/bundle, use that.
1559
-        // This mimics how OpenSSL uses the SSL_CERT_FILE env variable.
1560
-        $envCertDir = getenv('SSL_CERT_DIR');
1561
-        if ($envCertDir && is_dir($envCertDir) && is_readable($envCertDir)) {
1562
-            return $caPath = $envCertDir;
1563
-        }
1564
-
1565
-        $configured = ini_get('openssl.cafile');
1566
-        if ($configured && strlen($configured) > 0 && is_readable($configured) && validateCaFile(file_get_contents($configured))) {
1567
-            return $caPath = $configured;
1568
-        }
1569
-
1570
-        $configured = ini_get('openssl.capath');
1571
-        if ($configured && is_dir($configured) && is_readable($configured)) {
1572
-            return $caPath = $configured;
1573
-        }
1574
-
1575
-        $caBundlePaths = array(
1576
-            '/etc/pki/tls/certs/ca-bundle.crt', // Fedora, RHEL, CentOS (ca-certificates package)
1577
-            '/etc/ssl/certs/ca-certificates.crt', // Debian, Ubuntu, Gentoo, Arch Linux (ca-certificates package)
1578
-            '/etc/ssl/ca-bundle.pem', // SUSE, openSUSE (ca-certificates package)
1579
-            '/usr/local/share/certs/ca-root-nss.crt', // FreeBSD (ca_root_nss_package)
1580
-            '/usr/ssl/certs/ca-bundle.crt', // Cygwin
1581
-            '/opt/local/share/curl/curl-ca-bundle.crt', // OS X macports, curl-ca-bundle package
1582
-            '/usr/local/share/curl/curl-ca-bundle.crt', // Default cURL CA bunde path (without --with-ca-bundle option)
1583
-            '/usr/share/ssl/certs/ca-bundle.crt', // Really old RedHat?
1584
-            '/etc/ssl/cert.pem', // OpenBSD
1585
-            '/usr/local/etc/ssl/cert.pem', // FreeBSD 10.x
1586
-            '/usr/local/etc/openssl/cert.pem', // OS X homebrew, openssl package
1587
-            '/usr/local/etc/[email protected]/cert.pem', // OS X homebrew, [email protected] package
1588
-        );
1589
-
1590
-        foreach ($caBundlePaths as $caBundle) {
1591
-            if (@is_readable($caBundle) && validateCaFile(file_get_contents($caBundle))) {
1592
-                return $caPath = $caBundle;
1593
-            }
1594
-        }
1595
-
1596
-        foreach ($caBundlePaths as $caBundle) {
1597
-            $caBundle = dirname($caBundle);
1598
-            if (is_dir($caBundle) && glob($caBundle.'/*')) {
1599
-                return $caPath = $caBundle;
1600
-            }
1601
-        }
1602
-
1603
-        return $caPath = false;
1604
-    }
1605
-
1606
-    public static function getPackagedCaFile()
1607
-    {
1608
-        return <<<CACERT
1262
+	private $options = array('http' => array());
1263
+	private $disableTls = false;
1264
+
1265
+	public function __construct($disableTls = false, $cafile = false)
1266
+	{
1267
+		$this->disableTls = $disableTls;
1268
+		if ($this->disableTls === false) {
1269
+			if (!empty($cafile) && !is_dir($cafile)) {
1270
+				if (!is_readable($cafile) || !validateCaFile(file_get_contents($cafile))) {
1271
+					throw new RuntimeException('The configured cafile (' .$cafile. ') was not valid or could not be read.');
1272
+				}
1273
+			}
1274
+			$options = $this->getTlsStreamContextDefaults($cafile);
1275
+			$this->options = array_replace_recursive($this->options, $options);
1276
+		}
1277
+	}
1278
+
1279
+	public function get($url)
1280
+	{
1281
+		$context = $this->getStreamContext($url);
1282
+		$result = file_get_contents($url, false, $context);
1283
+
1284
+		if ($result && extension_loaded('zlib')) {
1285
+			$decode = false;
1286
+			foreach ($http_response_header as $header) {
1287
+				if (preg_match('{^content-encoding: *gzip *$}i', $header)) {
1288
+					$decode = true;
1289
+					continue;
1290
+				} elseif (preg_match('{^HTTP/}i', $header)) {
1291
+					$decode = false;
1292
+				}
1293
+			}
1294
+
1295
+			if ($decode) {
1296
+				if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
1297
+					$result = zlib_decode($result);
1298
+				} else {
1299
+					// work around issue with gzuncompress & co that do not work with all gzip checksums
1300
+					$result = file_get_contents('compress.zlib://data:application/octet-stream;base64,'.base64_encode($result));
1301
+				}
1302
+
1303
+				if (!$result) {
1304
+					throw new RuntimeException('Failed to decode zlib stream');
1305
+				}
1306
+			}
1307
+		}
1308
+
1309
+		return $result;
1310
+	}
1311
+
1312
+	protected function getStreamContext($url)
1313
+	{
1314
+		if ($this->disableTls === false) {
1315
+			if (PHP_VERSION_ID < 50600) {
1316
+				$this->options['ssl']['SNI_server_name'] = parse_url($url, PHP_URL_HOST);
1317
+			}
1318
+		}
1319
+		// Keeping the above mostly isolated from the code copied from Composer.
1320
+		return $this->getMergedStreamContext($url);
1321
+	}
1322
+
1323
+	protected function getTlsStreamContextDefaults($cafile)
1324
+	{
1325
+		$ciphers = implode(':', array(
1326
+			'ECDHE-RSA-AES128-GCM-SHA256',
1327
+			'ECDHE-ECDSA-AES128-GCM-SHA256',
1328
+			'ECDHE-RSA-AES256-GCM-SHA384',
1329
+			'ECDHE-ECDSA-AES256-GCM-SHA384',
1330
+			'DHE-RSA-AES128-GCM-SHA256',
1331
+			'DHE-DSS-AES128-GCM-SHA256',
1332
+			'kEDH+AESGCM',
1333
+			'ECDHE-RSA-AES128-SHA256',
1334
+			'ECDHE-ECDSA-AES128-SHA256',
1335
+			'ECDHE-RSA-AES128-SHA',
1336
+			'ECDHE-ECDSA-AES128-SHA',
1337
+			'ECDHE-RSA-AES256-SHA384',
1338
+			'ECDHE-ECDSA-AES256-SHA384',
1339
+			'ECDHE-RSA-AES256-SHA',
1340
+			'ECDHE-ECDSA-AES256-SHA',
1341
+			'DHE-RSA-AES128-SHA256',
1342
+			'DHE-RSA-AES128-SHA',
1343
+			'DHE-DSS-AES128-SHA256',
1344
+			'DHE-RSA-AES256-SHA256',
1345
+			'DHE-DSS-AES256-SHA',
1346
+			'DHE-RSA-AES256-SHA',
1347
+			'AES128-GCM-SHA256',
1348
+			'AES256-GCM-SHA384',
1349
+			'AES128-SHA256',
1350
+			'AES256-SHA256',
1351
+			'AES128-SHA',
1352
+			'AES256-SHA',
1353
+			'AES',
1354
+			'CAMELLIA',
1355
+			'DES-CBC3-SHA',
1356
+			'!aNULL',
1357
+			'!eNULL',
1358
+			'!EXPORT',
1359
+			'!DES',
1360
+			'!RC4',
1361
+			'!MD5',
1362
+			'!PSK',
1363
+			'!aECDH',
1364
+			'!EDH-DSS-DES-CBC3-SHA',
1365
+			'!EDH-RSA-DES-CBC3-SHA',
1366
+			'!KRB5-DES-CBC3-SHA',
1367
+		));
1368
+
1369
+		/**
1370
+		 * CN_match and SNI_server_name are only known once a URL is passed.
1371
+		 * They will be set in the getOptionsForUrl() method which receives a URL.
1372
+		 *
1373
+		 * cafile or capath can be overridden by passing in those options to constructor.
1374
+		 */
1375
+		$options = array(
1376
+			'ssl' => array(
1377
+				'ciphers' => $ciphers,
1378
+				'verify_peer' => true,
1379
+				'verify_depth' => 7,
1380
+				'SNI_enabled' => true,
1381
+			)
1382
+		);
1383
+
1384
+		/**
1385
+		 * Attempt to find a local cafile or throw an exception.
1386
+		 * The user may go download one if this occurs.
1387
+		 */
1388
+		if (!$cafile) {
1389
+			$cafile = self::getSystemCaRootBundlePath();
1390
+		}
1391
+		if (is_dir($cafile)) {
1392
+			$options['ssl']['capath'] = $cafile;
1393
+		} elseif ($cafile) {
1394
+			$options['ssl']['cafile'] = $cafile;
1395
+		} else {
1396
+			throw new RuntimeException('A valid cafile could not be located automatically.');
1397
+		}
1398
+
1399
+		/**
1400
+		 * Disable TLS compression to prevent CRIME attacks where supported.
1401
+		 */
1402
+		if (version_compare(PHP_VERSION, '5.4.13') >= 0) {
1403
+			$options['ssl']['disable_compression'] = true;
1404
+		}
1405
+
1406
+		return $options;
1407
+	}
1408
+
1409
+	/**
1410
+	 * function copied from Composer\Util\StreamContextFactory::getContext
1411
+	 *
1412
+	 * Any changes should be applied there as well, or backported here.
1413
+	 *
1414
+	 * @param string $url URL the context is to be used for
1415
+	 * @return resource Default context
1416
+	 * @throws \RuntimeException if https proxy required and OpenSSL uninstalled
1417
+	 */
1418
+	protected function getMergedStreamContext($url)
1419
+	{
1420
+		$options = $this->options;
1421
+
1422
+		// Handle HTTP_PROXY/http_proxy on CLI only for security reasons
1423
+		if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && (!empty($_SERVER['HTTP_PROXY']) || !empty($_SERVER['http_proxy']))) {
1424
+			$proxy = parse_url(!empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
1425
+		}
1426
+
1427
+		// Prefer CGI_HTTP_PROXY if available
1428
+		if (!empty($_SERVER['CGI_HTTP_PROXY'])) {
1429
+			$proxy = parse_url($_SERVER['CGI_HTTP_PROXY']);
1430
+		}
1431
+
1432
+		// Override with HTTPS proxy if present and URL is https
1433
+		if (preg_match('{^https://}i', $url) && (!empty($_SERVER['HTTPS_PROXY']) || !empty($_SERVER['https_proxy']))) {
1434
+			$proxy = parse_url(!empty($_SERVER['https_proxy']) ? $_SERVER['https_proxy'] : $_SERVER['HTTPS_PROXY']);
1435
+		}
1436
+
1437
+		// Remove proxy if URL matches no_proxy directive
1438
+		if (!empty($_SERVER['NO_PROXY']) || !empty($_SERVER['no_proxy']) && parse_url($url, PHP_URL_HOST)) {
1439
+			$pattern = new NoProxyPattern(!empty($_SERVER['no_proxy']) ? $_SERVER['no_proxy'] : $_SERVER['NO_PROXY']);
1440
+			if ($pattern->test($url)) {
1441
+				unset($proxy);
1442
+			}
1443
+		}
1444
+
1445
+		if (!empty($proxy)) {
1446
+			$proxyURL = isset($proxy['scheme']) ? $proxy['scheme'] . '://' : '';
1447
+			$proxyURL .= isset($proxy['host']) ? $proxy['host'] : '';
1448
+
1449
+			if (isset($proxy['port'])) {
1450
+				$proxyURL .= ":" . $proxy['port'];
1451
+			} elseif ('http://' == substr($proxyURL, 0, 7)) {
1452
+				$proxyURL .= ":80";
1453
+			} elseif ('https://' == substr($proxyURL, 0, 8)) {
1454
+				$proxyURL .= ":443";
1455
+			}
1456
+
1457
+			// http(s):// is not supported in proxy
1458
+			$proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL);
1459
+
1460
+			if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) {
1461
+				throw new RuntimeException('You must enable the openssl extension to use a proxy over https');
1462
+			}
1463
+
1464
+			$options['http'] = array(
1465
+				'proxy' => $proxyURL,
1466
+			);
1467
+
1468
+			// set request_fulluri, depending on default requirements and the environment
1469
+			switch (parse_url($url, PHP_URL_SCHEME)) {
1470
+				case 'http': // default is true for HTTP, check if explicitly disabled
1471
+					$reqFullUriEnv = getenv('HTTP_PROXY_REQUEST_FULLURI');
1472
+					if ($reqFullUriEnv === false || $reqFullUriEnv === '' || (strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv)) {
1473
+						$options['http']['request_fulluri'] = true;
1474
+					}
1475
+					break;
1476
+				case 'https': // default is false for HTTPS, check if explicitly enabled
1477
+					$reqFullUriEnv = getenv('HTTPS_PROXY_REQUEST_FULLURI');
1478
+					if (strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv) {
1479
+						$options['http']['request_fulluri'] = true;
1480
+					}
1481
+					break;
1482
+			}
1483
+
1484
+			// handle proxy auth if present
1485
+			if (isset($proxy['user'])) {
1486
+				$auth = rawurldecode($proxy['user']);
1487
+				if (isset($proxy['pass'])) {
1488
+					$auth .= ':' . rawurldecode($proxy['pass']);
1489
+				}
1490
+				$auth = base64_encode($auth);
1491
+
1492
+				$options['http']['header'] = "Proxy-Authorization: Basic {$auth}\r\n";
1493
+			}
1494
+		}
1495
+
1496
+		if (isset($options['http']['header'])) {
1497
+			$options['http']['header'] .= "Connection: close\r\n";
1498
+		} else {
1499
+			$options['http']['header'] = "Connection: close\r\n";
1500
+		}
1501
+		if (extension_loaded('zlib')) {
1502
+			$options['http']['header'] .= "Accept-Encoding: gzip\r\n";
1503
+		}
1504
+		$options['http']['header'] .= "User-Agent: ".COMPOSER_INSTALLER."\r\n";
1505
+		$options['http']['protocol_version'] = 1.1;
1506
+		$options['http']['timeout'] = 600;
1507
+
1508
+		return stream_context_create($options);
1509
+	}
1510
+
1511
+	/**
1512
+	 * This method was adapted from Sslurp.
1513
+	 * https://github.com/EvanDotPro/Sslurp
1514
+	 *
1515
+	 * (c) Evan Coury <[email protected]>
1516
+	 *
1517
+	 * For the full copyright and license information, please see below:
1518
+	 *
1519
+	 * Copyright (c) 2013, Evan Coury
1520
+	 * All rights reserved.
1521
+	 *
1522
+	 * Redistribution and use in source and binary forms, with or without modification,
1523
+	 * are permitted provided that the following conditions are met:
1524
+	 *
1525
+	 *     * Redistributions of source code must retain the above copyright notice,
1526
+	 *       this list of conditions and the following disclaimer.
1527
+	 *
1528
+	 *     * Redistributions in binary form must reproduce the above copyright notice,
1529
+	 *       this list of conditions and the following disclaimer in the documentation
1530
+	 *       and/or other materials provided with the distribution.
1531
+	 *
1532
+	 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1533
+	 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1534
+	 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1535
+	 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
1536
+	 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1537
+	 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1538
+	 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1539
+	 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1540
+	 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1541
+	 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1542
+	 */
1543
+	public static function getSystemCaRootBundlePath()
1544
+	{
1545
+		static $caPath = null;
1546
+
1547
+		if ($caPath !== null) {
1548
+			return $caPath;
1549
+		}
1550
+
1551
+		// If SSL_CERT_FILE env variable points to a valid certificate/bundle, use that.
1552
+		// This mimics how OpenSSL uses the SSL_CERT_FILE env variable.
1553
+		$envCertFile = getenv('SSL_CERT_FILE');
1554
+		if ($envCertFile && is_readable($envCertFile) && validateCaFile(file_get_contents($envCertFile))) {
1555
+			return $caPath = $envCertFile;
1556
+		}
1557
+
1558
+		// If SSL_CERT_DIR env variable points to a valid certificate/bundle, use that.
1559
+		// This mimics how OpenSSL uses the SSL_CERT_FILE env variable.
1560
+		$envCertDir = getenv('SSL_CERT_DIR');
1561
+		if ($envCertDir && is_dir($envCertDir) && is_readable($envCertDir)) {
1562
+			return $caPath = $envCertDir;
1563
+		}
1564
+
1565
+		$configured = ini_get('openssl.cafile');
1566
+		if ($configured && strlen($configured) > 0 && is_readable($configured) && validateCaFile(file_get_contents($configured))) {
1567
+			return $caPath = $configured;
1568
+		}
1569
+
1570
+		$configured = ini_get('openssl.capath');
1571
+		if ($configured && is_dir($configured) && is_readable($configured)) {
1572
+			return $caPath = $configured;
1573
+		}
1574
+
1575
+		$caBundlePaths = array(
1576
+			'/etc/pki/tls/certs/ca-bundle.crt', // Fedora, RHEL, CentOS (ca-certificates package)
1577
+			'/etc/ssl/certs/ca-certificates.crt', // Debian, Ubuntu, Gentoo, Arch Linux (ca-certificates package)
1578
+			'/etc/ssl/ca-bundle.pem', // SUSE, openSUSE (ca-certificates package)
1579
+			'/usr/local/share/certs/ca-root-nss.crt', // FreeBSD (ca_root_nss_package)
1580
+			'/usr/ssl/certs/ca-bundle.crt', // Cygwin
1581
+			'/opt/local/share/curl/curl-ca-bundle.crt', // OS X macports, curl-ca-bundle package
1582
+			'/usr/local/share/curl/curl-ca-bundle.crt', // Default cURL CA bunde path (without --with-ca-bundle option)
1583
+			'/usr/share/ssl/certs/ca-bundle.crt', // Really old RedHat?
1584
+			'/etc/ssl/cert.pem', // OpenBSD
1585
+			'/usr/local/etc/ssl/cert.pem', // FreeBSD 10.x
1586
+			'/usr/local/etc/openssl/cert.pem', // OS X homebrew, openssl package
1587
+			'/usr/local/etc/[email protected]/cert.pem', // OS X homebrew, [email protected] package
1588
+		);
1589
+
1590
+		foreach ($caBundlePaths as $caBundle) {
1591
+			if (@is_readable($caBundle) && validateCaFile(file_get_contents($caBundle))) {
1592
+				return $caPath = $caBundle;
1593
+			}
1594
+		}
1595
+
1596
+		foreach ($caBundlePaths as $caBundle) {
1597
+			$caBundle = dirname($caBundle);
1598
+			if (is_dir($caBundle) && glob($caBundle.'/*')) {
1599
+				return $caPath = $caBundle;
1600
+			}
1601
+		}
1602
+
1603
+		return $caPath = false;
1604
+	}
1605
+
1606
+	public static function getPackagedCaFile()
1607
+	{
1608
+		return <<<CACERT
1609 1609
 ##
1610 1610
 ## Bundle of CA Root Certificates
1611 1611
 ##
@@ -5073,6 +5073,6 @@  discard block
 block discarded – undo
5073 5073
 kcpG2om3PVODLAgfi49T3f+sHw==
5074 5074
 -----END CERTIFICATE-----
5075 5075
 CACERT;
5076
-    }
5076
+	}
5077 5077
 
5078 5078
 }
Please login to merge, or discard this patch.
Spacing   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -22,7 +22,7 @@  discard block
 block discarded – undo
22 22
 {
23 23
     ini_set('display_errors', 1);
24 24
 
25
-    if (extension_loaded('uopz') && !(ini_get('uopz.disable') || ini_get('uopz.exit'))) {
25
+    if (extension_loaded('uopz') && ! (ini_get('uopz.disable') || ini_get('uopz.exit'))) {
26 26
         // uopz works at opcode level and disables exit calls
27 27
         if (function_exists('uopz_allow_exit')) {
28 28
             @uopz_allow_exit(true);
@@ -66,7 +66,7 @@  discard block
 block discarded – undo
66 66
     $filename   = getOptValue('--filename', $argv, 'composer.phar');
67 67
     $cafile     = getOptValue('--cafile', $argv, false);
68 68
 
69
-    if (!checkParams($installDir, $version, $cafile)) {
69
+    if ( ! checkParams($installDir, $version, $cafile)) {
70 70
         exit(1);
71 71
     }
72 72
 
@@ -183,7 +183,7 @@  discard block
 block discarded – undo
183 183
 {
184 184
     $result = true;
185 185
 
186
-    if (false !== $installDir && !is_dir($installDir)) {
186
+    if (false !== $installDir && ! is_dir($installDir)) {
187 187
         out("The defined install dir ({$installDir}) does not exist.", 'info');
188 188
         $result = false;
189 189
     }
@@ -193,7 +193,7 @@  discard block
 block discarded – undo
193 193
         $result = false;
194 194
     }
195 195
 
196
-    if (false !== $cafile && (!file_exists($cafile) || !is_readable($cafile))) {
196
+    if (false !== $cafile && ( ! file_exists($cafile) || ! is_readable($cafile))) {
197 197
         out("The defined Certificate Authority (CA) cert file ({$cafile}) does not exist or is not readable.", 'info');
198 198
         $result = false;
199 199
     }
@@ -217,19 +217,19 @@  discard block
 block discarded – undo
217 217
     getPlatformIssues($errors, $warnings, $install);
218 218
 
219 219
     // Make openssl warning an error if tls has not been specifically disabled
220
-    if (isset($warnings['openssl']) && !$disableTls) {
220
+    if (isset($warnings['openssl']) && ! $disableTls) {
221 221
         $errors['openssl'] = $warnings['openssl'];
222 222
         unset($warnings['openssl']);
223 223
     }
224 224
 
225
-    if (!empty($errors)) {
225
+    if ( ! empty($errors)) {
226 226
         out('Some settings on your machine make Composer unable to work properly.', 'error');
227 227
         out('Make sure that you fix the issues listed below and run this script again:', 'error');
228 228
         outputIssues($errors);
229 229
         return false;
230 230
     }
231 231
 
232
-    if (empty($warnings) && !$quiet) {
232
+    if (empty($warnings) && ! $quiet) {
233 233
         out('All settings correct for using Composer', 'success');
234 234
     }
235 235
     return true;
@@ -250,7 +250,7 @@  discard block
 block discarded – undo
250 250
     $warnings = array();
251 251
 
252 252
     if ($iniPath = php_ini_loaded_file()) {
253
-        $iniMessage = PHP_EOL.'The php.ini used by your command-line PHP is: ' . $iniPath;
253
+        $iniMessage = PHP_EOL.'The php.ini used by your command-line PHP is: '.$iniPath;
254 254
     } else {
255 255
         $iniMessage = PHP_EOL.'A php.ini file does not exist. You will have to create one.';
256 256
     }
@@ -268,7 +268,7 @@  discard block
 block discarded – undo
268 268
     if (extension_loaded('suhosin')) {
269 269
         $suhosin = ini_get('suhosin.executor.include.whitelist');
270 270
         $suhosinBlacklist = ini_get('suhosin.executor.include.blacklist');
271
-        if (false === stripos($suhosin, 'phar') && (!$suhosinBlacklist || false !== stripos($suhosinBlacklist, 'phar'))) {
271
+        if (false === stripos($suhosin, 'phar') && ( ! $suhosinBlacklist || false !== stripos($suhosinBlacklist, 'phar'))) {
272 272
             $errors['suhosin'] = array(
273 273
                 'The suhosin.executor.include.whitelist setting is incorrect.',
274 274
                 'Add the following to the end of your `php.ini` or suhosin.ini (Example path [for Debian]: /etc/php5/cli/conf.d/suhosin.ini):',
@@ -278,42 +278,42 @@  discard block
 block discarded – undo
278 278
         }
279 279
     }
280 280
 
281
-    if (!function_exists('json_decode')) {
281
+    if ( ! function_exists('json_decode')) {
282 282
         $errors['json'] = array(
283 283
             'The json extension is missing.',
284 284
             'Install it or recompile php without --disable-json'
285 285
         );
286 286
     }
287 287
 
288
-    if (!extension_loaded('Phar')) {
288
+    if ( ! extension_loaded('Phar')) {
289 289
         $errors['phar'] = array(
290 290
             'The phar extension is missing.',
291 291
             'Install it or recompile php without --disable-phar'
292 292
         );
293 293
     }
294 294
 
295
-    if (!extension_loaded('filter')) {
295
+    if ( ! extension_loaded('filter')) {
296 296
         $errors['filter'] = array(
297 297
             'The filter extension is missing.',
298 298
             'Install it or recompile php without --disable-filter'
299 299
         );
300 300
     }
301 301
 
302
-    if (!extension_loaded('hash')) {
302
+    if ( ! extension_loaded('hash')) {
303 303
         $errors['hash'] = array(
304 304
             'The hash extension is missing.',
305 305
             'Install it or recompile php without --disable-hash'
306 306
         );
307 307
     }
308 308
 
309
-    if (!extension_loaded('iconv') && !extension_loaded('mbstring')) {
309
+    if ( ! extension_loaded('iconv') && ! extension_loaded('mbstring')) {
310 310
         $errors['iconv_mbstring'] = array(
311 311
             'The iconv OR mbstring extension is required and both are missing.',
312 312
             'Install either of them or recompile php without --disable-iconv'
313 313
         );
314 314
     }
315 315
 
316
-    if (!ini_get('allow_url_fopen')) {
316
+    if ( ! ini_get('allow_url_fopen')) {
317 317
         $errors['allow_url_fopen'] = array(
318 318
             'The allow_url_fopen setting is incorrect.',
319 319
             'Add the following to the end of your `php.ini`:',
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
         );
346 346
     }
347 347
 
348
-    if (!extension_loaded('openssl')) {
348
+    if ( ! extension_loaded('openssl')) {
349 349
         $warnings['openssl'] = array(
350 350
             'The openssl extension is missing, which means that secure HTTPS transfers are impossible.',
351 351
             'If possible you should enable it or recompile php with --with-openssl'
@@ -364,7 +364,7 @@  discard block
 block discarded – undo
364 364
         );
365 365
     }
366 366
 
367
-    if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) {
367
+    if ( ! defined('HHVM_VERSION') && ! extension_loaded('apcu') && ini_get('apc.enable_cli')) {
368 368
         $warnings['apc_cli'] = array(
369 369
             'The apc.enable_cli setting is incorrect.',
370 370
             'Add the following to the end of your `php.ini`:',
@@ -373,7 +373,7 @@  discard block
 block discarded – undo
373 373
         );
374 374
     }
375 375
 
376
-    if (!$install && extension_loaded('xdebug')) {
376
+    if ( ! $install && extension_loaded('xdebug')) {
377 377
         $warnings['xdebug_loaded'] = array(
378 378
             'The xdebug extension is loaded, this can slow down Composer a little.',
379 379
             'Disabling it when using Composer is recommended.'
@@ -389,7 +389,7 @@  discard block
 block discarded – undo
389 389
         }
390 390
     }
391 391
 
392
-    if (!extension_loaded('zlib')) {
392
+    if ( ! extension_loaded('zlib')) {
393 393
         $warnings['zlib'] = array(
394 394
             'The zlib extension is not loaded, this can slow down Composer a lot.',
395 395
             'If possible, install it or recompile php with --with-zlib',
@@ -407,7 +407,7 @@  discard block
 block discarded – undo
407 407
         );
408 408
     }
409 409
 
410
-    if (extension_loaded('uopz') && !(ini_get('uopz.disable') || ini_get('uopz.exit'))) {
410
+    if (extension_loaded('uopz') && ! (ini_get('uopz.disable') || ini_get('uopz.exit'))) {
411 411
         $warnings['uopz'] = array(
412 412
             'The uopz extension ignores exit calls and may not work with all Composer commands.',
413 413
             'Disabling it when using Composer is recommended.'
@@ -445,7 +445,7 @@  discard block
 block discarded – undo
445 445
         $warnings[$key] = PHP_EOL.implode(PHP_EOL, $value);
446 446
     }
447 447
 
448
-    return !empty($errors) || !empty($warnings);
448
+    return ! empty($errors) || ! empty($warnings);
449 449
 }
450 450
 
451 451
 
@@ -469,7 +469,7 @@  discard block
 block discarded – undo
469 469
  */
470 470
 function showWarnings($warnings)
471 471
 {
472
-    if (!empty($warnings)) {
472
+    if ( ! empty($warnings)) {
473 473
         out('Some settings on your machine may cause stability issues with Composer.', 'error');
474 474
         out('If you encounter issues, try to change the following:', 'error');
475 475
         outputIssues($warnings);
@@ -522,7 +522,7 @@  discard block
 block discarded – undo
522 522
 {
523 523
     $home = getenv('COMPOSER_HOME');
524 524
 
525
-    if (!$home) {
525
+    if ( ! $home) {
526 526
         $userDir = getUserDir();
527 527
 
528 528
         if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
@@ -530,9 +530,9 @@  discard block
 block discarded – undo
530 530
         } else {
531 531
             $home = $userDir.'/.composer';
532 532
 
533
-            if (!is_dir($home) && useXdg()) {
533
+            if ( ! is_dir($home) && useXdg()) {
534 534
                 // XDG Base Directory Specifications
535
-                if (!($xdgConfig = getenv('XDG_CONFIG_HOME'))) {
535
+                if ( ! ($xdgConfig = getenv('XDG_CONFIG_HOME'))) {
536 536
                     $xdgConfig = $userDir.'/.config';
537 537
                 }
538 538
                 $home = $xdgConfig.'/composer';
@@ -553,7 +553,7 @@  discard block
 block discarded – undo
553 553
     $userEnv = defined('PHP_WINDOWS_VERSION_MAJOR') ? 'APPDATA' : 'HOME';
554 554
     $userDir = getenv($userEnv);
555 555
 
556
-    if (!$userDir) {
556
+    if ( ! $userDir) {
557 557
         throw new RuntimeException('The '.$userEnv.' or COMPOSER_HOME environment variable must be set for composer to run correctly');
558 558
     }
559 559
 
@@ -582,7 +582,7 @@  discard block
 block discarded – undo
582 582
         || (PHP_VERSION_ID >= 50400 && PHP_VERSION_ID < 50422)
583 583
         || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50506)
584 584
     ) {
585
-        return !empty($contents);
585
+        return ! empty($contents);
586 586
     }
587 587
 
588 588
     return (bool) openssl_x509_parse($contents);
@@ -639,9 +639,9 @@  discard block
 block discarded – undo
639 639
             $this->httpClient = new HttpClient($this->disableTls, $this->cafile);
640 640
             $result = $this->install($version, $channel);
641 641
 
642
-            if ($result && $channel !== 'stable' && !$version && defined('PHP_BINARY')) {
642
+            if ($result && $channel !== 'stable' && ! $version && defined('PHP_BINARY')) {
643 643
                 $null = (defined('PHP_WINDOWS_VERSION_MAJOR') ? 'NUL' : '/dev/null');
644
-                @exec(escapeshellarg(PHP_BINARY) .' '.escapeshellarg($this->target).' self-update --'.$channel.' --set-channel-only -q > '.$null.' 2> '.$null, $output);
644
+                @exec(escapeshellarg(PHP_BINARY).' '.escapeshellarg($this->target).' self-update --'.$channel.' --set-channel-only -q > '.$null.' 2> '.$null, $output);
645 645
             }
646 646
         } catch (Exception $e) {
647 647
             $result = false;
@@ -652,7 +652,7 @@  discard block
 block discarded – undo
652 652
 
653 653
         if (isset($e)) {
654 654
             // Rethrow anything that is not a RuntimeException
655
-            if (!$e instanceof RuntimeException) {
655
+            if ( ! $e instanceof RuntimeException) {
656 656
                 throw $e;
657 657
             }
658 658
             out($e->getMessage(), 'error');
@@ -672,7 +672,7 @@  discard block
 block discarded – undo
672 672
         $this->installPath = (is_dir($installDir) ? rtrim($installDir, '/').'/' : '').$filename;
673 673
         $installDir = realpath($installDir) ? realpath($installDir) : getcwd();
674 674
 
675
-        if (!is_writeable($installDir)) {
675
+        if ( ! is_writeable($installDir)) {
676 676
             throw new RuntimeException('The installation directory "'.$installDir.'" is not writable');
677 677
         }
678 678
 
@@ -693,7 +693,7 @@  discard block
 block discarded – undo
693 693
             return;
694 694
         }
695 695
 
696
-        if (!in_array('sha384', array_map('strtolower', openssl_get_md_methods()))) {
696
+        if ( ! in_array('sha384', array_map('strtolower', openssl_get_md_methods()))) {
697 697
             throw new RuntimeException('SHA384 is not supported by your openssl extension');
698 698
         }
699 699
 
@@ -705,7 +705,7 @@  discard block
 block discarded – undo
705 705
             'tags' => $this->installKey(self::getPKTags(), $home, 'keys.tags.pub')
706 706
         );
707 707
 
708
-        if (empty($this->cafile) && !HttpClient::getSystemCaRootBundlePath()) {
708
+        if (empty($this->cafile) && ! HttpClient::getSystemCaRootBundlePath()) {
709 709
             $this->cafile = $this->installKey(HttpClient::getPackagedCaFile(), $home, 'cacert.pem');
710 710
         }
711 711
     }
@@ -720,10 +720,10 @@  discard block
 block discarded – undo
720 720
     {
721 721
         $home = getHomeDir();
722 722
 
723
-        if (!is_dir($home)) {
723
+        if ( ! is_dir($home)) {
724 724
             $this->errHandler->start();
725 725
 
726
-            if (!mkdir($home, 0777, true)) {
726
+            if ( ! mkdir($home, 0777, true)) {
727 727
                 throw new RuntimeException(sprintf(
728 728
                     'Unable to create Composer home directory "%s": %s',
729 729
                     $home,
@@ -757,11 +757,11 @@  discard block
 block discarded – undo
757 757
 
758 758
         $this->errHandler->stop();
759 759
 
760
-        if (!$write) {
760
+        if ( ! $write) {
761 761
             throw new RuntimeException(sprintf('Unable to write %s to: %s', $filename, $path));
762 762
         }
763 763
 
764
-        if (!$installed) {
764
+        if ( ! $installed) {
765 765
             $this->installs[] = $target;
766 766
         }
767 767
 
@@ -784,23 +784,23 @@  discard block
 block discarded – undo
784 784
         $infoType = 'info';
785 785
 
786 786
         while ($retries--) {
787
-            if (!$this->quiet) {
787
+            if ( ! $this->quiet) {
788 788
                 out($infoMsg, $infoType);
789 789
                 $infoMsg = 'Retrying...';
790 790
                 $infoType = 'error';
791 791
             }
792 792
 
793
-            if (!$this->getVersion($channel, $version, $url, $error)) {
793
+            if ( ! $this->getVersion($channel, $version, $url, $error)) {
794 794
                 out($error, 'error');
795 795
                 continue;
796 796
             }
797 797
 
798
-            if (!$this->downloadToTmp($url, $signature, $error)) {
798
+            if ( ! $this->downloadToTmp($url, $signature, $error)) {
799 799
                 out($error, 'error');
800 800
                 continue;
801 801
             }
802 802
 
803
-            if (!$this->verifyAndSave($version, $signature, $error)) {
803
+            if ( ! $this->verifyAndSave($version, $signature, $error)) {
804 804
                 out($error, 'error');
805 805
                 continue;
806 806
             }
@@ -809,7 +809,7 @@  discard block
 block discarded – undo
809 809
             break;
810 810
         }
811 811
 
812
-        if (!$this->quiet) {
812
+        if ( ! $this->quiet) {
813 813
             if ($result) {
814 814
                 out(PHP_EOL."Composer (version {$version}) successfully installed to: {$this->target}", 'success');
815 815
                 out("Use it: php {$this->installPath}", 'info');
@@ -865,12 +865,12 @@  discard block
 block discarded – undo
865 865
         $url = $this->baseUrl.'/versions';
866 866
         $errFmt = 'The "%s" file could not be %s: %s';
867 867
 
868
-        if (!$json = $this->httpClient->get($url)) {
868
+        if ( ! $json = $this->httpClient->get($url)) {
869 869
             $error = sprintf($errFmt, $url, 'downloaded', $this->errHandler->message);
870 870
             return false;
871 871
         }
872 872
 
873
-        if (!$data = json_decode($json, true)) {
873
+        if ( ! $data = json_decode($json, true)) {
874 874
             $error = sprintf($errFmt, $url, 'json-decoded', $this->getJsonError());
875 875
             return false;
876 876
         }
@@ -893,13 +893,13 @@  discard block
 block discarded – undo
893 893
         $sigUrl = $url.'.sig';
894 894
         $this->errHandler->start();
895 895
 
896
-        if (!$fh = fopen($this->tmpFile, 'w')) {
896
+        if ( ! $fh = fopen($this->tmpFile, 'w')) {
897 897
             $error = sprintf('Could not create file "%s": %s', $this->tmpFile, $this->errHandler->message);
898 898
 
899
-        } elseif (!$this->getSignature($sigUrl, $signature)) {
899
+        } elseif ( ! $this->getSignature($sigUrl, $signature)) {
900 900
             $error = sprintf($errFmt, $sigUrl, $this->errHandler->message);
901 901
 
902
-        } elseif (!fwrite($fh, $this->httpClient->get($url))) {
902
+        } elseif ( ! fwrite($fh, $this->httpClient->get($url))) {
903 903
             $error = sprintf($errFmt, $url, $this->errHandler->message);
904 904
         }
905 905
 
@@ -923,16 +923,16 @@  discard block
 block discarded – undo
923 923
     {
924 924
         $error = '';
925 925
 
926
-        if (!$this->validatePhar($this->tmpFile, $pharError)) {
926
+        if ( ! $this->validatePhar($this->tmpFile, $pharError)) {
927 927
             $error = 'The download is corrupt: '.$pharError;
928 928
 
929
-        } elseif (!$this->verifySignature($version, $signature, $this->tmpFile)) {
929
+        } elseif ( ! $this->verifySignature($version, $signature, $this->tmpFile)) {
930 930
             $error = 'Signature mismatch, could not verify the phar file integrity';
931 931
 
932 932
         } else {
933 933
             $this->errHandler->start();
934 934
 
935
-            if (!rename($this->tmpFile, $this->target)) {
935
+            if ( ! rename($this->tmpFile, $this->target)) {
936 936
                 $error = sprintf('Could not write to file "%s": %s', $this->target, $this->errHandler->message);
937 937
             }
938 938
             chmod($this->target, 0755);
@@ -960,7 +960,7 @@  discard block
 block discarded – undo
960 960
             }
961 961
         }
962 962
 
963
-        if (!$version) {
963
+        if ( ! $version) {
964 964
             $error = sprintf(
965 965
                 'None of the %d %s version(s) of Composer matches your PHP version (%s / ID: %d)',
966 966
                 count($data[$channel]),
@@ -982,7 +982,7 @@  discard block
 block discarded – undo
982 982
      */
983 983
     protected function getSignature($url, &$signature)
984 984
     {
985
-        if (!$result = $this->disableTls) {
985
+        if ( ! $result = $this->disableTls) {
986 986
             $signature = $this->httpClient->get($url);
987 987
 
988 988
             if ($signature) {
@@ -1006,7 +1006,7 @@  discard block
 block discarded – undo
1006 1006
      */
1007 1007
     protected function verifySignature($version, $signature, $file)
1008 1008
     {
1009
-        if (!$result = $this->disableTls) {
1009
+        if ( ! $result = $this->disableTls) {
1010 1010
             $path = preg_match('{^[0-9a-f]{40}$}', $version) ? $this->pubKeys['dev'] : $this->pubKeys['tags'];
1011 1011
             $pubkeyid = openssl_pkey_get_public('file://'.$path);
1012 1012
 
@@ -1045,7 +1045,7 @@  discard block
 block discarded – undo
1045 1045
             $result = true;
1046 1046
 
1047 1047
         } catch (Exception $e) {
1048
-            if (!$e instanceof UnexpectedValueException && !$e instanceof PharException) {
1048
+            if ( ! $e instanceof UnexpectedValueException && ! $e instanceof PharException) {
1049 1049
                 throw $e;
1050 1050
             }
1051 1051
             $error = $e->getMessage();
@@ -1075,7 +1075,7 @@  discard block
 block discarded – undo
1075 1075
      */
1076 1076
     protected function cleanUp($result)
1077 1077
     {
1078
-        if (!$result) {
1078
+        if ( ! $result) {
1079 1079
             // Output buffered errors
1080 1080
             if ($this->quiet) {
1081 1081
                 $this->outputErrors();
@@ -1095,7 +1095,7 @@  discard block
 block discarded – undo
1095 1095
         $shown = array();
1096 1096
 
1097 1097
         foreach ($errors as $error) {
1098
-            if ($error && !in_array($error, $shown)) {
1098
+            if ($error && ! in_array($error, $shown)) {
1099 1099
                 out($error, 'error');
1100 1100
                 $shown[] = $error;
1101 1101
             }
@@ -1188,7 +1188,7 @@  discard block
 block discarded – undo
1188 1188
      */
1189 1189
     public function start()
1190 1190
     {
1191
-        if (!$this->active) {
1191
+        if ( ! $this->active) {
1192 1192
             set_error_handler(array($this, 'handleError'));
1193 1193
             $this->active = true;
1194 1194
         }
@@ -1239,7 +1239,7 @@  discard block
 block discarded – undo
1239 1239
      */
1240 1240
     public function test($url)
1241 1241
     {
1242
-        if (!$this->composerInNoProxy) {
1242
+        if ( ! $this->composerInNoProxy) {
1243 1243
             return false;
1244 1244
         }
1245 1245
 
@@ -1266,9 +1266,9 @@  discard block
 block discarded – undo
1266 1266
     {
1267 1267
         $this->disableTls = $disableTls;
1268 1268
         if ($this->disableTls === false) {
1269
-            if (!empty($cafile) && !is_dir($cafile)) {
1270
-                if (!is_readable($cafile) || !validateCaFile(file_get_contents($cafile))) {
1271
-                    throw new RuntimeException('The configured cafile (' .$cafile. ') was not valid or could not be read.');
1269
+            if ( ! empty($cafile) && ! is_dir($cafile)) {
1270
+                if ( ! is_readable($cafile) || ! validateCaFile(file_get_contents($cafile))) {
1271
+                    throw new RuntimeException('The configured cafile ('.$cafile.') was not valid or could not be read.');
1272 1272
                 }
1273 1273
             }
1274 1274
             $options = $this->getTlsStreamContextDefaults($cafile);
@@ -1300,7 +1300,7 @@  discard block
 block discarded – undo
1300 1300
                     $result = file_get_contents('compress.zlib://data:application/octet-stream;base64,'.base64_encode($result));
1301 1301
                 }
1302 1302
 
1303
-                if (!$result) {
1303
+                if ( ! $result) {
1304 1304
                     throw new RuntimeException('Failed to decode zlib stream');
1305 1305
                 }
1306 1306
             }
@@ -1385,7 +1385,7 @@  discard block
 block discarded – undo
1385 1385
          * Attempt to find a local cafile or throw an exception.
1386 1386
          * The user may go download one if this occurs.
1387 1387
          */
1388
-        if (!$cafile) {
1388
+        if ( ! $cafile) {
1389 1389
             $cafile = self::getSystemCaRootBundlePath();
1390 1390
         }
1391 1391
         if (is_dir($cafile)) {
@@ -1420,34 +1420,34 @@  discard block
 block discarded – undo
1420 1420
         $options = $this->options;
1421 1421
 
1422 1422
         // Handle HTTP_PROXY/http_proxy on CLI only for security reasons
1423
-        if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && (!empty($_SERVER['HTTP_PROXY']) || !empty($_SERVER['http_proxy']))) {
1424
-            $proxy = parse_url(!empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
1423
+        if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && ( ! empty($_SERVER['HTTP_PROXY']) || ! empty($_SERVER['http_proxy']))) {
1424
+            $proxy = parse_url( ! empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
1425 1425
         }
1426 1426
 
1427 1427
         // Prefer CGI_HTTP_PROXY if available
1428
-        if (!empty($_SERVER['CGI_HTTP_PROXY'])) {
1428
+        if ( ! empty($_SERVER['CGI_HTTP_PROXY'])) {
1429 1429
             $proxy = parse_url($_SERVER['CGI_HTTP_PROXY']);
1430 1430
         }
1431 1431
 
1432 1432
         // Override with HTTPS proxy if present and URL is https
1433
-        if (preg_match('{^https://}i', $url) && (!empty($_SERVER['HTTPS_PROXY']) || !empty($_SERVER['https_proxy']))) {
1434
-            $proxy = parse_url(!empty($_SERVER['https_proxy']) ? $_SERVER['https_proxy'] : $_SERVER['HTTPS_PROXY']);
1433
+        if (preg_match('{^https://}i', $url) && ( ! empty($_SERVER['HTTPS_PROXY']) || ! empty($_SERVER['https_proxy']))) {
1434
+            $proxy = parse_url( ! empty($_SERVER['https_proxy']) ? $_SERVER['https_proxy'] : $_SERVER['HTTPS_PROXY']);
1435 1435
         }
1436 1436
 
1437 1437
         // Remove proxy if URL matches no_proxy directive
1438
-        if (!empty($_SERVER['NO_PROXY']) || !empty($_SERVER['no_proxy']) && parse_url($url, PHP_URL_HOST)) {
1439
-            $pattern = new NoProxyPattern(!empty($_SERVER['no_proxy']) ? $_SERVER['no_proxy'] : $_SERVER['NO_PROXY']);
1438
+        if ( ! empty($_SERVER['NO_PROXY']) || ! empty($_SERVER['no_proxy']) && parse_url($url, PHP_URL_HOST)) {
1439
+            $pattern = new NoProxyPattern( ! empty($_SERVER['no_proxy']) ? $_SERVER['no_proxy'] : $_SERVER['NO_PROXY']);
1440 1440
             if ($pattern->test($url)) {
1441 1441
                 unset($proxy);
1442 1442
             }
1443 1443
         }
1444 1444
 
1445
-        if (!empty($proxy)) {
1446
-            $proxyURL = isset($proxy['scheme']) ? $proxy['scheme'] . '://' : '';
1445
+        if ( ! empty($proxy)) {
1446
+            $proxyURL = isset($proxy['scheme']) ? $proxy['scheme'].'://' : '';
1447 1447
             $proxyURL .= isset($proxy['host']) ? $proxy['host'] : '';
1448 1448
 
1449 1449
             if (isset($proxy['port'])) {
1450
-                $proxyURL .= ":" . $proxy['port'];
1450
+                $proxyURL .= ":".$proxy['port'];
1451 1451
             } elseif ('http://' == substr($proxyURL, 0, 7)) {
1452 1452
                 $proxyURL .= ":80";
1453 1453
             } elseif ('https://' == substr($proxyURL, 0, 8)) {
@@ -1457,7 +1457,7 @@  discard block
 block discarded – undo
1457 1457
             // http(s):// is not supported in proxy
1458 1458
             $proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL);
1459 1459
 
1460
-            if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) {
1460
+            if (0 === strpos($proxyURL, 'ssl:') && ! extension_loaded('openssl')) {
1461 1461
                 throw new RuntimeException('You must enable the openssl extension to use a proxy over https');
1462 1462
             }
1463 1463
 
@@ -1485,7 +1485,7 @@  discard block
 block discarded – undo
1485 1485
             if (isset($proxy['user'])) {
1486 1486
                 $auth = rawurldecode($proxy['user']);
1487 1487
                 if (isset($proxy['pass'])) {
1488
-                    $auth .= ':' . rawurldecode($proxy['pass']);
1488
+                    $auth .= ':'.rawurldecode($proxy['pass']);
1489 1489
                 }
1490 1490
                 $auth = base64_encode($auth);
1491 1491
 
Please login to merge, or discard this patch.