+/**
+ * Displays a form to the user to request for their FTP/SSH details in order
+ * to connect to the filesystem.
+ *
+ * All chosen/entered details are saved, Excluding the Password.
+ *
+ * Hostnames may be in the form of hostname:portnumber (eg: wordpress.org:2467)
+ * to specify an alternate FTP/SSH port.
+ *
+ * Plugins may override this form by returning true|false via the
+ * {@see 'request_filesystem_credentials'} filter.
+ *
+ * @since 2.5.
+ *
+ * @todo Properly mark optional arguments as such
+ *
+ * @param string $form_post the URL to post the form to
+ * @param string $type the chosen Filesystem method in use
+ * @param boolean $error if the current request has failed to connect
+ * @param string $context The directory which is needed access to, The write-test will be performed on this directory by get_filesystem_method()
+ * @param array $extra_fields Extra POST fields which should be checked for to be included in the post.
+ * @param bool $allow_relaxed_file_ownership Whether to allow Group/World writable.
+ * @return boolean False on failure. True on success.
+ */
+function request_filesystem_credentials($form_post, $type = '', $error = false, $context = false, $extra_fields = null, $allow_relaxed_file_ownership = false ) {
+
+ /**
+ * Filter the filesystem credentials form output.
+ *
+ * Returning anything other than an empty string will effectively short-circuit
+ * output of the filesystem credentials form, returning that value instead.
+ *
+ * @since 2.5.0
+ *
+ * @param mixed $output Form output to return instead. Default empty.
+ * @param string $form_post URL to POST the form to.
+ * @param string $type Chosen type of filesystem.
+ * @param bool $error Whether the current request has failed to connect.
+ * Default false.
+ * @param string $context Full path to the directory that is tested for
+ * being writable.
+ * @param bool $allow_relaxed_file_ownership Whether to allow Group/World writable.
+ * @param array $extra_fields Extra POST fields.
+ */
+ $req_cred = apply_filters( 'request_filesystem_credentials', '', $form_post, $type, $error, $context, $extra_fields, $allow_relaxed_file_ownership );
+ if ( '' !== $req_cred )
+ return $req_cred;
+
+ if ( empty($type) ) {
+ $type = get_filesystem_method( array(), $context, $allow_relaxed_file_ownership );
+ }
+
+ if ( 'direct' == $type )
+ return true;
+
+ if ( is_null( $extra_fields ) )
+ $extra_fields = array( 'version', 'locale' );
+
+ $credentials = get_option('ftp_credentials', array( 'hostname' => '', 'username' => ''));
+
+ // If defined, set it to that, Else, If POST'd, set it to that, If not, Set it to whatever it previously was(saved details in option)
+ $credentials['hostname'] = defined('FTP_HOST') ? FTP_HOST : (!empty($_POST['hostname']) ? wp_unslash( $_POST['hostname'] ) : $credentials['hostname']);
+ $credentials['username'] = defined('FTP_USER') ? FTP_USER : (!empty($_POST['username']) ? wp_unslash( $_POST['username'] ) : $credentials['username']);
+ $credentials['password'] = defined('FTP_PASS') ? FTP_PASS : (!empty($_POST['password']) ? wp_unslash( $_POST['password'] ) : '');
+
+ // Check to see if we are setting the public/private keys for ssh
+ $credentials['public_key'] = defined('FTP_PUBKEY') ? FTP_PUBKEY : (!empty($_POST['public_key']) ? wp_unslash( $_POST['public_key'] ) : '');
+ $credentials['private_key'] = defined('FTP_PRIKEY') ? FTP_PRIKEY : (!empty($_POST['private_key']) ? wp_unslash( $_POST['private_key'] ) : '');
+
+ // Sanitize the hostname, Some people might pass in odd-data:
+ $credentials['hostname'] = preg_replace('|\w+://|', '', $credentials['hostname']); //Strip any schemes off
+
+ if ( strpos($credentials['hostname'], ':') ) {
+ list( $credentials['hostname'], $credentials['port'] ) = explode(':', $credentials['hostname'], 2);
+ if ( ! is_numeric($credentials['port']) )
+ unset($credentials['port']);
+ } else {
+ unset($credentials['port']);
+ }
+
+ if ( ( defined( 'FTP_SSH' ) && FTP_SSH ) || ( defined( 'FS_METHOD' ) && 'ssh2' == FS_METHOD ) ) {
+ $credentials['connection_type'] = 'ssh';
+ } elseif ( ( defined( 'FTP_SSL' ) && FTP_SSL ) && 'ftpext' == $type ) { //Only the FTP Extension understands SSL
+ $credentials['connection_type'] = 'ftps';
+ } elseif ( ! empty( $_POST['connection_type'] ) ) {
+ $credentials['connection_type'] = wp_unslash( $_POST['connection_type'] );
+ } elseif ( ! isset( $credentials['connection_type'] ) ) { //All else fails (And it's not defaulted to something else saved), Default to FTP
+ $credentials['connection_type'] = 'ftp';
+ }
+ if ( ! $error &&
+ (
+ ( !empty($credentials['password']) && !empty($credentials['username']) && !empty($credentials['hostname']) ) ||
+ ( 'ssh' == $credentials['connection_type'] && !empty($credentials['public_key']) && !empty($credentials['private_key']) )
+ ) ) {
+ $stored_credentials = $credentials;
+ if ( !empty($stored_credentials['port']) ) //save port as part of hostname to simplify above code.
+ $stored_credentials['hostname'] .= ':' . $stored_credentials['port'];
+
+ unset($stored_credentials['password'], $stored_credentials['port'], $stored_credentials['private_key'], $stored_credentials['public_key']);
+ if ( ! defined( 'WP_INSTALLING' ) ) {
+ update_option( 'ftp_credentials', $stored_credentials );
+ }
+ return $credentials;
+ }
+ $hostname = isset( $credentials['hostname'] ) ? $credentials['hostname'] : '';
+ $username = isset( $credentials['username'] ) ? $credentials['username'] : '';
+ $public_key = isset( $credentials['public_key'] ) ? $credentials['public_key'] : '';
+ $private_key = isset( $credentials['private_key'] ) ? $credentials['private_key'] : '';
+ $port = isset( $credentials['port'] ) ? $credentials['port'] : '';
+ $connection_type = isset( $credentials['connection_type'] ) ? $credentials['connection_type'] : '';
+
+ if ( $error ) {
+ $error_string = __('<strong>ERROR:</strong> There was an error connecting to the server, Please verify the settings are correct.');
+ if ( is_wp_error($error) )
+ $error_string = esc_html( $error->get_error_message() );
+ echo '<div id="message" class="error"><p>' . $error_string . '</p></div>';
+ }
+
+ $types = array();
+ if ( extension_loaded('ftp') || extension_loaded('sockets') || function_exists('fsockopen') )
+ $types[ 'ftp' ] = __('FTP');
+ if ( extension_loaded('ftp') ) //Only this supports FTPS
+ $types[ 'ftps' ] = __('FTPS (SSL)');
+ if ( extension_loaded('ssh2') && function_exists('stream_get_contents') )
+ $types[ 'ssh' ] = __('SSH2');
+
+ /**
+ * Filter the connection types to output to the filesystem credentials form.
+ *
+ * @since 2.9.0
+ *
+ * @param array $types Types of connections.
+ * @param array $credentials Credentials to connect with.
+ * @param string $type Chosen filesystem method.
+ * @param object $error Error object.
+ * @param string $context Full path to the directory that is tested
+ * for being writable.
+ */
+ $types = apply_filters( 'fs_ftp_connection_types', $types, $credentials, $type, $error, $context );
+
+?>
+<script type="text/javascript">
+<!--
+jQuery(function($){
+ jQuery("#ssh").click(function () {
+ jQuery("#ssh_keys").show();
+ });
+ jQuery("#ftp, #ftps").click(function () {
+ jQuery("#ssh_keys").hide();
+ });
+ jQuery('#request-filesystem-credentials-form input[value=""]:first').focus();
+});
+-->
+</script>
+<form action="<?php echo esc_url( $form_post ) ?>" method="post">
+<div id="request-filesystem-credentials-form" class="request-filesystem-credentials-form">
+<h3 id="request-filesystem-credentials-title"><?php _e( 'Connection Information' ) ?></h3>
+<p id="request-filesystem-credentials-desc"><?php
+ $label_user = __('Username');
+ $label_pass = __('Password');
+ _e('To perform the requested action, WordPress needs to access your web server.');
+ echo ' ';
+ if ( ( isset( $types['ftp'] ) || isset( $types['ftps'] ) ) ) {
+ if ( isset( $types['ssh'] ) ) {
+ _e('Please enter your FTP or SSH credentials to proceed.');
+ $label_user = __('FTP/SSH Username');
+ $label_pass = __('FTP/SSH Password');
+ } else {
+ _e('Please enter your FTP credentials to proceed.');
+ $label_user = __('FTP Username');
+ $label_pass = __('FTP Password');
+ }
+ echo ' ';
+ }
+ _e('If you do not remember your credentials, you should contact your web host.');
+?></p>
+<label for="hostname">
+ <span class="field-title"><?php _e( 'Hostname' ) ?></span>
+ <input name="hostname" type="text" id="hostname" aria-describedby="request-filesystem-credentials-desc" class="code" placeholder="<?php esc_attr_e( 'example: www.wordpress.org' ) ?>" value="<?php echo esc_attr($hostname); if ( !empty($port) ) echo ":$port"; ?>"<?php disabled( defined('FTP_HOST') ); ?> />
+</label>
+<div class="ftp-username">
+ <label for="username">
+ <span class="field-title"><?php echo $label_user; ?></span>
+ <input name="username" type="text" id="username" value="<?php echo esc_attr($username) ?>"<?php disabled( defined('FTP_USER') ); ?> />
+ </label>
+</div>
+<div class="ftp-password">
+ <label for="password">
+ <span class="field-title"><?php echo $label_pass; ?></span>
+ <input name="password" type="password" id="password" value="<?php if ( defined('FTP_PASS') ) echo '*****'; ?>"<?php disabled( defined('FTP_PASS') ); ?> />
+ <em><?php if ( ! defined('FTP_PASS') ) _e( 'This password will not be stored on the server.' ); ?></em>
+ </label>
+</div>
+<?php if ( isset($types['ssh']) ) : ?>
+<h4><?php _e('Authentication Keys') ?></h4>
+<label for="public_key">
+ <span class="field-title"><?php _e('Public Key:') ?></span>
+ <input name="public_key" type="text" id="public_key" aria-describedby="auth-keys-desc" value="<?php echo esc_attr($public_key) ?>"<?php disabled( defined('FTP_PUBKEY') ); ?> />
+</label>
+<label for="private_key">
+ <span class="field-title"><?php _e('Private Key:') ?></span>
+ <input name="private_key" type="text" id="private_key" value="<?php echo esc_attr($private_key) ?>"<?php disabled( defined('FTP_PRIKEY') ); ?> />
+</label>
+<span id="auth-keys-desc"><?php _e('Enter the location on the server where the public and private keys are located. If a passphrase is needed, enter that in the password field above.') ?></span>
+<?php endif; ?>
+<h4><?php _e('Connection Type') ?></h4>
+<fieldset><legend class="screen-reader-text"><span><?php _e('Connection Type') ?></span></legend>
+<?php
+ $disabled = disabled( (defined('FTP_SSL') && FTP_SSL) || (defined('FTP_SSH') && FTP_SSH), true, false );
+ foreach ( $types as $name => $text ) : ?>
+ <label for="<?php echo esc_attr($name) ?>">
+ <input type="radio" name="connection_type" id="<?php echo esc_attr($name) ?>" value="<?php echo esc_attr($name) ?>"<?php checked($name, $connection_type); echo $disabled; ?> />
+ <?php echo $text ?>
+ </label>
+ <?php endforeach; ?>
+</fieldset>
+<?php
+foreach ( (array) $extra_fields as $field ) {
+ if ( isset( $_POST[ $field ] ) )
+ echo '<input type="hidden" name="' . esc_attr( $field ) . '" value="' . esc_attr( wp_unslash( $_POST[ $field ] ) ) . '" />';
+}
+?>
+ <p class="request-filesystem-credentials-action-buttons">
+ <button class="button cancel-button" data-js-action="close" type="button"><?php _e( 'Cancel' ); ?></button>
+ <?php submit_button( __( 'Proceed' ), 'button', 'upgrade', false ); ?>
+ </p>
+</div>
+</form>
+<?php
+ return false;
+}
+
+/**
+ * Print the filesystem credentials modal when needed.
+ *
+ * @since 4.2.0
+ */
+function wp_print_request_filesystem_credentials_modal() {
+ $filesystem_method = get_filesystem_method();
+ ob_start();
+ $filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() );
+ ob_end_clean();
+ $request_filesystem_credentials = ( $filesystem_method != 'direct' && ! $filesystem_credentials_are_stored );
+ if ( ! $request_filesystem_credentials ) {
+ return;
+ }
+ ?>
+ <div id="request-filesystem-credentials-dialog" class="notification-dialog-wrap request-filesystem-credentials-dialog">
+ <div class="notification-dialog-background"></div>
+ <div class="notification-dialog" role="dialog" aria-labelledby="request-filesystem-credentials-title" tabindex="0">
+ <div class="request-filesystem-credentials-dialog-content">
+ <?php request_filesystem_credentials( site_url() ); ?>
+ <div>
+ </div>
+ </div>
+ <?php
+}