WordPress.org

Make WordPress Core

Ticket #16509: wp-install.php

File wp-install.php, 14.3 KB (added by kurtpayne, 3 years ago)
Line 
1<?php
2
3// Turn off buffering / chunking / compression
4ini_set('output_handler', '');
5ini_set('output_buffering', false);
6ini_set('implicit_flush', true);
7if (function_exists('apache_setenv')) {
8        apache_setenv('no-gzip', '1');
9        apache_setenv('force-response-1.0', '1');
10}
11while (@ob_end_flush());
12
13// Temp dir, zip file, needed for cleanup function
14$tempdir = '';
15
16/**
17 * Fill the output buffer
18 * @return void
19 */
20function flush_buffer() {
21        if ('cli' != php_sapi_name()) {
22                echo str_repeat(chr(0), 4096);
23        }
24}
25
26/**
27 * Get the user's consent in CLI mode
28 * @return void
29 */
30function cli_confirm() {
31        echo 'Do you want to continue?  Y/N  ';
32        if ('y' != strtolower(fgetc(STDIN))) {
33                die("Installation canceled.\n");
34        }
35}
36
37/**
38 * Pre-install screen in CLI mode
39 * @return void
40 */
41function cli_pre_install_screen() {
42        global $argc, $argv;
43?>
44=====================================================================
45                      WORDPRESS AUTO DOWNLOADER
46=====================================================================
47This script will download the latest version of WordPress and extract
48the files to this folder:
49
50    <?php echo realpath(getcwd()); ?> 
51
52<?php if ($argc > 1 && '--auto' != strtolower($argv[1])) : ?>
53If you do not want to do this, cancel this script by answering N or
54pressing CTRL+C.
55<?php endif; ?>
56
57REQUIREMENTS:
58        php version >= 5.2      - <?php echo (version_compare(phpversion(), '5.2.0', '>=') ? 'Yes' : 'No'); ?>  [Version <?php echo phpversion(); ?>]
59        Can reach wordpress.org - <?php $tmp = get_url('http://wordpress.org/'); echo (!empty($tmp) ? 'Yes' : 'No'); ?> 
60
61<?php
62}
63
64/**
65 * Post-install screen in CLI mode
66 * @return void
67 */
68function cli_post_install_screen() {
69?>
70=====================================================================
71                         DOWNLOAD COMPLETE!
72=====================================================================
73Please visit your website.  The WordPress installation wizard will
74complete your site's configuration.
75
76<?php
77}
78
79/**
80 * Browser screen header
81 * @return void
82 */
83function browser_header() {
84?>
85<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
86        <head>
87                <title>WordPress Auto Downloader</title>
88                <style type="text/css">
89                        html {
90                                background: #f9f9f9;
91                        }
92
93                        body {
94                                background: #fff;
95                                color: #333;
96                                font-family: sans-serif;
97                                margin: 2em auto;
98                                width: 700px;
99                                padding: 1em 2em;
100                                -moz-border-radius: 11px;
101                                -khtml-border-radius: 11px;
102                                -webkit-border-radius: 11px;
103                                border-radius: 11px;
104                                border: 1px solid #dfdfdf;
105                        }
106
107                        a {
108                                color: #2583ad;
109                                text-decoration: none;
110                        }
111
112                        a:hover {
113                                color: #d54e21;
114                        }
115
116                        h1 {
117                                border-bottom: 1px solid #dadada;
118                                clear: both;
119                                color: #666;
120                                font: 24px Georgia, "Times New Roman", Times, serif;
121                                margin: 5px 0 0 -4px;
122                                padding: 0;
123                                padding-bottom: 7px;
124                        }
125
126                        h2 {
127                                font-size: 16px;
128                        }
129
130                        p, li, dd, dt {
131                                padding-bottom: 2px;
132                                font-size: 12px;
133                                line-height: 18px;
134                        }
135
136                        code, .code {
137                                font-size: 13px;
138                        }
139
140                        ul, ol, dl {
141                                padding: 5px 5px 5px 22px;
142                        }
143
144                        a img {
145                                border:0
146                        }
147                        abbr {
148                                border: 0;
149                                font-variant: normal;
150                        }
151                        #logo {
152                                margin: 6px 0 14px 0;
153                                border-bottom: none;
154                                text-align:center
155                        }
156                        .step {
157                                margin: 20px 0 15px;
158                        }
159                        .step, .field-label {
160                                text-align: left;
161                                padding: 0;
162                        }
163
164                        .submit input, .button, .button-secondary {
165                                font-family: sans-serif;
166                                text-decoration: none;
167                                font-size: 14px !important;
168                                line-height: 16px;
169                                padding: 6px 12px;
170                                cursor: pointer;
171                                border: 1px solid #bbb;
172                                color: #464646;
173                                -moz-border-radius: 15px;
174                                -khtml-border-radius: 15px;
175                                -webkit-border-radius: 15px;
176                                border-radius: 15px;
177                                -moz-box-sizing: content-box;
178                                -webkit-box-sizing: content-box;
179                                -khtml-box-sizing: content-box;
180                                box-sizing: content-box;
181                        }
182
183                        .button:hover, .button-secondary:hover, .submit input:hover {
184                                color: #000;
185                                border-color: #666;
186                        }
187
188                        .button, .submit input, .button-secondary {
189                                background: #f2f2f2 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAACF0RVh0U29mdHdhcmUATWFjcm9tZWRpYSBGaXJld29ya3MgNC4w6iYndQAAABZ0RVh0Q3JlYXRpb24gVGltZQAxMS8xNy8wONpsdXEAAAAlSURBVHicY/z///9/BjTAhC7AwMDAwIJFIXbBoaJ9qLhz+IUSAIMMOibeSzRBAAAAAElFTkSuQmCC) repeat-x scroll left top;
190                        }
191
192                        .button:active, .submit input:active, .button-secondary:active {
193                                background: #eee url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAMAAADToCSPAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADlQTFRF7+/v8PDw8vLy7e3t+fn5////+/v7+Pj49PT0/f399vb27u7u8fHx/v7+/Pz89fX19/f38/Pz+vr68z2vlQAAADxJREFUeNpMxDkSgDAAxDBzE87A/x/LeLIFKsQg2rv465QP0Ss/YlW+xaZcxaI8Kr9iVr5EUT7FpPYnwABZDwRrFJ+PLwAAAABJRU5ErkJggg==) repeat-x scroll left top;
194                        }
195
196                        textarea {
197                                border: 1px solid #bbb;
198                                -moz-border-radius: 3px;
199                                -khtml-border-radius: 3px;
200                                -webkit-border-radius: 3px;
201                                border-radius: 3px;
202                        }
203
204                        .form-fields {
205                                margin-top: 1em;
206                                width: 100%;
207                        }
208
209                        .form-fields .field-input {
210                                margin-bottom: 9px;
211                                margin-left: 150px;
212                                padding: 10px;
213                                font-size: 12px;
214                        }
215
216                        .form-fields .field-full {
217                                margin-left: 0;
218                        }
219
220                        .form-fields .field-label {
221                                float: left;
222                                font-size: 13px;
223                                font-weight: bold;
224                                text-align: left;
225                                padding: 16px 10px 10px 10px;
226                                width: 130px;
227                                vertical-align: top;
228                        }
229
230                        .form-fields .field-row {
231                                background: #f3f3f3;
232                        }
233
234                        .form-fields code {
235                                line-height: 18px;
236                                font-size: 18px;
237                        }
238
239                        .form-fields p {
240                                margin: 4px 0 0 0;
241                                font-size: 11px;
242                        }
243
244                        .form-fields input {
245                                line-height: 20px;
246                                font-size: 15px;
247                                padding: 2px;
248                        }
249
250                        .form-fields p {
251                                font-weight: normal;
252                        }
253
254                        #error-page {
255                                margin-top: 50px;
256                        }
257
258                        #error-page p {
259                                font-size: 12px;
260                                line-height: 18px;
261                                margin: 25px 0 20px;
262                        }
263
264                        #error-page code, .code {
265                                font-family: Consolas, Monaco, monospace;
266                        }
267
268                        #pass-strength-result {
269                                background-color: #eee;
270                                border-color: #ddd !important;
271                                border-style: solid;
272                                border-width: 1px;
273                                margin: 5px 5px 5px 1px;
274                                padding: 5px;
275                                text-align: center;
276                                width: 200px;
277                                display: none;
278                        }
279
280                        #pass-strength-result.bad {
281                                background-color: #ffb78c;
282                                border-color: #ff853c !important;
283                        }
284
285                        #pass-strength-result.good {
286                                background-color: #ffec8b;
287                                border-color: #ffcc00 !important;
288                        }
289
290                        #pass-strength-result.short {
291                                background-color: #ffa0a0;
292                                border-color: #f04040 !important;
293                        }
294
295                        #pass-strength-result.strong {
296                                background-color: #c3ff88;
297                                border-color: #8dff1c !important;
298                        }
299
300                        .message {
301                                border: 1px solid #e6db55;
302                                padding: 0.3em 0.6em;
303                                margin: 5px 0 15px;
304                                background-color: #ffffe0;
305                        }
306
307
308                        /* install-rtl */
309                        body.rtl {
310                                font-family: Tahoma, arial;
311                        }
312
313                        .rtl h1 {
314                                font-family: arial;
315                                margin: 5px -4px 0 0;
316                        }
317
318                        .rtl ul,
319                        .rtl  ol {
320                                padding: 5px 22px 5px 5px;
321                        }
322
323                        .rtl .step,
324                        .rtl .field-label,
325                        .rtl .form-fields .field-label {
326                                text-align: right;
327                        }
328
329                        .rtl .submit input,
330                        .rtl .button,
331                        .rtl .button-secondary {
332                                margin-right: 0;
333                        }
334
335                        .rtl #user_login,
336                        .rtl #admin_email,
337                        .rtl #pass1,
338                        .rtl #pass2 {
339                                direction: ltr;
340                        }
341                </style>
342                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
343        </head>
344        <body id="error-page" style="height: 330px;">
345<?php
346}
347
348/**
349 * Browser screen footer
350 * @return void
351 */
352function browser_footer() {
353        ?>
354                </body>
355</html>
356<?php   
357}
358
359
360/**
361 * Pre-install screen in browser mode
362 * @return void
363 */
364function browser_pre_install_screen() {
365        browser_header();
366        ?>
367                <h1 style="text-align: center;">WordPress Auto Downloader</h1>
368                <p>This script will download the latest version of WordPress and extract the files to this folder:</p>
369                <div style="margin: auto auto 20px 50px;"><code><?php echo realpath(getcwd()); ?></code></div>
370                <p>If you do not want to do this, do not click the button below and delete this script from your server.</p>
371                <p><strong>REQUIREMENTS:</strong></p>
372                <pre>
373        php version >= 5.2      - <?php echo (version_compare(phpversion(), '5.2.0', '>=') ? 'Yes' : 'No'); ?>  [Version <?php echo phpversion(); ?>]
374        Can reach wordpress.org - <?php $tmp = get_url('http://wordpress.org/'); echo (!empty($tmp) ? 'Yes' : 'No'); ?>
375                </pre>
376                <p><a href="wp-install.php?install=yes" class="button">Download WordPress to this folder</a></p>
377        <?php
378        browser_footer();
379}
380
381/**
382 * Post-install screen in browser mode
383 * @return void
384 */
385function browser_post_install_screen() {
386?>
387        <p>
388        <strong>DOWNLOAD COMPLETE!</strong>
389        <div>
390                Please visit the <a href="<?php echo get_installation_url();?>" class="button">WordPress installation wizard</a> to
391                complete your site's configuration.
392        </div>
393        </p>
394<?php
395}
396
397/**
398 * Install WordPress
399 * @return void
400 */
401function install_wordpress() {
402        global $tempdir;
403
404        // Check permissions
405        if (!is_writable('.')) {
406                die('The current folder is not writable.');
407        }
408
409        // Create a temp folder
410        $tempdir = './wpinstall-' . substr(md5(uniqid()), -12);
411        if (false === @mkdir($tempdir)) {
412                die('Could not create temp folder');
413        }
414
415        // Download the zip file
416        $zipfile = 'http://wordpress.org/latest.zip';
417        echo "Downloading $zipfile ...\n"; flush_buffer();
418        $tmp = get_url($zipfile);
419        if (empty($tmp)) {
420                clean_up();
421                die('Cannot fetch remote resource: ' . $latest_zip);
422        }
423        file_put_contents("$tempdir/latest.zip", $tmp);
424        unset($tmp);
425
426        // Extract the zip contents
427        echo "Extracting latest.zip ...\n"; flush_buffer();
428        unzip_file("$tempdir/latest.zip", $tempdir);
429       
430        // Is it safe to move wordpress/* ?
431        echo "Checking to see if it's safe to move files from wordpress/ to current folder ...\n"; flush_buffer();
432        $dir = opendir("$tempdir/wordpress");
433        $files_in_the_way = array();
434        while (($file = readdir($dir)) !== FALSE) {
435                if ($file != '.' && $file != '..') {
436                        if (file_exists("./$file")) {
437                                $files_in_the_way[] = $file;
438                        }
439                }
440        }
441        closedir($dir);
442        if (!empty($files_in_the_way)) {
443                clean_up();
444                die("These files already exist in current folder, please remove:\n\n" . implode("\n", $files_in_the_way));
445        }
446       
447        // Move wordpress/*
448        echo "Moving files from wordpress/ to current folder ...\n"; flush_buffer();
449        $dir = opendir("$tempdir/wordpress");
450        while (($file = readdir($dir)) !== FALSE) {
451                if ($file != '.' && $file != '..') {
452                        rename("$tempdir/wordpress/$file", "./$file");
453                }
454        }
455        closedir($dir);
456
457        // Clean up
458        echo "Removing temporary files ...\n"; flush_buffer();
459        clean_up();
460
461        // Rename installer for security
462        $new_name = 'wp-install-' . md5(uniqid()) . '.php';
463        echo "Moving wp-install.php to $new_name for security ... \n"; flush_buffer();
464        rename('./wp-install.php', "./$new_name");
465}
466
467/**
468 * Get installation URL
469 * @return string
470 */
471function get_installation_url() {
472        $protocol = 'http://';
473        if ( (!empty($_SERVER['HTTPS']) && 'on' == strtolower($_SERVER['HTTPS'])) || 443 == @$_SERVER['SERVER_PORT'] ) {
474                $protocol = 'https://';
475        }
476        $domain = $_SERVER['HTTP_HOST'];
477        $path = dirname($_SERVER['SCRIPT_NAME']);
478        return $protocol.$domain.$path . '/index.php';
479}
480
481/**
482 * Clean up the installation
483 * @return void
484 */
485function clean_up() {
486        global $tempdir;
487        _rmdir("./$tempdir");
488}
489
490/**
491 * Recursively remove a directory
492 * @param string $path
493 * @return void
494 */
495function _rmdir($path) {
496        if (file_exists($path)) {
497                if (is_dir($path)) {
498                        $dir = opendir($path);
499                        while ( ($file = readdir($dir)) !== FALSE) {
500                                if ($file != '.' && $file != '..') {
501                                        $_path = "$path/$file";
502                                        if (is_dir($_path)) {
503                                                _rmdir($_path);
504                                        } elseif (is_file($_path) || is_link($_path)) {
505                                                unlink($_path);
506                                        }
507                                }
508                        }
509                        closedir($dir);
510                        rmdir($path);
511                } elseif (is_file($path) || is_link($path)) {
512                        unlink($path);
513                }
514        }
515}
516
517/**
518 * Unzip a file
519 * @param string $zipfile
520 * @param string $target
521 */
522function unzip_file($zipfile, $target) {
523       
524        // Try ZipArchive
525        if (extension_loaded('zip')) {
526                $zip = new ZipArchive();
527                if ($zip->open($zipfile) === FALSE) {
528                        clean_up();
529                        die('Cannot extract files from ' . $zipFile);
530                } else {
531                        $zip->extractTo($target);
532                        $zip->close();
533                }
534
535        // Try PclZip
536        } else {
537                eval(get_url('http://kpayne.co/pclzip.txt'));
538                $archive = new PclZip($zipfile);
539                $archive_files = $archive->extract($target);
540        }
541}
542
543/**
544 * Fetch content from a URL
545 * Supports GET method only, probably won't work with SSL
546 * Doesn't work with cookies, or anything fancy.
547 * @param string $url
548 * @return string
549 */
550function get_url($url) {
551
552        // Initialize content
553        $content = '';
554
555        // Try curl
556        if (extension_loaded('curl')) {
557                $ch = curl_init();
558                curl_setopt_array($ch, array(
559                        CURLOPT_URL            => $url,
560                        CURLOPT_HEADER         => false,
561                        CURLOPT_FOLLOWLOCATION => true,
562                        CURLOPT_RETURNTRANSFER => true
563                ));
564                $content = curl_exec($ch);
565                curl_close($ch);
566       
567        // Try file_get_contents
568        } elseif (ini_get('allow_url_fopen')) {
569                $content = file_get_contents($url);
570               
571        // Try fsockopen
572        } else {
573                $parts = parse_url($url);
574                if (empty($parts['port'])) {
575                        $parts['port'] = 80;
576                }
577                $errno = 0;
578                $errstr = '';
579                $fp = fsockopen($parts['host'], $parts['port'], $errno, $errstr);
580                if ($errno == 0) {
581                        $header_passed = false;
582                        fprintf($fp, "GET %s HTTP/1.0\nHost: %s\n\n", $url, $parts['host']);
583                        while (!feof($fp)) {
584                                $line = fgets($fp);
585                                if (!$header_passed && 0 == strlen((trim($line)))) {
586                                        $header_passed = true;
587                                        continue;
588                                }
589                                if ($header_passed) {
590                                        $content .= $line;
591                                }
592                        }
593                        fclose($fp);
594                }
595        }
596
597        // Done
598        return $content;
599}
600
601/***************/
602/**   MAIN   **/
603/**************/
604
605// CLI version
606if ('cli' == php_sapi_name()) {
607
608        // Usage
609        if (($argc > 1 && (strtolower($argv[1]) == '--help' || strtolower($argv[1]) == '--usage')) || $argc > 2) {
610                printf("Usage: %s [--auto]\n\t--auto will download WordPress without any confirmation\n", $argv[0]);
611
612        } else {
613                cli_pre_install_screen();
614               
615                // Allow quick installs with "--auto" flag
616                if ($argc > 1 && strtolower($argv[1]) == '--auto') {
617                        echo "\n";
618                } else {
619                        cli_confirm();
620                }
621
622                install_wordpress();
623                cli_post_install_screen();
624        }
625// Browser version
626} else {
627        if (!empty($_GET['install']) && 'yes' == $_GET['install']) {
628                browser_header();
629                echo '<h1 style="text-align: center;">WordPress Auto Downloader</h1>';
630                echo '<pre>'; flush_buffer();
631                install_wordpress();
632                echo '</pre>'; flush_buffer();
633                browser_post_install_screen();
634                browser_footer();
635        } else {
636                browser_pre_install_screen();
637        }
638}
639
640?>