Wordpress 4.6
[autoinstalls/wordpress.git] / wp-admin / setup-config.php
1 <?php
2 /**
3  * Retrieves and creates the wp-config.php file.
4  *
5  * The permissions for the base directory must allow for writing files in order
6  * for the wp-config.php to be created using this page.
7  *
8  * @internal This file must be parsable by PHP4.
9  *
10  * @package WordPress
11  * @subpackage Administration
12  */
13
14 /**
15  * We are installing.
16  */
17 define('WP_INSTALLING', true);
18
19 /**
20  * We are blissfully unaware of anything.
21  */
22 define('WP_SETUP_CONFIG', true);
23
24 /**
25  * Disable error reporting
26  *
27  * Set this to error_reporting( -1 ) for debugging
28  */
29 error_reporting(0);
30
31 if ( ! defined( 'ABSPATH' ) ) {
32         define( 'ABSPATH', dirname( dirname( __FILE__ ) ) . '/' );
33 }
34
35 require( ABSPATH . 'wp-settings.php' );
36
37 /** Load WordPress Administration Upgrade API */
38 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
39
40 /** Load WordPress Translation Install API */
41 require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
42
43 nocache_headers();
44
45 // Support wp-config-sample.php one level up, for the develop repo.
46 if ( file_exists( ABSPATH . 'wp-config-sample.php' ) )
47         $config_file = file( ABSPATH . 'wp-config-sample.php' );
48 elseif ( file_exists( dirname( ABSPATH ) . '/wp-config-sample.php' ) )
49         $config_file = file( dirname( ABSPATH ) . '/wp-config-sample.php' );
50 else
51         wp_die( __( 'Sorry, I need a wp-config-sample.php file to work from. Please re-upload this file to your WordPress installation.' ) );
52
53 // Check if wp-config.php has been created
54 if ( file_exists( ABSPATH . 'wp-config.php' ) )
55         wp_die( '<p>' . sprintf(
56                         /* translators: %s: install.php */
57                         __( "The file 'wp-config.php' already exists. If you need to reset any of the configuration items in this file, please delete it first. You may try <a href='%s'>installing now</a>." ),
58                         'install.php'
59                 ) . '</p>'
60         );
61
62 // Check if wp-config.php exists above the root directory but is not part of another install
63 if ( @file_exists( ABSPATH . '../wp-config.php' ) && ! @file_exists( ABSPATH . '../wp-settings.php' ) ) {
64         wp_die( '<p>' . sprintf(
65                         /* translators: %s: install.php */
66                         __( "The file 'wp-config.php' already exists one level above your WordPress installation. If you need to reset any of the configuration items in this file, please delete it first. You may try <a href='%s'>installing now</a>." ),
67                         'install.php'
68                 ) . '</p>'
69         );
70 }
71
72 $step = isset( $_GET['step'] ) ? (int) $_GET['step'] : -1;
73
74 /**
75  * Display setup wp-config.php file header.
76  *
77  * @ignore
78  * @since 2.3.0
79  *
80  * @global string    $wp_local_package
81  * @global WP_Locale $wp_locale
82  *
83  * @param string|array $body_classes
84  */
85 function setup_config_display_header( $body_classes = array() ) {
86         $body_classes = (array) $body_classes;
87         $body_classes[] = 'wp-core-ui';
88         if ( is_rtl() ) {
89                 $body_classes[] = 'rtl';
90         }
91
92         header( 'Content-Type: text/html; charset=utf-8' );
93 ?>
94 <!DOCTYPE html>
95 <html xmlns="http://www.w3.org/1999/xhtml"<?php if ( is_rtl() ) echo ' dir="rtl"'; ?>>
96 <head>
97         <meta name="viewport" content="width=device-width" />
98         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
99         <meta name="robots" content="noindex,nofollow" />
100         <title><?php _e( 'WordPress &rsaquo; Setup Configuration File' ); ?></title>
101         <?php wp_admin_css( 'install', true ); ?>
102 </head>
103 <body class="<?php echo implode( ' ', $body_classes ); ?>">
104 <p id="logo"><a href="<?php esc_attr_e( 'https://wordpress.org/' ); ?>" tabindex="-1"><?php _e( 'WordPress' ); ?></a></p>
105 <?php
106 } // end function setup_config_display_header();
107
108 $language = '';
109 if ( ! empty( $_REQUEST['language'] ) ) {
110         $language = preg_replace( '/[^a-zA-Z_]/', '', $_REQUEST['language'] );
111 } elseif ( isset( $GLOBALS['wp_local_package'] ) ) {
112         $language = $GLOBALS['wp_local_package'];
113 }
114
115 switch($step) {
116         case -1:
117                 if ( wp_can_install_language_pack() && empty( $language ) && ( $languages = wp_get_available_translations() ) ) {
118                         setup_config_display_header( 'language-chooser' );
119                         echo '<h1 class="screen-reader-text">Select a default language</h1>';
120                         echo '<form id="setup" method="post" action="?step=0">';
121                         wp_install_language_form( $languages );
122                         echo '</form>';
123                         break;
124                 }
125
126                 // Deliberately fall through if we can't reach the translations API.
127
128         case 0:
129                 if ( ! empty( $language ) ) {
130                         $loaded_language = wp_download_language_pack( $language );
131                         if ( $loaded_language ) {
132                                 load_default_textdomain( $loaded_language );
133                                 $GLOBALS['wp_locale'] = new WP_Locale();
134                         }
135                 }
136
137                 setup_config_display_header();
138                 $step_1 = 'setup-config.php?step=1';
139                 if ( isset( $_REQUEST['noapi'] ) ) {
140                         $step_1 .= '&amp;noapi';
141                 }
142                 if ( ! empty( $loaded_language ) ) {
143                         $step_1 .= '&amp;language=' . $loaded_language;
144                 }
145 ?>
146 <h1 class="screen-reader-text"><?php _e( 'Before getting started' ) ?></h1>
147 <p><?php _e( 'Welcome to WordPress. Before getting started, we need some information on the database. You will need to know the following items before proceeding.' ) ?></p>
148 <ol>
149         <li><?php _e( 'Database name' ); ?></li>
150         <li><?php _e( 'Database username' ); ?></li>
151         <li><?php _e( 'Database password' ); ?></li>
152         <li><?php _e( 'Database host' ); ?></li>
153         <li><?php _e( 'Table prefix (if you want to run more than one WordPress in a single database)' ); ?></li>
154 </ol>
155 <p><?php
156         /* translators: %s: wp-config.php */
157         printf( __( 'We&#8217;re going to use this information to create a %s file.' ),
158                 '<code>wp-config.php</code>'
159         );
160         ?>
161         <strong><?php
162                 /* translators: 1: wp-config-sample.php, 2: wp-config.php */
163                 printf( __( 'If for any reason this automatic file creation doesn&#8217;t work, don&#8217;t worry. All this does is fill in the database information to a configuration file. You may also simply open %1$s in a text editor, fill in your information, and save it as %2$s.' ),
164                         '<code>wp-config-sample.php</code>',
165                         '<code>wp-config.php</code>'
166                 );
167         ?></strong>
168         <?php
169         /* translators: %s: Codex URL */
170         printf( __( 'Need more help? <a href="%s">We got it</a>.' ),
171                 __( 'https://codex.wordpress.org/Editing_wp-config.php' )
172         );
173 ?></p>
174 <p><?php _e( 'In all likelihood, these items were supplied to you by your Web Host. If you don&#8217;t have this information, then you will need to contact them before you can continue. If you&#8217;re all ready&hellip;' ); ?></p>
175
176 <p class="step"><a href="<?php echo $step_1; ?>" class="button button-large"><?php _e( 'Let&#8217;s go!' ); ?></a></p>
177 <?php
178         break;
179
180         case 1:
181                 load_default_textdomain( $language );
182                 $GLOBALS['wp_locale'] = new WP_Locale();
183
184                 setup_config_display_header();
185         ?>
186 <h1 class="screen-reader-text"><?php _e( 'Set up your database connection' ) ?></h1>
187 <form method="post" action="setup-config.php?step=2">
188         <p><?php _e( 'Below you should enter your database connection details. If you&#8217;re not sure about these, contact your host.' ); ?></p>
189         <table class="form-table">
190                 <tr>
191                         <th scope="row"><label for="dbname"><?php _e( 'Database Name' ); ?></label></th>
192                         <td><input name="dbname" id="dbname" type="text" size="25" value="wordpress" /></td>
193                         <td><?php _e( 'The name of the database you want to use with WordPress.' ); ?></td>
194                 </tr>
195                 <tr>
196                         <th scope="row"><label for="uname"><?php _e( 'Username' ); ?></label></th>
197                         <td><input name="uname" id="uname" type="text" size="25" value="<?php echo htmlspecialchars( _x( 'username', 'example username' ), ENT_QUOTES ); ?>" /></td>
198                         <td><?php _e( 'Your database username.' ); ?></td>
199                 </tr>
200                 <tr>
201                         <th scope="row"><label for="pwd"><?php _e( 'Password' ); ?></label></th>
202                         <td><input name="pwd" id="pwd" type="text" size="25" value="<?php echo htmlspecialchars( _x( 'password', 'example password' ), ENT_QUOTES ); ?>" autocomplete="off" /></td>
203                         <td><?php _e( 'Your database password.' ); ?></td>
204                 </tr>
205                 <tr>
206                         <th scope="row"><label for="dbhost"><?php _e( 'Database Host' ); ?></label></th>
207                         <td><input name="dbhost" id="dbhost" type="text" size="25" value="localhost" /></td>
208                         <td><?php
209                                 /* translators: %s: localhost */
210                                 printf( __( 'You should be able to get this info from your web host, if %s doesn&#8217;t work.' ),'<code>localhost</code>' );
211                         ?></td>
212                 </tr>
213                 <tr>
214                         <th scope="row"><label for="prefix"><?php _e( 'Table Prefix' ); ?></label></th>
215                         <td><input name="prefix" id="prefix" type="text" value="wp_" size="25" /></td>
216                         <td><?php _e( 'If you want to run multiple WordPress installations in a single database, change this.' ); ?></td>
217                 </tr>
218         </table>
219         <?php if ( isset( $_GET['noapi'] ) ) { ?><input name="noapi" type="hidden" value="1" /><?php } ?>
220         <input type="hidden" name="language" value="<?php echo esc_attr( $language ); ?>" />
221         <p class="step"><input name="submit" type="submit" value="<?php echo htmlspecialchars( __( 'Submit' ), ENT_QUOTES ); ?>" class="button button-large" /></p>
222 </form>
223 <?php
224         break;
225
226         case 2:
227         load_default_textdomain( $language );
228         $GLOBALS['wp_locale'] = new WP_Locale();
229
230         $dbname = trim( wp_unslash( $_POST[ 'dbname' ] ) );
231         $uname = trim( wp_unslash( $_POST[ 'uname' ] ) );
232         $pwd = trim( wp_unslash( $_POST[ 'pwd' ] ) );
233         $dbhost = trim( wp_unslash( $_POST[ 'dbhost' ] ) );
234         $prefix = trim( wp_unslash( $_POST[ 'prefix' ] ) );
235
236         $step_1 = 'setup-config.php?step=1';
237         $install = 'install.php';
238         if ( isset( $_REQUEST['noapi'] ) ) {
239                 $step_1 .= '&amp;noapi';
240         }
241
242         if ( ! empty( $language ) ) {
243                 $step_1 .= '&amp;language=' . $language;
244                 $install .= '?language=' . $language;
245         } else {
246                 $install .= '?language=en_US';
247         }
248
249         $tryagain_link = '</p><p class="step"><a href="' . $step_1 . '" onclick="javascript:history.go(-1);return false;" class="button button-large">' . __( 'Try again' ) . '</a>';
250
251         if ( empty( $prefix ) )
252                 wp_die( __( '<strong>ERROR</strong>: "Table Prefix" must not be empty.' . $tryagain_link ) );
253
254         // Validate $prefix: it can only contain letters, numbers and underscores.
255         if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
256                 wp_die( __( '<strong>ERROR</strong>: "Table Prefix" can only contain numbers, letters, and underscores.' . $tryagain_link ) );
257
258         // Test the db connection.
259         /**#@+
260          * @ignore
261          */
262         define('DB_NAME', $dbname);
263         define('DB_USER', $uname);
264         define('DB_PASSWORD', $pwd);
265         define('DB_HOST', $dbhost);
266         /**#@-*/
267
268         // Re-construct $wpdb with these new values.
269         unset( $wpdb );
270         require_wp_db();
271
272         /*
273          * The wpdb constructor bails when WP_SETUP_CONFIG is set, so we must
274          * fire this manually. We'll fail here if the values are no good.
275          */
276         $wpdb->db_connect();
277
278         if ( ! empty( $wpdb->error ) )
279                 wp_die( $wpdb->error->get_error_message() . $tryagain_link );
280
281         $wpdb->query( "SELECT $prefix" );
282         if ( ! $wpdb->last_error ) {
283                 // MySQL was able to parse the prefix as a value, which we don't want. Bail.
284                 wp_die( __( '<strong>ERROR</strong>: "Table Prefix" is invalid.' ) );
285         }
286
287         // Generate keys and salts using secure CSPRNG; fallback to API if enabled; further fallback to original wp_generate_password().
288         try {
289                 $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_ []{}<>~`+=,.;:/?|';
290                 $max = strlen($chars) - 1;
291                 for ( $i = 0; $i < 8; $i++ ) {
292                         $key = '';
293                         for ( $j = 0; $j < 64; $j++ ) {
294                                 $key .= substr( $chars, random_int( 0, $max ), 1 );
295                         }
296                         $secret_keys[] = $key;
297                 }
298         } catch ( Exception $ex ) {
299                 $no_api = isset( $_POST['noapi'] );
300
301                 if ( ! $no_api ) {
302                         $secret_keys = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' );
303                 }
304
305                 if ( $no_api || is_wp_error( $secret_keys ) ) {
306                         $secret_keys = array();
307                         for ( $i = 0; $i < 8; $i++ ) {
308                                 $secret_keys[] = wp_generate_password( 64, true, true );
309                         }
310                 } else {
311                         $secret_keys = explode( "\n", wp_remote_retrieve_body( $secret_keys ) );
312                         foreach ( $secret_keys as $k => $v ) {
313                                 $secret_keys[$k] = substr( $v, 28, 64 );
314                         }
315                 }
316         }
317
318         $key = 0;
319         // Not a PHP5-style by-reference foreach, as this file must be parseable by PHP4.
320         foreach ( $config_file as $line_num => $line ) {
321                 if ( '$table_prefix  =' == substr( $line, 0, 16 ) ) {
322                         $config_file[ $line_num ] = '$table_prefix  = \'' . addcslashes( $prefix, "\\'" ) . "';\r\n";
323                         continue;
324                 }
325
326                 if ( ! preg_match( '/^define\(\'([A-Z_]+)\',([ ]+)/', $line, $match ) )
327                         continue;
328
329                 $constant = $match[1];
330                 $padding  = $match[2];
331
332                 switch ( $constant ) {
333                         case 'DB_NAME'     :
334                         case 'DB_USER'     :
335                         case 'DB_PASSWORD' :
336                         case 'DB_HOST'     :
337                                 $config_file[ $line_num ] = "define('" . $constant . "'," . $padding . "'" . addcslashes( constant( $constant ), "\\'" ) . "');\r\n";
338                                 break;
339                         case 'DB_CHARSET'  :
340                                 if ( 'utf8mb4' === $wpdb->charset || ( ! $wpdb->charset && $wpdb->has_cap( 'utf8mb4' ) ) ) {
341                                         $config_file[ $line_num ] = "define('" . $constant . "'," . $padding . "'utf8mb4');\r\n";
342                                 }
343                                 break;
344                         case 'AUTH_KEY'         :
345                         case 'SECURE_AUTH_KEY'  :
346                         case 'LOGGED_IN_KEY'    :
347                         case 'NONCE_KEY'        :
348                         case 'AUTH_SALT'        :
349                         case 'SECURE_AUTH_SALT' :
350                         case 'LOGGED_IN_SALT'   :
351                         case 'NONCE_SALT'       :
352                                 $config_file[ $line_num ] = "define('" . $constant . "'," . $padding . "'" . $secret_keys[$key++] . "');\r\n";
353                                 break;
354                 }
355         }
356         unset( $line );
357
358         if ( ! is_writable(ABSPATH) ) :
359                 setup_config_display_header();
360 ?>
361 <p><?php
362         /* translators: %s: wp-config.php */
363         printf( __( 'Sorry, but I can&#8217;t write the %s file.' ), '<code>wp-config.php</code>' );
364 ?></p>
365 <p><?php
366         /* translators: %s: wp-config.php */
367         printf( __( 'You can create the %s manually and paste the following text into it.' ), '<code>wp-config.php</code>' );
368 ?></p>
369 <textarea id="wp-config" cols="98" rows="15" class="code" readonly="readonly"><?php
370                 foreach ( $config_file as $line ) {
371                         echo htmlentities($line, ENT_COMPAT, 'UTF-8');
372                 }
373 ?></textarea>
374 <p><?php _e( 'After you&#8217;ve done that, click &#8220;Run the install.&#8221;' ); ?></p>
375 <p class="step"><a href="<?php echo $install; ?>" class="button button-large"><?php _e( 'Run the install' ); ?></a></p>
376 <script>
377 (function(){
378 if ( ! /iPad|iPod|iPhone/.test( navigator.userAgent ) ) {
379         var el = document.getElementById('wp-config');
380         el.focus();
381         el.select();
382 }
383 })();
384 </script>
385 <?php
386         else :
387                 /*
388                  * If this file doesn't exist, then we are using the wp-config-sample.php
389                  * file one level up, which is for the develop repo.
390                  */
391                 if ( file_exists( ABSPATH . 'wp-config-sample.php' ) )
392                         $path_to_wp_config = ABSPATH . 'wp-config.php';
393                 else
394                         $path_to_wp_config = dirname( ABSPATH ) . '/wp-config.php';
395
396                 $handle = fopen( $path_to_wp_config, 'w' );
397                 foreach ( $config_file as $line ) {
398                         fwrite( $handle, $line );
399                 }
400                 fclose( $handle );
401                 chmod( $path_to_wp_config, 0666 );
402                 setup_config_display_header();
403 ?>
404 <h1 class="screen-reader-text"><?php _e( 'Successful database connection' ) ?></h1>
405 <p><?php _e( 'All right, sparky! You&#8217;ve made it through this part of the installation. WordPress can now communicate with your database. If you are ready, time now to&hellip;' ); ?></p>
406
407 <p class="step"><a href="<?php echo $install; ?>" class="button button-large"><?php _e( 'Run the install' ); ?></a></p>
408 <?php
409         endif;
410         break;
411 }
412 ?>
413 <?php wp_print_scripts( 'language-chooser' ); ?>
414 </body>
415 </html>