2007-05-28 00:04:33 +00:00
<? php
2008-10-02 01:03:26 +00:00
/**
2015-10-16 16:56:26 +00:00
* Filesystem API: Top-level functionality
*
2012-07-26 15:08:30 +00:00
* Functions for reading, writing, modifying, and deleting files on the file system.
2012-10-03 18:49:37 +00:00
* Includes functionality for theme-specific files as well as operations for uploading,
2012-07-26 15:08:30 +00:00
* archiving, and rendering output when necessary.
2008-10-02 01:03:26 +00:00
*
* @package WordPress
2015-10-16 16:56:26 +00:00
* @subpackage Filesystem
* @since 2.3.0
2008-10-02 01:03:26 +00:00
*/
2007-05-28 00:04:33 +00:00
2008-10-02 01:03:26 +00:00
/** The descriptions for theme files. */
2010-12-04 04:22:48 +00:00
$wp_file_descriptions = array (
2008-08-23 09:49:52 +00:00
'index.php' => __ ( 'Main Index Template' ),
'style.css' => __ ( 'Stylesheet' ),
2010-04-04 11:14:29 +00:00
'editor-style.css' => __ ( 'Visual Editor Stylesheet' ),
2010-12-04 04:22:48 +00:00
'editor-style-rtl.css' => __ ( 'Visual Editor RTL Stylesheet' ),
2008-10-02 01:03:26 +00:00
'rtl.css' => __ ( 'RTL Stylesheet' ),
'comments.php' => __ ( 'Comments' ),
'comments-popup.php' => __ ( 'Popup Comments' ),
2015-09-18 16:03:24 +00:00
'footer.php' => __ ( 'Theme Footer' ),
'header.php' => __ ( 'Theme Header' ),
2008-08-23 09:49:52 +00:00
'sidebar.php' => __ ( 'Sidebar' ),
'archive.php' => __ ( 'Archives' ),
2010-04-04 11:23:09 +00:00
'author.php' => __ ( 'Author Template' ),
'tag.php' => __ ( 'Tag Template' ),
2008-08-23 09:49:52 +00:00
'category.php' => __ ( 'Category Template' ),
'page.php' => __ ( 'Page Template' ),
'search.php' => __ ( 'Search Results' ),
'searchform.php' => __ ( 'Search Form' ),
'single.php' => __ ( 'Single Post' ),
'404.php' => __ ( '404 Template' ),
'link.php' => __ ( 'Links Template' ),
'functions.php' => __ ( 'Theme Functions' ),
'attachment.php' => __ ( 'Attachment Template' ),
'image.php' => __ ( 'Image Attachment Template' ),
'video.php' => __ ( 'Video Attachment Template' ),
'audio.php' => __ ( 'Audio Attachment Template' ),
'application.php' => __ ( 'Application Attachment Template' ),
'.htaccess' => __ ( '.htaccess (for rewrite rules )' ),
2007-05-28 00:04:33 +00:00
// Deprecated files
2010-12-04 04:22:48 +00:00
'wp-layout.css' => __ ( 'Stylesheet' ),
'wp-comments.php' => __ ( 'Comments Template' ),
'wp-comments-popup.php' => __ ( 'Popup Comments Template' ),
);
2008-10-02 01:03:26 +00:00
/**
2010-10-27 22:24:06 +00:00
* Get the description for standard WordPress theme files and other various standard
* WordPress files
2008-10-02 01:03:26 +00:00
*
2010-10-27 22:24:06 +00:00
* @since 1.5.0
2008-10-02 01:03:26 +00:00
*
2015-05-28 21:41:30 +00:00
* @global array $wp_file_descriptions
2010-10-27 22:24:06 +00:00
* @param string $file Filesystem path or filename
2015-09-28 03:11:24 +00:00
* @return string Description of file from $wp_file_descriptions or basename of $file if description doesn't exist.
* Appends 'Page Template' to basename of $file if the file is a page template
2008-10-02 01:03:26 +00:00
*/
2007-05-28 00:04:33 +00:00
function get_file_description ( $file ) {
2015-09-28 03:11:24 +00:00
global $wp_file_descriptions , $allowed_files ;
2007-05-28 00:04:33 +00:00
2015-09-28 03:11:24 +00:00
$relative_pathinfo = pathinfo ( $file );
$file_path = $allowed_files [ $file ];
if ( isset ( $wp_file_descriptions [ basename ( $file ) ] ) && '.' === $relative_pathinfo [ 'dirname' ] ) {
return $wp_file_descriptions [ basename ( $file ) ];
} elseif ( file_exists ( $file_path ) && is_file ( $file_path ) ) {
$template_data = implode ( '' , file ( $file_path ) );
if ( preg_match ( '|Template Name:(.*)$|mi' , $template_data , $name ) ) {
return sprintf ( __ ( '%s Page Template' ), _cleanup_header_comment ( $name [ 1 ] ) );
}
2007-05-28 00:04:33 +00:00
}
2012-03-29 03:00:38 +00:00
return trim ( basename ( $file ) );
2007-05-28 00:04:33 +00:00
}
2008-10-02 01:03:26 +00:00
/**
2010-10-27 22:24:06 +00:00
* Get the absolute filesystem path to the root of the WordPress installation
2008-10-02 01:03:26 +00:00
*
2010-10-27 22:24:06 +00:00
* @since 1.5.0
2008-10-02 01:03:26 +00:00
*
2010-10-27 22:24:06 +00:00
* @return string Full filesystem path to the root of the WordPress installation
2008-10-02 01:03:26 +00:00
*/
2007-05-28 00:04:33 +00:00
function get_home_path () {
2014-06-29 10:29:14 +00:00
$home = set_url_scheme ( get_option ( 'home' ), 'http' );
$siteurl = set_url_scheme ( get_option ( 'siteurl' ), 'http' );
2012-07-06 13:54:15 +00:00
if ( ! empty ( $home ) && 0 !== strcasecmp ( $home , $siteurl ) ) {
$wp_path_rel_to_home = str_ireplace ( $home , '' , $siteurl ); /* $siteurl - $home */
2012-11-21 22:39:59 +00:00
$pos = strripos ( str_replace ( '\\' , '/' , $_SERVER [ 'SCRIPT_FILENAME' ] ), trailingslashit ( $wp_path_rel_to_home ) );
2012-07-06 13:54:15 +00:00
$home_path = substr ( $_SERVER [ 'SCRIPT_FILENAME' ], 0 , $pos );
2009-05-05 02:45:40 +00:00
$home_path = trailingslashit ( $home_path );
2007-05-28 00:04:33 +00:00
} else {
$home_path = ABSPATH ;
}
2013-03-12 11:04:14 +00:00
return str_replace ( '\\' , '/' , $home_path );
2007-05-28 00:04:33 +00:00
}
2008-10-02 01:03:26 +00:00
/**
2009-11-05 23:03:48 +00:00
* Returns a listing of all files in the specified folder and all subdirectories up to 100 levels deep.
* The depth of the recursiveness can be controlled by the $levels param.
2008-10-02 01:03:26 +00:00
*
2009-11-05 23:03:48 +00:00
* @since 2.6.0
2008-10-02 01:03:26 +00:00
*
2014-12-06 21:24:45 +00:00
* @param string $folder Optional. Full path to folder. Default empty.
* @param int $levels Optional. Levels of folders to follow, Default 100 (PHP Loop limit).
2009-11-05 23:03:48 +00:00
* @return bool|array False on failure, Else array of files
2008-10-02 01:03:26 +00:00
*/
2008-06-16 18:35:48 +00:00
function list_files ( $folder = '' , $levels = 100 ) {
2010-01-18 20:34:48 +00:00
if ( empty ( $folder ) )
2008-06-16 18:35:48 +00:00
return false ;
2010-01-18 20:34:48 +00:00
if ( ! $levels )
2008-06-16 18:35:48 +00:00
return false ;
$files = array ();
if ( $dir = @ opendir ( $folder ) ) {
while (( $file = readdir ( $dir ) ) !== false ) {
if ( in_array ( $file , array ( '.' , '..' ) ) )
continue ;
if ( is_dir ( $folder . '/' . $file ) ) {
$files2 = list_files ( $folder . '/' . $file , $levels - 1 );
2010-01-18 20:34:48 +00:00
if ( $files2 )
2008-06-16 18:35:48 +00:00
$files = array_merge ( $files , $files2 );
else
$files [] = $folder . '/' . $file . '/' ;
} else {
$files [] = $folder . '/' . $file ;
}
}
}
@ closedir ( $dir );
return $files ;
}
2007-05-28 00:04:33 +00:00
2008-10-02 01:03:26 +00:00
/**
2009-11-05 23:03:48 +00:00
* Returns a filename of a Temporary unique file.
* Please note that the calling function must unlink() this itself.
2008-10-02 01:03:26 +00:00
*
2009-11-05 23:03:48 +00:00
* The filename is based off the passed parameter or defaults to the current unix timestamp,
2011-12-14 17:36:38 +00:00
* while the directory can either be passed as well, or by leaving it blank, default to a writable temporary directory.
2008-10-02 01:03:26 +00:00
*
2009-11-05 23:03:48 +00:00
* @since 2.6.0
*
2014-12-06 21:24:45 +00:00
* @param string $filename Optional. Filename to base the Unique file off. Default empty.
* @param string $dir Optional. Directory to store the file in. Default empty.
2009-11-05 23:03:48 +00:00
* @return string a writable filename
2008-10-02 01:03:26 +00:00
*/
2015-03-31 02:11:26 +00:00
function wp_tempnam ( $filename = '' , $dir = '' ) {
if ( empty ( $dir ) ) {
2008-04-25 21:34:54 +00:00
$dir = get_temp_dir ();
2015-03-31 02:11:26 +00:00
}
2015-04-29 03:17:31 +00:00
if ( empty ( $filename ) || '.' == $filename || '/' == $filename ) {
2008-04-25 21:34:54 +00:00
$filename = time ();
2015-03-31 02:11:26 +00:00
}
// Use the basename of the given file without the extension as the name for the temporary directory
$temp_filename = basename ( $filename );
$temp_filename = preg_replace ( '|\.[^.]*$|' , '' , $temp_filename );
2008-04-25 21:34:54 +00:00
2015-09-16 12:46:28 +00:00
// If the folder is falsey, use its parent directory name instead.
2015-03-31 02:11:26 +00:00
if ( ! $temp_filename ) {
return wp_tempnam ( dirname ( $filename ), $dir );
}
$temp_filename .= '.tmp' ;
$temp_filename = $dir . wp_unique_filename ( $dir , $temp_filename );
touch ( $temp_filename );
return $temp_filename ;
2008-04-25 21:34:54 +00:00
}
2008-10-02 01:03:26 +00:00
/**
2010-10-27 22:24:06 +00:00
* Make sure that the file that was requested to edit, is allowed to be edited
*
* Function will die if if you are not allowed to edit the file
2008-10-02 01:03:26 +00:00
*
2010-10-27 22:24:06 +00:00
* @since 1.5.0
2008-10-02 01:03:26 +00:00
*
2010-10-27 22:24:06 +00:00
* @param string $file file the users is attempting to edit
* @param array $allowed_files Array of allowed files to edit, $file must match an entry exactly
2014-11-03 07:09:23 +00:00
* @return string|null
2008-10-02 01:03:26 +00:00
*/
2007-05-28 00:04:33 +00:00
function validate_file_to_edit ( $file , $allowed_files = '' ) {
$code = validate_file ( $file , $allowed_files );
if ( ! $code )
return $file ;
switch ( $code ) {
case 1 :
2014-02-21 14:46:14 +00:00
wp_die ( __ ( 'Sorry, that file cannot be edited.' ) );
2007-05-28 00:04:33 +00:00
2014-07-17 09:14:16 +00:00
// case 2 :
// wp_die( __('Sorry, can’t call files with their real path.' ));
2007-05-28 00:04:33 +00:00
case 3 :
2014-02-21 14:46:14 +00:00
wp_die ( __ ( 'Sorry, that file cannot be edited.' ) );
2007-05-28 00:04:33 +00:00
}
}
2008-10-02 01:03:26 +00:00
/**
2010-10-27 22:24:06 +00:00
* Handle PHP uploads in WordPress, sanitizing file names, checking extensions for mime type,
* and moving the file to the appropriate directory within the uploads directory.
2008-10-02 01:03:26 +00:00
*
2014-07-17 18:58:44 +00:00
* @since 4.0.0
2008-10-02 01:03:26 +00:00
*
2014-07-17 18:58:44 +00:00
* @see wp_handle_upload_error
*
2015-01-16 19:03:23 +00:00
* @param array $file Reference to a single element of $_FILES. Call the function once for each uploaded file.
* @param array|false $overrides An associative array of names => values to override default variables. Default false.
* @param string $time Time formatted in 'yyyy/mm'.
* @param string $action Expected value for $_POST['action'].
2014-07-17 18:58:44 +00:00
* @return array On success, returns an associative array of file attributes. On failure, returns
* $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ).
*/
function _wp_handle_upload ( & $file , $overrides , $time , $action ) {
2007-05-28 00:04:33 +00:00
// The default error handler.
2010-02-22 16:54:51 +00:00
if ( ! function_exists ( 'wp_handle_upload_error' ) ) {
2007-05-28 00:04:33 +00:00
function wp_handle_upload_error ( & $file , $message ) {
2014-07-17 18:58:44 +00:00
return array ( 'error' => $message );
2007-05-28 00:04:33 +00:00
}
}
2014-03-24 02:45:15 +00:00
/**
2014-11-30 11:28:24 +00:00
* Filter the data for a file before it is uploaded to WordPress.
2014-03-24 02:45:15 +00:00
*
2014-11-30 11:28:24 +00:00
* The dynamic portion of the hook name, `$action`, refers to the post action.
*
* @since 2.9.0 as 'wp_handle_upload_prefilter'.
* @since 4.0.0 Converted to a dynamic hook with `$action`.
2014-03-24 02:45:15 +00:00
*
* @param array $file An array of data for a single file.
*/
2014-07-17 18:58:44 +00:00
$file = apply_filters ( " { $action } _prefilter" , $file );
2009-11-05 14:24:20 +00:00
2007-05-28 00:04:33 +00:00
// You may define your own function and pass the name in $overrides['upload_error_handler']
$upload_error_handler = 'wp_handle_upload_error' ;
2014-05-16 16:10:38 +00:00
if ( isset ( $overrides [ 'upload_error_handler' ] ) ) {
$upload_error_handler = $overrides [ 'upload_error_handler' ];
}
2007-05-28 00:04:33 +00:00
2011-12-13 23:45:31 +00:00
// You may have had one or more 'wp_handle_upload_prefilter' functions error out the file. Handle that gracefully.
2014-07-17 18:58:44 +00:00
if ( isset ( $file [ 'error' ] ) && ! is_numeric ( $file [ 'error' ] ) && $file [ 'error' ] ) {
2009-11-05 14:24:20 +00:00
return $upload_error_handler ( $file , $file [ 'error' ] );
2014-07-17 18:58:44 +00:00
}
2009-11-05 14:24:20 +00:00
2014-05-16 16:10:38 +00:00
// Install user overrides. Did we mention that this voids your warranty?
2008-11-14 23:01:16 +00:00
// You may define your own function and pass the name in $overrides['unique_filename_callback']
$unique_filename_callback = null ;
2014-05-16 16:10:38 +00:00
if ( isset ( $overrides [ 'unique_filename_callback' ] ) ) {
$unique_filename_callback = $overrides [ 'unique_filename_callback' ];
}
2008-11-14 23:01:16 +00:00
2014-07-17 09:14:16 +00:00
/*
* This may not have orignially been intended to be overrideable,
* but historically has been.
*/
2014-05-16 16:10:38 +00:00
if ( isset ( $overrides [ 'upload_error_strings' ] ) ) {
$upload_error_strings = $overrides [ 'upload_error_strings' ];
2014-07-17 18:58:44 +00:00
} else {
// Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].
$upload_error_strings = array (
false ,
__ ( 'The uploaded file exceeds the upload_max_filesize directive in php.ini.' ),
__ ( 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.' ),
__ ( 'The uploaded file was only partially uploaded.' ),
__ ( 'No file was uploaded.' ),
'' ,
__ ( 'Missing a temporary folder.' ),
__ ( 'Failed to write file to disk.' ),
__ ( 'File upload stopped by extension.' )
);
2014-05-16 16:10:38 +00:00
}
2011-07-21 17:46:01 +00:00
// All tests are on by default. Most can be turned off by $overrides[{test_name}] = false;
2014-05-16 16:10:38 +00:00
$test_form = isset ( $overrides [ 'test_form' ] ) ? $overrides [ 'test_form' ] : true ;
$test_size = isset ( $overrides [ 'test_size' ] ) ? $overrides [ 'test_size' ] : true ;
2007-05-28 00:04:33 +00:00
2014-07-17 09:14:16 +00:00
// If you override this, you must provide $ext and $type!!
2014-05-16 16:10:38 +00:00
$test_type = isset ( $overrides [ 'test_type' ] ) ? $overrides [ 'test_type' ] : true ;
$mimes = isset ( $overrides [ 'mimes' ] ) ? $overrides [ 'mimes' ] : false ;
2007-05-28 00:04:33 +00:00
// A correct form post will pass this test.
2014-07-17 18:58:44 +00:00
if ( $test_form && ( ! isset ( $_POST [ 'action' ] ) || ( $_POST [ 'action' ] != $action ) ) ) {
2014-05-16 16:10:38 +00:00
return call_user_func ( $upload_error_handler , $file , __ ( 'Invalid form submission.' ) );
}
2007-05-28 00:04:33 +00:00
// A successful upload will pass this test. It makes no sense to override this one.
2014-02-27 21:16:15 +00:00
if ( isset ( $file [ 'error' ] ) && $file [ 'error' ] > 0 ) {
return call_user_func ( $upload_error_handler , $file , $upload_error_strings [ $file [ 'error' ] ] );
}
2007-05-28 00:04:33 +00:00
2014-07-17 18:58:44 +00:00
$test_file_size = 'wp_handle_upload' === $action ? $file [ 'size' ] : filesize ( $file [ 'tmp_name' ] );
2007-05-28 00:04:33 +00:00
// A non-empty file will pass this test.
2014-07-17 18:58:44 +00:00
if ( $test_size && ! ( $test_file_size > 0 ) ) {
if ( is_multisite () ) {
2010-02-22 16:54:51 +00:00
$error_msg = __ ( 'File is empty. Please upload something more substantial.' );
2014-07-17 18:58:44 +00:00
} else {
2010-02-22 16:54:51 +00:00
$error_msg = __ ( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.' );
2014-07-17 18:58:44 +00:00
}
return call_user_func ( $upload_error_handler , $file , $error_msg );
2010-02-22 16:54:51 +00:00
}
2007-05-28 00:04:33 +00:00
// A properly uploaded file will pass this test. There should be no reason to override this one.
2014-07-17 18:58:44 +00:00
$test_uploaded_file = 'wp_handle_upload' === $action ? @ is_uploaded_file ( $file [ 'tmp_name' ] ) : @ is_file ( $file [ 'tmp_name' ] );
2014-10-28 21:17:22 +00:00
if ( ! $test_uploaded_file ) {
2014-07-17 18:58:44 +00:00
return call_user_func ( $upload_error_handler , $file , __ ( 'Specified file failed upload test.' ) );
}
2007-05-28 00:04:33 +00:00
// A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
if ( $test_type ) {
2010-05-15 04:47:03 +00:00
$wp_filetype = wp_check_filetype_and_ext ( $file [ 'tmp_name' ], $file [ 'name' ], $mimes );
2014-05-15 04:31:14 +00:00
$ext = empty ( $wp_filetype [ 'ext' ] ) ? '' : $wp_filetype [ 'ext' ];
$type = empty ( $wp_filetype [ 'type' ] ) ? '' : $wp_filetype [ 'type' ];
$proper_filename = empty ( $wp_filetype [ 'proper_filename' ] ) ? '' : $wp_filetype [ 'proper_filename' ];
2007-05-28 00:04:33 +00:00
2010-05-15 04:47:03 +00:00
// Check to see if wp_check_filetype_and_ext() determined the filename was incorrect
2014-05-15 04:31:14 +00:00
if ( $proper_filename ) {
2010-05-15 04:47:03 +00:00
$file [ 'name' ] = $proper_filename ;
2014-05-15 04:31:14 +00:00
}
if ( ( ! $type || ! $ext ) && ! current_user_can ( 'unfiltered_upload' ) ) {
return call_user_func ( $upload_error_handler , $file , __ ( 'Sorry, this file type is not permitted for security reasons.' ) );
}
if ( ! $type ) {
2008-03-06 19:48:54 +00:00
$type = $file [ 'type' ];
2014-05-15 04:31:14 +00:00
}
2009-05-07 06:50:54 +00:00
} else {
$type = '' ;
2007-05-28 00:04:33 +00:00
}
2014-07-17 09:14:16 +00:00
/*
* A writable uploads dir will pass this test. Again, there's no point
* overriding this one.
*/
2014-07-17 18:58:44 +00:00
if ( ! ( ( $uploads = wp_upload_dir ( $time ) ) && false === $uploads [ 'error' ] ) ) {
return call_user_func ( $upload_error_handler , $file , $uploads [ 'error' ] );
}
2007-05-28 00:04:33 +00:00
2007-12-18 03:32:43 +00:00
$filename = wp_unique_filename ( $uploads [ 'path' ], $file [ 'name' ], $unique_filename_callback );
2007-05-28 00:04:33 +00:00
2014-07-17 09:14:16 +00:00
// Move the file to the uploads dir.
2011-07-29 08:59:35 +00:00
$new_file = $uploads [ 'path' ] . "/ $filename " ;
2014-07-17 18:58:44 +00:00
if ( 'wp_handle_upload' === $action ) {
$move_new_file = @ move_uploaded_file ( $file [ 'tmp_name' ], $new_file );
} else {
2015-11-09 00:44:27 +00:00
// use copy and unlink because rename breaks streams.
$move_new_file = @ copy ( $file [ 'tmp_name' ], $new_file );
unlink ( $file [ 'tmp_name' ] );
2014-07-17 18:58:44 +00:00
}
if ( false === $move_new_file ) {
if ( 0 === strpos ( $uploads [ 'basedir' ], ABSPATH ) ) {
2013-06-21 02:29:26 +00:00
$error_path = str_replace ( ABSPATH , '' , $uploads [ 'basedir' ] ) . $uploads [ 'subdir' ];
2014-07-17 18:58:44 +00:00
} else {
2013-06-21 02:29:26 +00:00
$error_path = basename ( $uploads [ 'basedir' ] ) . $uploads [ 'subdir' ];
2014-07-17 18:58:44 +00:00
}
2013-06-21 02:29:26 +00:00
return $upload_error_handler ( $file , sprintf ( __ ( 'The uploaded file could not be moved to %s.' ), $error_path ) );
}
2011-10-24 19:13:23 +00:00
2014-07-17 09:14:16 +00:00
// Set correct file permissions.
2007-05-28 00:04:33 +00:00
$stat = stat ( dirname ( $new_file ));
$perms = $stat [ 'mode' ] & 0000666 ;
@ chmod ( $new_file , $perms );
2014-07-17 09:14:16 +00:00
// Compute the URL.
2007-05-28 00:04:33 +00:00
$url = $uploads [ 'url' ] . "/ $filename " ;
2014-07-17 18:58:44 +00:00
if ( is_multisite () ) {
2010-02-04 18:57:32 +00:00
delete_transient ( 'dirsize_cache' );
2014-07-17 18:58:44 +00:00
}
2010-02-04 18:57:32 +00:00
2014-03-24 02:45:15 +00:00
/**
* Filter the data array for the uploaded file.
*
* @since 2.1.0
*
* @param array $upload {
* Array of upload data.
*
* @type string $file Filename of the newly-uploaded file.
* @type string $url URL of the uploaded file.
* @type string $type File type.
* }
2014-07-17 18:58:44 +00:00
* @param string $context The type of upload action. Values include 'upload' or 'sideload'.
2014-03-24 02:45:15 +00:00
*/
2014-07-17 18:58:44 +00:00
return apply_filters ( 'wp_handle_upload' , array (
'file' => $new_file ,
'url' => $url ,
'type' => $type
), 'wp_handle_sideload' === $action ? 'sideload' : 'upload' ); }
2008-10-02 01:03:26 +00:00
/**
2014-07-17 18:58:44 +00:00
* Wrapper for _wp_handle_upload(), passes 'wp_handle_upload' action.
2008-10-02 01:03:26 +00:00
*
2014-07-17 18:58:44 +00:00
* @since 2.0.0
*
* @see _wp_handle_upload()
2008-10-02 01:03:26 +00:00
*
2014-07-17 18:58:44 +00:00
* @param array $file Reference to a single element of $_FILES. Call the function once for
* each uploaded file.
* @param array|bool $overrides Optional. An associative array of names=>values to override default
* variables. Default false.
* @param string $time Optional. Time formatted in 'yyyy/mm'. Default null.
* @return array On success, returns an associative array of file attributes. On failure, returns
* $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ).
2008-10-02 01:03:26 +00:00
*/
2014-07-17 18:58:44 +00:00
function wp_handle_upload ( & $file , $overrides = false , $time = null ) {
/*
* $_POST['action'] must be set and its value must equal $overrides['action']
* or this:
*/
$action = 'wp_handle_upload' ;
if ( isset ( $overrides [ 'action' ] ) ) {
$action = $overrides [ 'action' ];
2014-05-16 16:15:14 +00:00
}
2008-06-04 16:13:55 +00:00
2014-07-17 18:58:44 +00:00
return _wp_handle_upload ( $file , $overrides , $time , $action );
}
2008-11-15 18:10:35 +00:00
2014-07-17 18:58:44 +00:00
/**
* Wrapper for _wp_handle_upload(), passes 'wp_handle_sideload' action
*
* @since 2.6.0
*
* @see _wp_handle_upload()
*
* @param array $file An array similar to that of a PHP $_FILES POST array
* @param array|bool $overrides Optional. An associative array of names=>values to override default
* variables. Default false.
* @param string $time Optional. Time formatted in 'yyyy/mm'. Default null.
* @return array On success, returns an associative array of file attributes. On failure, returns
* $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ).
*/
function wp_handle_sideload ( & $file , $overrides = false , $time = null ) {
/*
* $_POST['action'] must be set and its value must equal $overrides['action']
* or this:
*/
2008-06-04 16:13:55 +00:00
$action = 'wp_handle_sideload' ;
2014-05-16 16:15:14 +00:00
if ( isset ( $overrides [ 'action' ] ) ) {
$action = $overrides [ 'action' ];
}
2014-07-17 18:58:44 +00:00
return _wp_handle_upload ( $file , $overrides , $time , $action );
2008-06-04 16:13:55 +00:00
}
2007-05-28 00:04:33 +00:00
2014-07-17 18:58:44 +00:00
2008-02-11 05:45:54 +00:00
/**
2009-11-05 23:03:48 +00:00
* Downloads a url to a local temporary file using the WordPress HTTP Class.
2011-12-14 17:36:38 +00:00
* Please note, That the calling function must unlink() the file.
2008-10-02 01:03:26 +00:00
*
2009-11-05 23:03:48 +00:00
* @since 2.5.0
2008-10-02 01:03:26 +00:00
*
* @param string $url the URL of the file to download
2010-12-07 12:45:24 +00:00
* @param int $timeout The timeout for the request to download the file default 300 seconds
2008-10-02 01:03:26 +00:00
* @return mixed WP_Error on failure, string Filename on success.
*/
2010-12-07 12:45:24 +00:00
function download_url ( $url , $timeout = 300 ) {
2008-02-11 05:45:54 +00:00
//WARNING: The file is not automatically deleted, The script must unlink() the file.
2008-10-15 16:35:35 +00:00
if ( ! $url )
2010-01-21 21:37:43 +00:00
return new WP_Error ( 'http_no_url' , __ ( 'Invalid URL Provided.' ));
2008-02-11 05:45:54 +00:00
2008-04-25 21:34:54 +00:00
$tmpfname = wp_tempnam ( $url );
2008-10-15 16:35:35 +00:00
if ( ! $tmpfname )
2010-01-21 21:37:43 +00:00
return new WP_Error ( 'http_no_file' , __ ( 'Could not create Temporary file.' ));
2008-02-11 05:45:54 +00:00
2013-07-31 06:52:13 +00:00
$response = wp_safe_remote_get ( $url , array ( 'timeout' => $timeout , 'stream' => true , 'filename' => $tmpfname ) );
2008-03-02 20:17:30 +00:00
2011-03-25 02:42:20 +00:00
if ( is_wp_error ( $response ) ) {
unlink ( $tmpfname );
2008-10-15 16:35:35 +00:00
return $response ;
}
2011-05-14 19:45:07 +00:00
if ( 200 != wp_remote_retrieve_response_code ( $response ) ){
2011-03-25 02:42:20 +00:00
unlink ( $tmpfname );
2011-05-14 19:45:07 +00:00
return new WP_Error ( 'http_404' , trim ( wp_remote_retrieve_response_message ( $response ) ) );
2008-03-27 07:36:30 +00:00
}
2008-10-14 16:37:08 +00:00
2013-09-21 06:54:09 +00:00
$content_md5 = wp_remote_retrieve_header ( $response , 'content-md5' );
if ( $content_md5 ) {
$md5_check = verify_file_md5 ( $tmpfname , $content_md5 );
if ( is_wp_error ( $md5_check ) ) {
unlink ( $tmpfname );
return $md5_check ;
}
}
2008-02-11 05:45:54 +00:00
return $tmpfname ;
}
2013-09-21 06:54:09 +00:00
/**
2014-04-04 00:03:14 +00:00
* Calculates and compares the MD5 of a file to its expected value.
2013-09-21 06:54:09 +00:00
*
* @since 3.7.0
*
* @param string $filename The filename to check the MD5 of.
* @param string $expected_md5 The expected MD5 of the file, either a base64 encoded raw md5, or a hex-encoded md5
* @return bool|object WP_Error on failure, true on success, false when the MD5 format is unknown/unexpected
*/
function verify_file_md5 ( $filename , $expected_md5 ) {
if ( 32 == strlen ( $expected_md5 ) )
$expected_raw_md5 = pack ( 'H*' , $expected_md5 );
elseif ( 24 == strlen ( $expected_md5 ) )
$expected_raw_md5 = base64_decode ( $expected_md5 );
else
return false ; // unknown format
$file_md5 = md5_file ( $filename , true );
if ( $file_md5 === $expected_raw_md5 )
return true ;
return new WP_Error ( 'md5_mismatch' , sprintf ( __ ( 'The checksum of the file (%1$s) does not match the expected checksum value (%2$s).' ), bin2hex ( $file_md5 ), bin2hex ( $expected_raw_md5 ) ) );
}
2008-10-02 01:03:26 +00:00
/**
2011-09-03 14:18:10 +00:00
* Unzips a specified ZIP file to a location on the Filesystem via the WordPress Filesystem Abstraction.
2010-05-02 23:24:36 +00:00
* Assumes that WP_Filesystem() has already been called and set up. Does not extract a root-level __MACOSX directory, if present.
2008-10-02 01:03:26 +00:00
*
2009-11-05 23:03:48 +00:00
* Attempts to increase the PHP Memory limit to 256M before uncompressing,
* However, The most memory required shouldn't be much larger than the Archive itself.
2008-10-02 01:03:26 +00:00
*
2009-11-05 23:03:48 +00:00
* @since 2.5.0
*
2015-05-28 21:41:30 +00:00
* @global WP_Filesystem_Base $wp_filesystem Subclass
*
2009-11-05 23:03:48 +00:00
* @param string $file Full path and filename of zip archive
* @param string $to Full path on the filesystem to extract archive to
* @return mixed WP_Error on failure, True on success
2008-10-02 01:03:26 +00:00
*/
2008-02-11 05:45:54 +00:00
function unzip_file ( $file , $to ) {
global $wp_filesystem ;
if ( ! $wp_filesystem || ! is_object ( $wp_filesystem ) )
return new WP_Error ( 'fs_unavailable' , __ ( 'Could not access filesystem.' ));
2008-03-02 20:17:30 +00:00
2010-02-07 04:52:35 +00:00
// Unzip can use a lot of memory, but not this much hopefully
2014-03-24 02:45:15 +00:00
/** This filter is documented in wp-admin/admin.php */
2011-04-28 16:25:36 +00:00
@ ini_set ( 'memory_limit' , apply_filters ( 'admin_memory_limit' , WP_MAX_MEMORY_LIMIT ) );
2008-11-11 19:11:48 +00:00
2010-01-22 11:02:09 +00:00
$needed_dirs = array ();
2008-09-09 03:24:05 +00:00
$to = trailingslashit ( $to );
2010-01-22 11:02:09 +00:00
// Determine any parent dir's needed (of the upgrade directory)
if ( ! $wp_filesystem -> is_dir ( $to ) ) { //Only do parents if no children exist
$path = preg_split ( '![/\\\]!' , untrailingslashit ( $to ));
for ( $i = count ( $path ); $i >= 0 ; $i -- ) {
2008-09-13 18:06:20 +00:00
if ( empty ( $path [ $i ]) )
continue ;
2008-02-11 05:45:54 +00:00
2010-01-22 11:02:09 +00:00
$dir = implode ( '/' , array_slice ( $path , 0 , $i + 1 ) );
2010-02-07 04:52:35 +00:00
if ( preg_match ( '!^[a-z]:$!i' , $dir ) ) // Skip it if it looks like a Windows Drive letter.
2010-01-22 11:02:09 +00:00
continue ;
if ( ! $wp_filesystem -> is_dir ( $dir ) )
$needed_dirs [] = $dir ;
else
break ; // A folder exists, therefor, we dont need the check the levels below this
2008-08-07 19:15:04 +00:00
}
2008-02-11 05:45:54 +00:00
}
2010-01-22 11:02:09 +00:00
2014-03-24 02:45:15 +00:00
/**
* Filter whether to use ZipArchive to unzip archives.
*
* @since 3.0.0
*
* @param bool $ziparchive Whether to use ZipArchive. Default true.
*/
2015-09-20 03:52:25 +00:00
if ( class_exists ( 'ZipArchive' , false ) && apply_filters ( 'unzip_file_use_ziparchive' , true ) ) {
2010-02-19 10:59:32 +00:00
$result = _unzip_file_ziparchive ( $file , $to , $needed_dirs );
if ( true === $result ) {
return $result ;
} elseif ( is_wp_error ( $result ) ) {
if ( 'incompatible_archive' != $result -> get_error_code () )
return $result ;
}
}
// Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file.
return _unzip_file_pclzip ( $file , $to , $needed_dirs );
2010-02-07 04:52:35 +00:00
}
2010-02-07 05:07:36 +00:00
/**
* This function should not be called directly, use unzip_file instead. Attempts to unzip an archive using the ZipArchive class.
* Assumes that WP_Filesystem() has already been called and set up.
*
2010-03-26 19:13:36 +00:00
* @since 3.0.0
2010-02-07 05:07:36 +00:00
* @see unzip_file
* @access private
*
2015-05-28 21:41:30 +00:00
* @global WP_Filesystem_Base $wp_filesystem Subclass
*
2010-02-07 05:07:36 +00:00
* @param string $file Full path and filename of zip archive
* @param string $to Full path on the filesystem to extract archive to
* @param array $needed_dirs A partial list of required folders needed to be created.
* @return mixed WP_Error on failure, True on success
*/
2010-02-07 21:28:05 +00:00
function _unzip_file_ziparchive ( $file , $to , $needed_dirs = array () ) {
2010-02-07 04:52:35 +00:00
global $wp_filesystem ;
$z = new ZipArchive ();
2010-02-07 21:28:05 +00:00
2013-10-14 21:55:09 +00:00
$zopen = $z -> open ( $file , ZIPARCHIVE :: CHECKCONS );
2010-05-29 13:16:35 +00:00
if ( true !== $zopen )
2013-10-14 21:55:09 +00:00
return new WP_Error ( 'incompatible_archive' , __ ( 'Incompatible Archive.' ), array ( 'ziparchive_error' => $zopen ) );
2010-02-07 04:52:35 +00:00
2013-10-14 20:15:09 +00:00
$uncompressed_size = 0 ;
2010-02-07 04:52:35 +00:00
for ( $i = 0 ; $i < $z -> numFiles ; $i ++ ) {
if ( ! $info = $z -> statIndex ( $i ) )
2013-10-11 16:06:11 +00:00
return new WP_Error ( 'stat_failed_ziparchive' , __ ( 'Could not retrieve file from archive.' ) );
2010-02-07 04:52:35 +00:00
2010-05-02 23:24:36 +00:00
if ( '__MACOSX/' === substr ( $info [ 'name' ], 0 , 9 ) ) // Skip the OS X-created __MACOSX directory
continue ;
2013-10-14 20:15:09 +00:00
$uncompressed_size += $info [ 'size' ];
2010-02-07 04:52:35 +00:00
if ( '/' == substr ( $info [ 'name' ], - 1 ) ) // directory
$needed_dirs [] = $to . untrailingslashit ( $info [ 'name' ]);
else
$needed_dirs [] = $to . untrailingslashit ( dirname ( $info [ 'name' ]));
}
2010-02-08 18:02:23 +00:00
2013-10-14 20:58:09 +00:00
/*
* disk_free_space() could return false. Assume that any falsey value is an error.
* A disk that has zero free bytes has bigger problems.
* Require we have enough space to unzip the file and copy its contents, with a 10% buffer.
*/
2013-10-24 22:59:29 +00:00
if ( defined ( 'DOING_CRON' ) && DOING_CRON ) {
$available_space = @ disk_free_space ( WP_CONTENT_DIR );
if ( $available_space && ( $uncompressed_size * 2.1 ) > $available_space )
return new WP_Error ( 'disk_full_unzip_file' , __ ( 'Could not copy files. You may have run out of disk space.' ), compact ( 'uncompressed_size' , 'available_space' ) );
}
2013-10-14 20:15:09 +00:00
2010-02-07 04:52:35 +00:00
$needed_dirs = array_unique ( $needed_dirs );
2010-05-23 05:56:31 +00:00
foreach ( $needed_dirs as $dir ) {
2010-05-26 02:42:15 +00:00
// Check the parent folders of the folders all exist within the creation array.
2010-05-23 05:56:31 +00:00
if ( untrailingslashit ( $to ) == $dir ) // Skip over the working directory, We know this exists (or will exist)
continue ;
2010-06-07 11:19:51 +00:00
if ( strpos ( $dir , $to ) === false ) // If the directory is not within the working directory, Skip it
continue ;
2010-05-23 05:56:31 +00:00
$parent_folder = dirname ( $dir );
while ( ! empty ( $parent_folder ) && untrailingslashit ( $to ) != $parent_folder && ! in_array ( $parent_folder , $needed_dirs ) ) {
$needed_dirs [] = $parent_folder ;
$parent_folder = dirname ( $parent_folder );
}
}
2010-02-07 04:52:35 +00:00
asort ( $needed_dirs );
2010-02-08 18:02:23 +00:00
2010-02-07 04:52:35 +00:00
// Create those directories if need be:
foreach ( $needed_dirs as $_dir ) {
2015-03-31 02:11:26 +00:00
// Only check to see if the Dir exists upon creation failure. Less I/O this way.
if ( ! $wp_filesystem -> mkdir ( $_dir , FS_CHMOD_DIR ) && ! $wp_filesystem -> is_dir ( $_dir ) ) {
2013-10-14 22:25:08 +00:00
return new WP_Error ( 'mkdir_failed_ziparchive' , __ ( 'Could not create directory.' ), substr ( $_dir , strlen ( $to ) ) );
2015-03-31 02:11:26 +00:00
}
2010-02-07 04:52:35 +00:00
}
unset ( $needed_dirs );
2010-02-08 18:02:23 +00:00
2010-02-07 04:52:35 +00:00
for ( $i = 0 ; $i < $z -> numFiles ; $i ++ ) {
if ( ! $info = $z -> statIndex ( $i ) )
2013-10-11 16:06:11 +00:00
return new WP_Error ( 'stat_failed_ziparchive' , __ ( 'Could not retrieve file from archive.' ) );
2010-02-07 04:52:35 +00:00
if ( '/' == substr ( $info [ 'name' ], - 1 ) ) // directory
continue ;
2010-05-02 23:24:36 +00:00
if ( '__MACOSX/' === substr ( $info [ 'name' ], 0 , 9 ) ) // Don't extract the OS X-created __MACOSX directory files
2010-05-03 20:26:11 +00:00
continue ;
2010-05-02 23:24:36 +00:00
2010-02-07 05:02:24 +00:00
$contents = $z -> getFromIndex ( $i );
if ( false === $contents )
2013-10-11 16:06:11 +00:00
return new WP_Error ( 'extract_failed_ziparchive' , __ ( 'Could not extract file from archive.' ), $info [ 'name' ] );
2010-02-07 05:02:24 +00:00
if ( ! $wp_filesystem -> put_contents ( $to . $info [ 'name' ], $contents , FS_CHMOD_FILE ) )
2013-10-14 22:25:08 +00:00
return new WP_Error ( 'copy_failed_ziparchive' , __ ( 'Could not copy file.' ), $info [ 'name' ] );
2010-02-07 04:52:35 +00:00
}
2010-02-19 10:59:32 +00:00
$z -> close ();
2010-02-07 04:52:35 +00:00
return true ;
}
2010-02-07 05:07:36 +00:00
/**
* This function should not be called directly, use unzip_file instead. Attempts to unzip an archive using the PclZip library.
* Assumes that WP_Filesystem() has already been called and set up.
*
2010-03-26 19:13:36 +00:00
* @since 3.0.0
2010-02-07 05:07:36 +00:00
* @see unzip_file
* @access private
*
2015-05-28 21:41:30 +00:00
* @global WP_Filesystem_Base $wp_filesystem Subclass
*
2010-02-07 05:07:36 +00:00
* @param string $file Full path and filename of zip archive
* @param string $to Full path on the filesystem to extract archive to
* @param array $needed_dirs A partial list of required folders needed to be created.
* @return mixed WP_Error on failure, True on success
*/
2010-02-07 04:52:35 +00:00
function _unzip_file_pclzip ( $file , $to , $needed_dirs = array ()) {
global $wp_filesystem ;
2013-09-11 08:09:08 +00:00
mbstring_binary_safe_encoding ();
2011-04-03 12:32:06 +00:00
2010-02-07 04:52:35 +00:00
require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
$archive = new PclZip ( $file );
2011-04-03 12:32:06 +00:00
$archive_files = $archive -> extract ( PCLZIP_OPT_EXTRACT_AS_STRING );
2013-09-11 08:09:08 +00:00
reset_mbstring_encoding ();
2011-04-03 12:32:06 +00:00
2010-02-07 04:52:35 +00:00
// Is the archive valid?
2011-04-23 14:30:44 +00:00
if ( ! is_array ( $archive_files ) )
2010-02-07 04:52:35 +00:00
return new WP_Error ( 'incompatible_archive' , __ ( 'Incompatible Archive.' ), $archive -> errorInfo ( true ));
if ( 0 == count ( $archive_files ) )
2013-10-11 16:06:11 +00:00
return new WP_Error ( 'empty_archive_pclzip' , __ ( 'Empty archive.' ) );
2010-02-07 04:52:35 +00:00
2013-10-14 20:15:09 +00:00
$uncompressed_size = 0 ;
2010-01-22 11:02:09 +00:00
// Determine any children directories needed (From within the archive)
2010-05-02 23:24:36 +00:00
foreach ( $archive_files as $file ) {
2010-05-03 20:26:11 +00:00
if ( '__MACOSX/' === substr ( $file [ 'filename' ], 0 , 9 ) ) // Skip the OS X-created __MACOSX directory
2010-05-02 23:24:36 +00:00
continue ;
2010-05-03 20:26:11 +00:00
2013-10-14 20:15:09 +00:00
$uncompressed_size += $file [ 'size' ];
2010-01-22 11:02:09 +00:00
$needed_dirs [] = $to . untrailingslashit ( $file [ 'folder' ] ? $file [ 'filename' ] : dirname ( $file [ 'filename' ]) );
2010-05-02 23:24:36 +00:00
}
2010-01-22 11:02:09 +00:00
2013-10-14 20:58:09 +00:00
/*
* disk_free_space() could return false. Assume that any falsey value is an error.
* A disk that has zero free bytes has bigger problems.
* Require we have enough space to unzip the file and copy its contents, with a 10% buffer.
*/
2013-10-24 22:59:29 +00:00
if ( defined ( 'DOING_CRON' ) && DOING_CRON ) {
$available_space = @ disk_free_space ( WP_CONTENT_DIR );
if ( $available_space && ( $uncompressed_size * 2.1 ) > $available_space )
return new WP_Error ( 'disk_full_unzip_file' , __ ( 'Could not copy files. You may have run out of disk space.' ), compact ( 'uncompressed_size' , 'available_space' ) );
}
2013-10-14 20:15:09 +00:00
2010-01-22 11:02:09 +00:00
$needed_dirs = array_unique ( $needed_dirs );
2010-05-23 05:56:31 +00:00
foreach ( $needed_dirs as $dir ) {
2010-05-26 02:42:15 +00:00
// Check the parent folders of the folders all exist within the creation array.
2010-05-23 05:56:31 +00:00
if ( untrailingslashit ( $to ) == $dir ) // Skip over the working directory, We know this exists (or will exist)
continue ;
2010-06-07 11:19:51 +00:00
if ( strpos ( $dir , $to ) === false ) // If the directory is not within the working directory, Skip it
continue ;
2010-05-23 05:56:31 +00:00
$parent_folder = dirname ( $dir );
while ( ! empty ( $parent_folder ) && untrailingslashit ( $to ) != $parent_folder && ! in_array ( $parent_folder , $needed_dirs ) ) {
$needed_dirs [] = $parent_folder ;
$parent_folder = dirname ( $parent_folder );
}
}
2010-01-22 11:02:09 +00:00
asort ( $needed_dirs );
// Create those directories if need be:
foreach ( $needed_dirs as $_dir ) {
2013-10-15 21:24:09 +00:00
// Only check to see if the dir exists upon creation failure. Less I/O this way.
if ( ! $wp_filesystem -> mkdir ( $_dir , FS_CHMOD_DIR ) && ! $wp_filesystem -> is_dir ( $_dir ) )
2013-10-14 22:25:08 +00:00
return new WP_Error ( 'mkdir_failed_pclzip' , __ ( 'Could not create directory.' ), substr ( $_dir , strlen ( $to ) ) );
2010-01-22 11:02:09 +00:00
}
2010-02-07 04:52:35 +00:00
unset ( $needed_dirs );
2010-01-22 11:02:09 +00:00
// Extract the files from the zip
foreach ( $archive_files as $file ) {
if ( $file [ 'folder' ] )
continue ;
2010-05-02 23:24:36 +00:00
if ( '__MACOSX/' === substr ( $file [ 'filename' ], 0 , 9 ) ) // Don't extract the OS X-created __MACOSX directory files
continue ;
2010-01-22 11:02:09 +00:00
if ( ! $wp_filesystem -> put_contents ( $to . $file [ 'filename' ], $file [ 'content' ], FS_CHMOD_FILE ) )
2013-10-14 22:25:08 +00:00
return new WP_Error ( 'copy_failed_pclzip' , __ ( 'Could not copy file.' ), $file [ 'filename' ] );
2010-01-22 11:02:09 +00:00
}
2008-03-01 21:20:23 +00:00
return true ;
2008-02-11 05:45:54 +00:00
}
2008-10-02 01:03:26 +00:00
/**
2009-11-05 23:03:48 +00:00
* Copies a directory from one location to another via the WordPress Filesystem Abstraction.
* Assumes that WP_Filesystem() has already been called and setup.
2008-10-02 01:03:26 +00:00
*
2009-11-05 23:03:48 +00:00
* @since 2.5.0
2008-10-02 01:03:26 +00:00
*
2015-05-28 21:41:30 +00:00
* @global WP_Filesystem_Base $wp_filesystem Subclass
*
2009-11-05 23:03:48 +00:00
* @param string $from source directory
* @param string $to destination directory
2011-03-31 13:28:36 +00:00
* @param array $skip_list a list of files/folders to skip copying
2009-11-05 23:03:48 +00:00
* @return mixed WP_Error on failure, True on success.
2008-10-02 01:03:26 +00:00
*/
2011-03-31 13:28:36 +00:00
function copy_dir ( $from , $to , $skip_list = array () ) {
2008-02-11 05:45:54 +00:00
global $wp_filesystem ;
$dirlist = $wp_filesystem -> dirlist ( $from );
$from = trailingslashit ( $from );
$to = trailingslashit ( $to );
foreach ( ( array ) $dirlist as $filename => $fileinfo ) {
2013-09-21 06:49:11 +00:00
if ( in_array ( $filename , $skip_list ) )
continue ;
2011-03-31 13:28:36 +00:00
2008-03-01 21:20:23 +00:00
if ( 'f' == $fileinfo [ 'type' ] ) {
2011-03-22 00:04:15 +00:00
if ( ! $wp_filesystem -> copy ( $from . $filename , $to . $filename , true , FS_CHMOD_FILE ) ) {
2008-11-03 17:16:41 +00:00
// If copy failed, chmod file to 0644 and try again.
2013-10-15 19:14:10 +00:00
$wp_filesystem -> chmod ( $to . $filename , FS_CHMOD_FILE );
2011-03-22 00:04:15 +00:00
if ( ! $wp_filesystem -> copy ( $from . $filename , $to . $filename , true , FS_CHMOD_FILE ) )
2013-10-11 16:06:11 +00:00
return new WP_Error ( 'copy_failed_copy_dir' , __ ( 'Could not copy file.' ), $to . $filename );
2008-11-03 17:16:41 +00:00
}
2008-03-01 21:20:23 +00:00
} elseif ( 'd' == $fileinfo [ 'type' ] ) {
2008-08-08 22:49:35 +00:00
if ( ! $wp_filesystem -> is_dir ( $to . $filename ) ) {
2008-12-04 21:58:46 +00:00
if ( ! $wp_filesystem -> mkdir ( $to . $filename , FS_CHMOD_DIR ) )
2013-10-11 16:06:11 +00:00
return new WP_Error ( 'mkdir_failed_copy_dir' , __ ( 'Could not create directory.' ), $to . $filename );
2008-08-08 22:49:35 +00:00
}
2013-09-21 06:49:11 +00:00
// generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list
$sub_skip_list = array ();
foreach ( $skip_list as $skip_item ) {
if ( 0 === strpos ( $skip_item , $filename . '/' ) )
$sub_skip_list [] = preg_replace ( '!^' . preg_quote ( $filename , '!' ) . '/!i' , '' , $skip_item );
}
$result = copy_dir ( $from . $filename , $to . $filename , $sub_skip_list );
2008-05-29 17:29:32 +00:00
if ( is_wp_error ( $result ) )
return $result ;
2008-02-11 05:45:54 +00:00
}
}
2009-11-05 23:03:48 +00:00
return true ;
2008-02-11 05:45:54 +00:00
}
2008-10-02 01:03:26 +00:00
/**
2009-11-05 23:03:48 +00:00
* Initialises and connects the WordPress Filesystem Abstraction classes.
* This function will include the chosen transport and attempt connecting.
2008-10-02 01:03:26 +00:00
*
2014-12-06 21:24:45 +00:00
* Plugins may add extra transports, And force WordPress to use them by returning
* the filename via the {@see 'filesystem_method_file'} filter.
2008-10-02 01:03:26 +00:00
*
2009-11-05 23:03:48 +00:00
* @since 2.5.0
*
2015-05-28 21:41:30 +00:00
* @global WP_Filesystem_Base $wp_filesystem Subclass
*
2015-05-04 01:04:25 +00:00
* @param array|false $args Optional. Connection args, These are passed directly to
* the `WP_Filesystem_*()` classes. Default false.
* @param string|false $context Optional. Context for get_filesystem_method(). Default false.
* @param bool $allow_relaxed_file_ownership Optional. Whether to allow Group/World writable. Default false.
2015-06-27 01:03:25 +00:00
* @return null|bool false on failure, true on success.
2008-10-02 01:03:26 +00:00
*/
2014-11-19 05:40:23 +00:00
function WP_Filesystem ( $args = false , $context = false , $allow_relaxed_file_ownership = false ) {
2008-02-11 05:45:54 +00:00
global $wp_filesystem ;
2008-05-29 17:29:32 +00:00
require_once ( ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php' );
2014-11-19 05:40:23 +00:00
$method = get_filesystem_method ( $args , $context , $allow_relaxed_file_ownership );
2008-05-05 17:06:29 +00:00
2008-02-11 05:45:54 +00:00
if ( ! $method )
return false ;
2015-09-20 03:52:25 +00:00
if ( ! class_exists ( "WP_Filesystem_ $method " , false ) ) {
2014-03-24 02:45:15 +00:00
/**
* Filter the path for a specific filesystem method class file.
*
* @since 2.6.0
*
* @see get_filesystem_method()
*
* @param string $path Path to the specific filesystem method class file.
* @param string $method The filesystem method to use.
*/
$abstraction_file = apply_filters ( 'filesystem_method_file' , ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php' , $method );
2010-01-18 20:34:48 +00:00
if ( ! file_exists ( $abstraction_file ) )
2009-05-30 17:14:07 +00:00
return ;
2009-09-14 14:03:32 +00:00
2009-05-30 17:14:07 +00:00
require_once ( $abstraction_file );
}
2008-02-11 05:45:54 +00:00
$method = "WP_Filesystem_ $method " ;
$wp_filesystem = new $method ( $args );
2009-08-15 12:01:04 +00:00
//Define the timeouts for the connections. Only available after the construct is called to allow for per-transport overriding of the default.
if ( ! defined ( 'FS_CONNECT_TIMEOUT' ) )
define ( 'FS_CONNECT_TIMEOUT' , 30 );
if ( ! defined ( 'FS_TIMEOUT' ) )
define ( 'FS_TIMEOUT' , 30 );
2009-04-19 19:36:28 +00:00
if ( is_wp_error ( $wp_filesystem -> errors ) && $wp_filesystem -> errors -> get_error_code () )
2008-02-11 05:45:54 +00:00
return false ;
if ( ! $wp_filesystem -> connect () )
2011-09-03 14:18:10 +00:00
return false ; //There was an error connecting to the server.
2008-02-11 05:45:54 +00:00
2008-12-04 21:58:46 +00:00
// Set the permission constants if not already set.
if ( ! defined ( 'FS_CHMOD_DIR' ) )
2013-10-09 16:47:09 +00:00
define ( 'FS_CHMOD_DIR' , ( fileperms ( ABSPATH ) & 0777 | 0755 ) );
2008-12-04 21:58:46 +00:00
if ( ! defined ( 'FS_CHMOD_FILE' ) )
2013-10-09 16:47:09 +00:00
define ( 'FS_CHMOD_FILE' , ( fileperms ( ABSPATH . 'index.php' ) & 0777 | 0644 ) );
2008-12-04 21:58:46 +00:00
2008-02-11 05:45:54 +00:00
return true ;
}
2008-10-02 01:03:26 +00:00
/**
2015-03-25 16:32:28 +00:00
* Determines which method to use for reading, writing, modifying, or deleting
* files on the filesystem.
2014-11-24 05:19:23 +00:00
*
2015-03-25 16:32:28 +00:00
* The priority of the transports are: Direct, SSH2, FTP PHP Extension, FTP Sockets
* (Via Sockets class, or `fsockopen()`). Valid values for these are: 'direct', 'ssh2',
* 'ftpext' or 'ftpsockets'.
2008-10-02 01:03:26 +00:00
*
2015-03-25 16:32:28 +00:00
* The return value can be overridden by defining the `FS_METHOD` constant in `wp-config.php`,
* or filtering via {@see 'filesystem_method'}.
2014-11-24 05:19:23 +00:00
*
2015-03-25 16:32:28 +00:00
* @link https://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants
2014-11-24 05:19:23 +00:00
*
2015-03-25 16:32:28 +00:00
* Plugins may define a custom transport handler, See WP_Filesystem().
2009-11-05 23:03:48 +00:00
*
* @since 2.5.0
2008-10-02 01:03:26 +00:00
*
2015-09-25 23:58:25 +00:00
* @global callable $_wp_filesystem_direct_method
2015-05-28 21:41:30 +00:00
*
2015-03-25 16:32:28 +00:00
* @param array $args Optional. Connection details. Default empty array.
* @param string $context Optional. Full path to the directory that is tested
* for being writable. Default false.
* @param bool $allow_relaxed_file_ownership Optional. Whether to allow Group/World writable.
* Default false.
2009-11-05 23:03:48 +00:00
* @return string The transport to use, see description for valid return values.
2008-10-02 01:03:26 +00:00
*/
2014-11-19 05:40:23 +00:00
function get_filesystem_method ( $args = array (), $context = false , $allow_relaxed_file_ownership = false ) {
2014-03-15 03:09:16 +00:00
$method = defined ( 'FS_METHOD' ) ? FS_METHOD : false ; // Please ensure that this is either 'direct', 'ssh2', 'ftpext' or 'ftpsockets'
2009-05-25 10:39:21 +00:00
2014-11-19 05:40:23 +00:00
if ( ! $context ) {
$context = WP_CONTENT_DIR ;
}
// If the directory doesn't exist (wp-content/languages) then use the parent directory as we'll create it.
if ( WP_LANG_DIR == $context && ! is_dir ( $context ) ) {
$context = dirname ( $context );
}
2013-10-16 04:15:09 +00:00
2014-11-19 05:40:23 +00:00
$context = trailingslashit ( $context );
if ( ! $method ) {
2013-10-16 04:15:09 +00:00
2009-08-15 08:03:48 +00:00
$temp_file_name = $context . 'temp-write-test-' . time ();
2009-05-25 10:39:21 +00:00
$temp_handle = @ fopen ( $temp_file_name , 'w' );
2009-05-27 00:56:32 +00:00
if ( $temp_handle ) {
2014-11-19 05:40:23 +00:00
// Attempt to determine the file owner of the WordPress files, and that of newly created files
$wp_file_owner = $temp_file_owner = false ;
if ( function_exists ( 'fileowner' ) ) {
$wp_file_owner = @ fileowner ( __FILE__ );
$temp_file_owner = @ fileowner ( $temp_file_name );
}
if ( $wp_file_owner !== false && $wp_file_owner === $temp_file_owner ) {
2015-01-08 05:03:23 +00:00
// WordPress is creating files as the same owner as the WordPress files,
2014-11-19 05:40:23 +00:00
// this means it's safe to modify & create new files via PHP.
$method = 'direct' ;
2014-12-15 14:08:23 +00:00
$GLOBALS [ '_wp_filesystem_direct_method' ] = 'file_owner' ;
2015-01-08 07:05:25 +00:00
} elseif ( $allow_relaxed_file_ownership ) {
2014-11-19 05:40:23 +00:00
// The $context directory is writable, and $allow_relaxed_file_ownership is set, this means we can modify files
// safely in this directory. This mode doesn't create new files, only alter existing ones.
2009-05-27 00:56:32 +00:00
$method = 'direct' ;
2014-12-15 14:08:23 +00:00
$GLOBALS [ '_wp_filesystem_direct_method' ] = 'relaxed_ownership' ;
2014-11-19 05:40:23 +00:00
}
2009-05-27 00:56:32 +00:00
@ fclose ( $temp_handle );
2009-08-15 08:03:48 +00:00
@ unlink ( $temp_file_name );
2009-05-27 00:56:32 +00:00
}
2009-05-25 10:39:21 +00:00
}
2008-02-11 05:45:54 +00:00
2009-06-23 21:54:53 +00:00
if ( ! $method && isset ( $args [ 'connection_type' ]) && 'ssh' == $args [ 'connection_type' ] && extension_loaded ( 'ssh2' ) && function_exists ( 'stream_get_contents' ) ) $method = 'ssh2' ;
2008-04-25 21:34:54 +00:00
if ( ! $method && extension_loaded ( 'ftp' ) ) $method = 'ftpext' ;
if ( ! $method && ( extension_loaded ( 'sockets' ) || function_exists ( 'fsockopen' ) ) ) $method = 'ftpsockets' ; //Sockets: Socket extension; PHP Mode: FSockopen / fwrite / fread
2014-03-24 02:45:15 +00:00
/**
* Filter the filesystem method to use.
*
* @since 2.6.0
*
2014-11-19 05:40:23 +00:00
* @param string $method Filesystem method to return.
* @param array $args An array of connection details for the method.
* @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.
2014-03-24 02:45:15 +00:00
*/
2014-11-19 05:40:23 +00:00
return apply_filters ( 'filesystem_method' , $method , $args , $context , $allow_relaxed_file_ownership );
2008-02-11 05:45:54 +00:00
}
2008-10-02 01:03:26 +00:00
/**
2014-11-24 05:19:23 +00:00
* Displays a form to the user to request for their FTP/SSH details in order
* to connect to the filesystem.
*
2009-11-05 23:03:48 +00:00
* All chosen/entered details are saved, Excluding the Password.
2008-10-02 01:03:26 +00:00
*
2014-11-24 05:19:23 +00:00
* Hostnames may be in the form of hostname:portnumber (eg: wordpress.org:2467)
* to specify an alternate FTP/SSH port.
2008-10-02 01:03:26 +00:00
*
2014-11-24 05:19:23 +00:00
* Plugins may override this form by returning true|false via the
* {@see 'request_filesystem_credentials'} filter.
2009-11-05 23:03:48 +00:00
*
2014-11-24 05:19:23 +00:00
* @since 2.5.
*
* @todo Properly mark optional arguments as such
2009-11-05 23:03:48 +00:00
*
2015-10-21 03:51:24 +00:00
* @global string $pagenow
*
2015-06-27 01:03:25 +00:00
* @param string $form_post the URL to post the form to
* @param string $type the chosen Filesystem method in use
* @param bool $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 bool False on failure. True on success.
2008-10-02 01:03:26 +00:00
*/
2014-11-19 05:40:23 +00:00
function request_filesystem_credentials ( $form_post , $type = '' , $error = false , $context = false , $extra_fields = null , $allow_relaxed_file_ownership = false ) {
2015-10-21 03:51:24 +00:00
global $pagenow ;
2014-03-24 02:45:15 +00:00
/**
* 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.
2014-11-19 05:40:23 +00:00
* @param bool $allow_relaxed_file_ownership Whether to allow Group/World writable.
2014-03-24 02:45:15 +00:00
* @param array $extra_fields Extra POST fields.
*/
2014-11-19 05:40:23 +00:00
$req_cred = apply_filters ( 'request_filesystem_credentials' , '' , $form_post , $type , $error , $context , $extra_fields , $allow_relaxed_file_ownership );
2008-08-04 21:01:09 +00:00
if ( '' !== $req_cred )
return $req_cred ;
2014-11-19 05:40:23 +00:00
if ( empty ( $type ) ) {
$type = get_filesystem_method ( array (), $context , $allow_relaxed_file_ownership );
}
2008-08-04 21:01:09 +00:00
if ( 'direct' == $type )
return true ;
2008-08-09 05:36:14 +00:00
2010-03-03 19:53:39 +00:00
if ( is_null ( $extra_fields ) )
$extra_fields = array ( 'version' , 'locale' );
2009-04-22 23:38:01 +00:00
$credentials = get_option ( 'ftp_credentials' , array ( 'hostname' => '' , 'username' => '' ));
2008-08-04 21:01:09 +00:00
// 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)
2013-03-01 17:00:25 +00:00
$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' ] ) : '' );
2008-12-09 18:03:31 +00:00
2008-09-11 17:44:43 +00:00
// Check to see if we are setting the public/private keys for ssh
2013-03-01 17:00:25 +00:00
$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' ] ) : '' );
2008-12-09 18:03:31 +00:00
2014-07-17 09:14:16 +00:00
// Sanitize the hostname, Some people might pass in odd-data:
2008-12-12 20:12:16 +00:00
$credentials [ 'hostname' ] = preg_replace ( '|\w+://|' , '' , $credentials [ 'hostname' ]); //Strip any schemes off
2009-11-05 23:03:48 +00:00
if ( strpos ( $credentials [ 'hostname' ], ':' ) ) {
2008-09-09 03:24:05 +00:00
list ( $credentials [ 'hostname' ], $credentials [ 'port' ] ) = explode ( ':' , $credentials [ 'hostname' ], 2 );
2009-11-05 23:03:48 +00:00
if ( ! is_numeric ( $credentials [ 'port' ]) )
unset ( $credentials [ 'port' ]);
} else {
2008-12-12 20:12:16 +00:00
unset ( $credentials [ 'port' ]);
2009-11-05 23:03:48 +00:00
}
2008-09-09 03:24:05 +00:00
2015-01-08 07:05:25 +00:00
if ( ( defined ( 'FTP_SSH' ) && FTP_SSH ) || ( defined ( 'FS_METHOD' ) && 'ssh2' == FS_METHOD ) ) {
2008-09-05 05:35:58 +00:00
$credentials [ 'connection_type' ] = 'ssh' ;
2015-01-08 07:05:25 +00:00
} elseif ( ( defined ( 'FTP_SSL' ) && FTP_SSL ) && 'ftpext' == $type ) { //Only the FTP Extension understands SSL
2008-09-05 05:35:58 +00:00
$credentials [ 'connection_type' ] = 'ftps' ;
2015-01-08 07:05:25 +00:00
} elseif ( ! empty ( $_POST [ 'connection_type' ] ) ) {
2013-03-01 17:00:25 +00:00
$credentials [ 'connection_type' ] = wp_unslash ( $_POST [ 'connection_type' ] );
2015-01-08 07:05:25 +00:00
} elseif ( ! isset ( $credentials [ 'connection_type' ] ) ) { //All else fails (And it's not defaulted to something else saved), Default to FTP
2008-09-05 05:35:58 +00:00
$credentials [ 'connection_type' ] = 'ftp' ;
2015-01-08 07:05:25 +00:00
}
2009-05-24 23:47:49 +00:00
if ( ! $error &&
2009-04-22 23:38:01 +00:00
(
( ! empty ( $credentials [ 'password' ]) && ! empty ( $credentials [ 'username' ]) && ! empty ( $credentials [ 'hostname' ]) ) ||
( 'ssh' == $credentials [ 'connection_type' ] && ! empty ( $credentials [ 'public_key' ]) && ! empty ( $credentials [ 'private_key' ]) )
) ) {
2008-08-04 21:01:09 +00:00
$stored_credentials = $credentials ;
2008-12-12 20:12:16 +00:00
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' ]);
2015-10-05 15:06:28 +00:00
if ( ! wp_installing () ) {
2014-09-17 17:58:15 +00:00
update_option ( 'ftp_credentials' , $stored_credentials );
}
2008-08-04 21:01:09 +00:00
return $credentials ;
}
2014-05-16 18:26:15 +00:00
$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' ] : '' ;
2014-08-24 16:04:18 +00:00
$connection_type = isset ( $credentials [ 'connection_type' ] ) ? $credentials [ 'connection_type' ] : '' ;
2014-05-16 18:26:15 +00:00
2008-09-05 05:35:58 +00:00
if ( $error ) {
2011-09-30 17:18:35 +00:00
$error_string = __ ( '<strong>ERROR:</strong> There was an error connecting to the server, Please verify the settings are correct.' );
2008-09-05 05:35:58 +00:00
if ( is_wp_error ( $error ) )
2011-01-01 22:14:42 +00:00
$error_string = esc_html ( $error -> get_error_message () );
echo '<div id="message" class="error"><p>' . $error_string . '</p></div>' ;
2008-09-05 05:35:58 +00:00
}
2009-11-05 23:03:48 +00:00
$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' );
2014-03-24 02:45:15 +00:00
/**
* 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 );
2009-11-05 23:03:48 +00:00
2008-08-04 21:01:09 +00:00
?>
2008-09-11 17:44:43 +00:00
<script type="text/javascript">
<!--
jQuery(function($){
jQuery("#ssh").click(function () {
2008-09-13 18:06:20 +00:00
jQuery("#ssh_keys").show();
2008-09-11 17:44:43 +00:00
});
2008-09-13 18:06:20 +00:00
jQuery("#ftp, #ftps").click(function () {
jQuery("#ssh_keys").hide();
2008-12-09 18:03:31 +00:00
});
2015-04-22 16:24:26 +00:00
jQuery('#request-filesystem-credentials-form input[value=""]:first').focus();
2008-09-11 17:44:43 +00:00
});
-->
</script>
2013-03-18 14:01:25 +00:00
<form action="<?php echo esc_url( $form_post ) ?>" method="post">
2015-04-01 02:48:28 +00:00
<div id="request-filesystem-credentials-form" class="request-filesystem-credentials-form">
2015-10-21 03:51:24 +00:00
<?php
// Print a H1 heading in the FTP credentials modal dialog, default is a H2.
$heading_tag = 'h2';
if ( 'plugins.php' === $pagenow || 'plugin-install.php' === $pagenow ) {
$heading_tag = 'h1';
}
echo "<$heading_tag id='request-filesystem-credentials-title'>" . __( 'Connection Information' ) . "</$heading_tag>";
?>
2015-04-01 02:48:28 +00:00
<p id="request-filesystem-credentials-desc"><?php
2010-06-03 18:58:41 +00:00
$label_user = __('Username');
$label_pass = __('Password');
2010-09-07 15:11:43 +00:00
_e('To perform the requested action, WordPress needs to access your web server.');
2010-06-01 21:57:26 +00:00
echo ' ';
2010-06-01 20:35:59 +00:00
if ( ( isset( $types['ftp'] ) || isset( $types['ftps'] ) ) ) {
2010-06-03 18:58:41 +00:00
if ( isset( $types['ssh'] ) ) {
2010-06-01 20:35:59 +00:00
_e('Please enter your FTP or SSH credentials to proceed.');
2010-06-03 18:58:41 +00:00
$label_user = __('FTP/SSH Username');
$label_pass = __('FTP/SSH Password');
} else {
2010-06-01 20:35:59 +00:00
_e('Please enter your FTP credentials to proceed.');
2010-06-03 18:58:41 +00:00
$label_user = __('FTP Username');
$label_pass = __('FTP Password');
}
2010-06-01 21:57:26 +00:00
echo ' ';
2010-06-01 20:35:59 +00:00
}
_e('If you do not remember your credentials, you should contact your web host.');
?></p>
2015-04-01 02:48:28 +00:00
<label for="hostname">
<span class="field-title"><?php _e( 'Hostname' ) ?></span>
2015-04-08 16:50:27 +00:00
<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') ); ?> />
2015-04-01 02:48:28 +00:00
</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>
2009-11-05 23:03:48 +00:00
<?php if ( isset($types['ssh']) ) : ?>
2015-10-21 03:51:24 +00:00
<fieldset>
<legend><?php _e( 'Authentication Keys' ); ?></legend>
2015-04-01 02:48:28 +00:00
<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>
2015-10-21 03:51:24 +00:00
</fieldset>
2015-04-01 02:48:28 +00:00
<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>
2009-05-30 17:14:07 +00:00
<?php endif; ?>
2015-10-21 03:51:24 +00:00
<fieldset>
<legend><?php _e( 'Connection Type' ); ?></legend>
2010-03-11 17:21:18 +00:00
<?php
$disabled = disabled( (defined('FTP_SSL') && FTP_SSL) || (defined('FTP_SSH') && FTP_SSH), true, false );
foreach ( $types as $name => $text ) : ?>
2009-11-06 10:53:41 +00:00
<label for="<?php echo esc_attr($name) ?>">
2010-03-11 17:21:18 +00:00
<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; ?> />
2009-11-05 23:03:48 +00:00
<?php echo $text ?>
</label>
<?php endforeach; ?>
2008-09-05 05:35:58 +00:00
</fieldset>
2010-03-03 19:53:39 +00:00
<?php
foreach ( (array) $extra_fields as $field ) {
if ( isset( $_POST[ $field ] ) )
2013-03-01 17:00:25 +00:00
echo '<input type="hidden" name="' . esc_attr( $field ) . '" value="' . esc_attr( wp_unslash( $_POST[ $field ] ) ) . '" />';
2010-03-03 19:53:39 +00:00
}
?>
2015-04-01 02:48:28 +00:00
<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>
2008-08-04 21:01:09 +00:00
</div>
</form>
<?php
return false;
}
2015-03-18 03:18:27 +00:00
/**
2015-04-04 21:13:26 +00:00
* Print the filesystem credentials modal when needed.
2015-03-18 03:18:27 +00:00
*
* @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>
2015-04-01 02:48:28 +00:00
<div class="notification-dialog" role="dialog" aria-labelledby="request-filesystem-credentials-title" tabindex="0">
2015-03-18 03:18:27 +00:00
<div class="request-filesystem-credentials-dialog-content">
<?php request_filesystem_credentials( site_url() ); ?>
2015-09-05 15:17:24 +00:00
</div>
2015-03-18 03:18:27 +00:00
</div>
</div>
<?php
}