sys_get_temp_dir(), before finally defaulting to /tmp/
*
* In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
*
* @since 2.5.0
*
* @return string Writable temporary directory
*/
function get_temp_dir() {
static $temp;
if ( defined('WP_TEMP_DIR') )
return trailingslashit(WP_TEMP_DIR);
if ( $temp )
return trailingslashit($temp);
$temp = WP_CONTENT_DIR . '/';
if ( is_dir($temp) && @is_writable($temp) )
return $temp;
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_writable($temp) )
return trailingslashit($temp);
}
$temp = ini_get('upload_tmp_dir');
if ( is_dir($temp) && @is_writable($temp) )
return trailingslashit($temp);
$temp = '/tmp/';
return $temp;
}
/**
* Get an array containing the current upload directory's path and url.
*
* Checks the 'upload_path' option, which should be from the web root folder,
* and if it isn't empty it will be used. If it is empty, then the path will be
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
*
* The upload URL path is set either by the 'upload_url_path' option or by using
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
*
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
* the administration settings panel), then the time will be used. The format
* will be year first and then month.
*
* If the path couldn't be created, then an error will be returned with the key
* 'error' containing the error message. The error suggests that the parent
* directory is not writable by the server.
*
* On success, the returned array will have many indices:
* 'path' - base directory and sub directory or full path to upload directory.
* 'url' - base url and sub directory or absolute URL to upload directory.
* 'subdir' - sub directory if uploads use year/month folders option is on.
* 'basedir' - path without subdir.
* 'baseurl' - URL path without subdir.
* 'error' - set to false.
*
* @since 2.0.0
* @uses apply_filters() Calls 'upload_dir' on returned array.
*
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array See above for description.
*/
function wp_upload_dir( $time = null ) {
global $switched;
$siteurl = get_option( 'siteurl' );
$upload_path = get_option( 'upload_path' );
$upload_path = trim($upload_path);
$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
if ( empty($upload_path) ) {
$dir = WP_CONTENT_DIR . '/uploads';
} else {
$dir = $upload_path;
if ( 'wp-content/uploads' == $upload_path ) {
$dir = WP_CONTENT_DIR . '/uploads';
} elseif ( 0 !== strpos($dir, ABSPATH) ) {
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
$dir = path_join( ABSPATH, $dir );
}
}
if ( !$url = get_option( 'upload_url_path' ) ) {
if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
$url = WP_CONTENT_URL . '/uploads';
else
$url = trailingslashit( $siteurl ) . $upload_path;
}
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
$dir = ABSPATH . UPLOADS;
$url = trailingslashit( $siteurl ) . UPLOADS;
}
if ( is_multisite() && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
if ( defined( 'BLOGUPLOADDIR' ) )
$dir = untrailingslashit(BLOGUPLOADDIR);
$url = str_replace( UPLOADS, 'files', $url );
}
$bdir = $dir;
$burl = $url;
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
if ( !$time )
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
$dir .= $subdir;
$url .= $subdir;
$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
// Make sure we have an uploads dir
if ( ! wp_mkdir_p( $uploads['path'] ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
return array( 'error' => $message );
}
return $uploads;
}
/**
* Get a filename that is sanitized and unique for the given directory.
*
* If the filename is not unique, then a number will be added to the filename
* before the extension, and will continue adding numbers until the filename is
* unique.
*
* The callback is passed three parameters, the first one is the directory, the
* second is the filename, and the third is the extension.
*
* @since 2.5.0
*
* @param string $dir
* @param string $filename
* @param mixed $unique_filename_callback Callback.
* @return string New filename, if given wasn't unique.
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// sanitize the file name before we begin processing
$filename = sanitize_file_name($filename);
// separate the filename into a name and extension
$info = pathinfo($filename);
$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
$name = basename($filename, $ext);
// edge case: if file is named '.ext', treat as an empty name
if ( $name === $ext )
$name = '';
// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
} else {
$number = '';
// change '.ext' to lower case
if ( $ext && strtolower($ext) != $ext ) {
$ext2 = strtolower($ext);
$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
// check for both lower and upper case extension or image sub-sizes may be overwritten
while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
$new_number = $number + 1;
$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
$number = $new_number;
}
return $filename2;
}
while ( file_exists( $dir . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
}
return $filename;
}
/**
* Create a file in the upload folder with given content.
*
* If there is an error, then the key 'error' will exist with the error message.
* If success, then the key 'file' will have the unique file path, the 'url' key
* will have the link to the new file. and the 'error' key will be set to false.
*
* This function will not move an uploaded file to the upload folder. It will
* create a new file with the content in $bits parameter. If you move the upload
* file, read the content of the uploaded file, and then you can give the
* filename and content to this function, which will add it to the upload
* folder.
*
* The permissions will be set on the new file automatically by this function.
*
* @since 2.0.0
*
* @param string $name
* @param null $deprecated Never used. Set to null.
* @param mixed $bits File content
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
if ( !empty( $deprecated ) )
_deprecated_argument( __FUNCTION__, '2.0' );
if ( empty( $name ) )
return array( 'error' => __( 'Empty filename' ) );
$wp_filetype = wp_check_filetype( $name );
if ( !$wp_filetype['ext'] )
return array( 'error' => __( 'Invalid file type' ) );
$upload = wp_upload_dir( $time );
if ( $upload['error'] !== false )
return $upload;
$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
if ( !is_array( $upload_bits_error ) ) {
$upload[ 'error' ] = $upload_bits_error;
return $upload;
}
$filename = wp_unique_filename( $upload['path'], $name );
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
return array( 'error' => $message );
}
$ifp = @ fopen( $new_file, 'wb' );
if ( ! $ifp )
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
$stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
clearstatcache();
// Compute the URL
$url = $upload['url'] . "/$filename";
return array( 'file' => $new_file, 'url' => $url, 'error' => false );
}
/**
* Retrieve the file type based on the extension name.
*
* @package WordPress
* @since 2.5.0
* @uses apply_filters() Calls 'ext2type' hook on default supported types.
*
* @param string $ext The extension to search.
* @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
*/
function wp_ext2type( $ext ) {
$ext2type = apply_filters( 'ext2type', array(
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsb', 'xlsm' ),
'interactive' => array( 'key', 'ppt', 'pptx', 'pptm', 'odp', 'swf' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
));
foreach ( $ext2type as $type => $exts )
if ( in_array( $ext, $exts ) )
return $type;
}
/**
* Retrieve the file type from the file name.
*
* You can optionally define the mime array, if needed.
*
* @since 2.0.4
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Attempt to determine the real file type of a file.
* If unable to, the file name extension will be used to determine type.
*
* If it's determined that the extension does not match the file's real type,
* then the "proper_filename" value will be set with a proper filename and extension.
*
* Currently this function only supports validating images known to getimagesize().
*
* @since 3.0.0
*
* @param string $file Full path to the image.
* @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
*/
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
$proper_filename = false;
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) )
return compact( 'ext', 'type', 'proper_filename' );
// We're able to validate images using GD
if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
// Attempt to figure out what type of image it actually is
$imgstats = @getimagesize( $file );
// If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
// This is a simplified array of MIMEs that getimagesize() can detect and their extensions
// You shouldn't need to use this filter, but it's here just in case
$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
) );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
$new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename )
$proper_filename = $new_filename; // Mark that it changed
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
extract( $wp_filetype );
}
}
}
// Let plugins try and validate other types of files
// Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
}
/**
* Retrieve list of allowed mime types and file extensions.
*
* @since 2.8.6
*
* @return array Array of mime types keyed by the file extension regex corresponding to those types.
*/
function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( 'upload_mimes', array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'bmp' => 'image/bmp',
'tif|tiff' => 'image/tiff',
'ico' => 'image/x-icon',
'asf|asx|wax|wmv|wmx' => 'video/asf',
'avi' => 'video/avi',
'divx' => 'video/divx',
'flv' => 'video/x-flv',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'txt|asc|c|cc|h' => 'text/plain',
'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'css' => 'text/css',
'htm|html' => 'text/html',
'mp3|m4a|m4b' => 'audio/mpeg',
'mp4|m4v' => 'video/mp4',
'ra|ram' => 'audio/x-realaudio',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
'ogv' => 'video/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/wma',
'mka' => 'audio/x-matroska',
'mkv' => 'video/x-matroska',
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'doc|docx' => 'application/msword',
'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docm|dotm' => 'application/vnd.ms-word',
'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'rar' => 'application/rar',
'7z' => 'application/x-7z-compressed',
'exe' => 'application/x-msdownload',
// openoffice formats
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
// wordperfect formats
'wp|wpd' => 'application/wordperfect',
) );
}
return $mimes;
}
/**
* Retrieve nonce action "Are you sure" message.
*
* The action is split by verb and noun. The action format is as follows:
* verb-action_extra. The verb is before the first dash and has the format of
* letters and no spaces and numbers. The noun is after the dash and before the
* underscore, if an underscore exists. The noun is also only letters.
*
* The filter will be called for any action, which is not defined by WordPress.
* You may use the filter for your plugin to explain nonce actions to the user,
* when they get the "Are you sure?" message. The filter is in the format of
* 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
* $noun replaced by the found noun. The two parameters that are given to the
* hook are the localized "Are you sure you want to do this?" message with the
* extra text (the text after the underscore).
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action Nonce action.
* @return string Are you sure message.
*/
function wp_explain_nonce( $action ) {
if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
$verb = $matches[1];
$noun = $matches[2];
$trans = array();
$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' );
$trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false );
$trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' );
$trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' );
$trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' );
$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' );
$trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' );
$trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' );
$trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
$trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false );
$trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' );
$trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' );
$trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false );
$trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false );
$trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' );
$trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' );
$trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' );
$trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' );
$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' );
$trans['upgrade']['plugin'] = array( __( 'Your attempt to update this plugin: “%s” has failed.' ), 'use_id' );
$trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false );
$trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' );
$trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' );
$trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false );
$trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false );
$trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false );
$trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false );
$trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
$trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' );
$trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' );
$trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' );
$trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
if ( isset( $trans[$verb][$noun] ) ) {
if ( !empty( $trans[$verb][$noun][1] ) ) {
$lookup = $trans[$verb][$noun][1];
if ( isset($trans[$verb][$noun][2]) )
$lookup_value = $trans[$verb][$noun][2];
$object = $matches[4];
if ( 'use_id' != $lookup ) {
if ( isset( $lookup_value ) )
$object = call_user_func( $lookup, $lookup_value, $object );
else
$object = call_user_func( $lookup, $object );
}
return sprintf( $trans[$verb][$noun][0], esc_html($object) );
} else {
return $trans[$verb][$noun][0];
}
}
return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
} else {
return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
}
}
/**
* Display "Are You Sure" message to confirm the action being taken.
*
* If the action has the nonce explain message, then it will be displayed along
* with the "Are you sure?" message.
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action The nonce action.
*/
function wp_nonce_ays( $action ) {
$title = __( 'WordPress Failure Notice' );
$html = esc_html( wp_explain_nonce( $action ) );
if ( 'log-out' == $action )
$html .= "" . sprintf( __( "Do you really want to log out?"), wp_logout_url() ); elseif ( wp_get_referer() ) $html .= "
" . __( 'Please try again.' ) . ""; wp_die( $html, $title, array('response' => 403) ); } /** * Kill WordPress execution and display HTML message with error message. * * This function complements the die() PHP function. The difference is that * HTML will be displayed to the user. It is recommended to use this function * only, when the execution should not continue any further. It is not * recommended to call this function very often and try to handle as many errors * as possible silently. * * @since 2.0.4 * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function wp_die( $message, $title = '', $args = array() ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) die('-1'); if ( function_exists( 'apply_filters' ) ) { $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); } else { $function = '_default_wp_die_handler'; } call_user_func( $function, $message, $title, $args ); } /** * Kill WordPress execution and display HTML message with error message. * * This is the default handler for wp_die if you want a custom one for your * site then you can overload using the wp_die_handler filter in wp_die * * @since 3.0.0 * @access private * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 500 ); $r = wp_parse_args($args, $defaults); $have_gettext = function_exists('__'); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( empty( $title ) ) { $error_data = $message->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['title'] ) ) $title = $error_data['title']; } $errors = $message->get_error_messages(); switch ( count( $errors ) ) : case 0 : $message = ''; break; case 1 : $message = "
{$errors[0]}
"; break; default : $message = "$message
"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { $back_text = $have_gettext? __('« Back') : '« Back'; $message .= "\n"; } if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : if ( !headers_sent() ) { status_header( $r['response'] ); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); } if ( empty($title) ) $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; $text_direction = 'ltr'; if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) $text_direction = 'rtl'; elseif ( function_exists( 'is_rtl' ) && is_rtl() ) $text_direction = 'rtl'; ?> >sys_get_temp_dir(), before finally defaulting to /tmp/
*
* In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
*
* @since 2.5.0
*
* @return string Writable temporary directory
*/
function get_temp_dir() {
static $temp;
if ( defined('WP_TEMP_DIR') )
return trailingslashit(WP_TEMP_DIR);
if ( $temp )
return trailingslashit($temp);
$temp = WP_CONTENT_DIR . '/';
if ( is_dir($temp) && @is_writable($temp) )
return $temp;
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_writable($temp) )
return trailingslashit($temp);
}
$temp = ini_get('upload_tmp_dir');
if ( is_dir($temp) && @is_writable($temp) )
return trailingslashit($temp);
$temp = '/tmp/';
return $temp;
}
/**
* Get an array containing the current upload directory's path and url.
*
* Checks the 'upload_path' option, which should be from the web root folder,
* and if it isn't empty it will be used. If it is empty, then the path will be
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
*
* The upload URL path is set either by the 'upload_url_path' option or by using
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
*
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
* the administration settings panel), then the time will be used. The format
* will be year first and then month.
*
* If the path couldn't be created, then an error will be returned with the key
* 'error' containing the error message. The error suggests that the parent
* directory is not writable by the server.
*
* On success, the returned array will have many indices:
* 'path' - base directory and sub directory or full path to upload directory.
* 'url' - base url and sub directory or absolute URL to upload directory.
* 'subdir' - sub directory if uploads use year/month folders option is on.
* 'basedir' - path without subdir.
* 'baseurl' - URL path without subdir.
* 'error' - set to false.
*
* @since 2.0.0
* @uses apply_filters() Calls 'upload_dir' on returned array.
*
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array See above for description.
*/
function wp_upload_dir( $time = null ) {
global $switched;
$siteurl = get_option( 'siteurl' );
$upload_path = get_option( 'upload_path' );
$upload_path = trim($upload_path);
$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
if ( empty($upload_path) ) {
$dir = WP_CONTENT_DIR . '/uploads';
} else {
$dir = $upload_path;
if ( 'wp-content/uploads' == $upload_path ) {
$dir = WP_CONTENT_DIR . '/uploads';
} elseif ( 0 !== strpos($dir, ABSPATH) ) {
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
$dir = path_join( ABSPATH, $dir );
}
}
if ( !$url = get_option( 'upload_url_path' ) ) {
if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
$url = WP_CONTENT_URL . '/uploads';
else
$url = trailingslashit( $siteurl ) . $upload_path;
}
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
$dir = ABSPATH . UPLOADS;
$url = trailingslashit( $siteurl ) . UPLOADS;
}
if ( is_multisite() && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
if ( defined( 'BLOGUPLOADDIR' ) )
$dir = untrailingslashit(BLOGUPLOADDIR);
$url = str_replace( UPLOADS, 'files', $url );
}
$bdir = $dir;
$burl = $url;
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
if ( !$time )
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
$dir .= $subdir;
$url .= $subdir;
$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
// Make sure we have an uploads dir
if ( ! wp_mkdir_p( $uploads['path'] ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
return array( 'error' => $message );
}
return $uploads;
}
/**
* Get a filename that is sanitized and unique for the given directory.
*
* If the filename is not unique, then a number will be added to the filename
* before the extension, and will continue adding numbers until the filename is
* unique.
*
* The callback is passed three parameters, the first one is the directory, the
* second is the filename, and the third is the extension.
*
* @since 2.5.0
*
* @param string $dir
* @param string $filename
* @param mixed $unique_filename_callback Callback.
* @return string New filename, if given wasn't unique.
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// sanitize the file name before we begin processing
$filename = sanitize_file_name($filename);
// separate the filename into a name and extension
$info = pathinfo($filename);
$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
$name = basename($filename, $ext);
// edge case: if file is named '.ext', treat as an empty name
if ( $name === $ext )
$name = '';
// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
} else {
$number = '';
// change '.ext' to lower case
if ( $ext && strtolower($ext) != $ext ) {
$ext2 = strtolower($ext);
$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
// check for both lower and upper case extension or image sub-sizes may be overwritten
while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
$new_number = $number + 1;
$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
$number = $new_number;
}
return $filename2;
}
while ( file_exists( $dir . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
}
return $filename;
}
/**
* Create a file in the upload folder with given content.
*
* If there is an error, then the key 'error' will exist with the error message.
* If success, then the key 'file' will have the unique file path, the 'url' key
* will have the link to the new file. and the 'error' key will be set to false.
*
* This function will not move an uploaded file to the upload folder. It will
* create a new file with the content in $bits parameter. If you move the upload
* file, read the content of the uploaded file, and then you can give the
* filename and content to this function, which will add it to the upload
* folder.
*
* The permissions will be set on the new file automatically by this function.
*
* @since 2.0.0
*
* @param string $name
* @param null $deprecated Never used. Set to null.
* @param mixed $bits File content
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
if ( !empty( $deprecated ) )
_deprecated_argument( __FUNCTION__, '2.0' );
if ( empty( $name ) )
return array( 'error' => __( 'Empty filename' ) );
$wp_filetype = wp_check_filetype( $name );
if ( !$wp_filetype['ext'] )
return array( 'error' => __( 'Invalid file type' ) );
$upload = wp_upload_dir( $time );
if ( $upload['error'] !== false )
return $upload;
$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
if ( !is_array( $upload_bits_error ) ) {
$upload[ 'error' ] = $upload_bits_error;
return $upload;
}
$filename = wp_unique_filename( $upload['path'], $name );
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
return array( 'error' => $message );
}
$ifp = @ fopen( $new_file, 'wb' );
if ( ! $ifp )
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
$stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
clearstatcache();
// Compute the URL
$url = $upload['url'] . "/$filename";
return array( 'file' => $new_file, 'url' => $url, 'error' => false );
}
/**
* Retrieve the file type based on the extension name.
*
* @package WordPress
* @since 2.5.0
* @uses apply_filters() Calls 'ext2type' hook on default supported types.
*
* @param string $ext The extension to search.
* @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
*/
function wp_ext2type( $ext ) {
$ext2type = apply_filters( 'ext2type', array(
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsb', 'xlsm' ),
'interactive' => array( 'key', 'ppt', 'pptx', 'pptm', 'odp', 'swf' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
));
foreach ( $ext2type as $type => $exts )
if ( in_array( $ext, $exts ) )
return $type;
}
/**
* Retrieve the file type from the file name.
*
* You can optionally define the mime array, if needed.
*
* @since 2.0.4
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Attempt to determine the real file type of a file.
* If unable to, the file name extension will be used to determine type.
*
* If it's determined that the extension does not match the file's real type,
* then the "proper_filename" value will be set with a proper filename and extension.
*
* Currently this function only supports validating images known to getimagesize().
*
* @since 3.0.0
*
* @param string $file Full path to the image.
* @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
*/
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
$proper_filename = false;
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) )
return compact( 'ext', 'type', 'proper_filename' );
// We're able to validate images using GD
if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
// Attempt to figure out what type of image it actually is
$imgstats = @getimagesize( $file );
// If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
// This is a simplified array of MIMEs that getimagesize() can detect and their extensions
// You shouldn't need to use this filter, but it's here just in case
$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
) );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
$new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename )
$proper_filename = $new_filename; // Mark that it changed
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
extract( $wp_filetype );
}
}
}
// Let plugins try and validate other types of files
// Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
}
/**
* Retrieve list of allowed mime types and file extensions.
*
* @since 2.8.6
*
* @return array Array of mime types keyed by the file extension regex corresponding to those types.
*/
function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( 'upload_mimes', array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'bmp' => 'image/bmp',
'tif|tiff' => 'image/tiff',
'ico' => 'image/x-icon',
'asf|asx|wax|wmv|wmx' => 'video/asf',
'avi' => 'video/avi',
'divx' => 'video/divx',
'flv' => 'video/x-flv',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'txt|asc|c|cc|h' => 'text/plain',
'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'css' => 'text/css',
'htm|html' => 'text/html',
'mp3|m4a|m4b' => 'audio/mpeg',
'mp4|m4v' => 'video/mp4',
'ra|ram' => 'audio/x-realaudio',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
'ogv' => 'video/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/wma',
'mka' => 'audio/x-matroska',
'mkv' => 'video/x-matroska',
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'doc|docx' => 'application/msword',
'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docm|dotm' => 'application/vnd.ms-word',
'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'rar' => 'application/rar',
'7z' => 'application/x-7z-compressed',
'exe' => 'application/x-msdownload',
// openoffice formats
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
// wordperfect formats
'wp|wpd' => 'application/wordperfect',
) );
}
return $mimes;
}
/**
* Retrieve nonce action "Are you sure" message.
*
* The action is split by verb and noun. The action format is as follows:
* verb-action_extra. The verb is before the first dash and has the format of
* letters and no spaces and numbers. The noun is after the dash and before the
* underscore, if an underscore exists. The noun is also only letters.
*
* The filter will be called for any action, which is not defined by WordPress.
* You may use the filter for your plugin to explain nonce actions to the user,
* when they get the "Are you sure?" message. The filter is in the format of
* 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
* $noun replaced by the found noun. The two parameters that are given to the
* hook are the localized "Are you sure you want to do this?" message with the
* extra text (the text after the underscore).
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action Nonce action.
* @return string Are you sure message.
*/
function wp_explain_nonce( $action ) {
if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
$verb = $matches[1];
$noun = $matches[2];
$trans = array();
$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' );
$trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false );
$trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' );
$trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' );
$trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' );
$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' );
$trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' );
$trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' );
$trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
$trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false );
$trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' );
$trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' );
$trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false );
$trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false );
$trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' );
$trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' );
$trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' );
$trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' );
$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' );
$trans['upgrade']['plugin'] = array( __( 'Your attempt to update this plugin: “%s” has failed.' ), 'use_id' );
$trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false );
$trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' );
$trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' );
$trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false );
$trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false );
$trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false );
$trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false );
$trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
$trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' );
$trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' );
$trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' );
$trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
if ( isset( $trans[$verb][$noun] ) ) {
if ( !empty( $trans[$verb][$noun][1] ) ) {
$lookup = $trans[$verb][$noun][1];
if ( isset($trans[$verb][$noun][2]) )
$lookup_value = $trans[$verb][$noun][2];
$object = $matches[4];
if ( 'use_id' != $lookup ) {
if ( isset( $lookup_value ) )
$object = call_user_func( $lookup, $lookup_value, $object );
else
$object = call_user_func( $lookup, $object );
}
return sprintf( $trans[$verb][$noun][0], esc_html($object) );
} else {
return $trans[$verb][$noun][0];
}
}
return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
} else {
return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
}
}
/**
* Display "Are You Sure" message to confirm the action being taken.
*
* If the action has the nonce explain message, then it will be displayed along
* with the "Are you sure?" message.
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action The nonce action.
*/
function wp_nonce_ays( $action ) {
$title = __( 'WordPress Failure Notice' );
$html = esc_html( wp_explain_nonce( $action ) );
if ( 'log-out' == $action )
$html .= "" . sprintf( __( "Do you really want to log out?"), wp_logout_url() ); elseif ( wp_get_referer() ) $html .= "
" . __( 'Please try again.' ) . ""; wp_die( $html, $title, array('response' => 403) ); } /** * Kill WordPress execution and display HTML message with error message. * * This function complements the die() PHP function. The difference is that * HTML will be displayed to the user. It is recommended to use this function * only, when the execution should not continue any further. It is not * recommended to call this function very often and try to handle as many errors * as possible silently. * * @since 2.0.4 * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function wp_die( $message, $title = '', $args = array() ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) die('-1'); if ( function_exists( 'apply_filters' ) ) { $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); } else { $function = '_default_wp_die_handler'; } call_user_func( $function, $message, $title, $args ); } /** * Kill WordPress execution and display HTML message with error message. * * This is the default handler for wp_die if you want a custom one for your * site then you can overload using the wp_die_handler filter in wp_die * * @since 3.0.0 * @access private * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 500 ); $r = wp_parse_args($args, $defaults); $have_gettext = function_exists('__'); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( empty( $title ) ) { $error_data = $message->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['title'] ) ) $title = $error_data['title']; } $errors = $message->get_error_messages(); switch ( count( $errors ) ) : case 0 : $message = ''; break; case 1 : $message = "
{$errors[0]}
"; break; default : $message = "$message
"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { $back_text = $have_gettext? __('« Back') : '« Back'; $message .= "\n"; } if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : if ( !headers_sent() ) { status_header( $r['response'] ); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); } if ( empty($title) ) $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; $text_direction = 'ltr'; if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) $text_direction = 'rtl'; elseif ( function_exists( 'is_rtl' ) && is_rtl() ) $text_direction = 'rtl'; ?> >sys_get_temp_dir(), before finally defaulting to /tmp/
*
* In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
*
* @since 2.5.0
*
* @return string Writable temporary directory
*/
function get_temp_dir() {
static $temp;
if ( defined('WP_TEMP_DIR') )
return trailingslashit(WP_TEMP_DIR);
if ( $temp )
return trailingslashit($temp);
$temp = WP_CONTENT_DIR . '/';
if ( is_dir($temp) && @is_writable($temp) )
return $temp;
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_writable($temp) )
return trailingslashit($temp);
}
$temp = ini_get('upload_tmp_dir');
if ( is_dir($temp) && @is_writable($temp) )
return trailingslashit($temp);
$temp = '/tmp/';
return $temp;
}
/**
* Get an array containing the current upload directory's path and url.
*
* Checks the 'upload_path' option, which should be from the web root folder,
* and if it isn't empty it will be used. If it is empty, then the path will be
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
*
* The upload URL path is set either by the 'upload_url_path' option or by using
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
*
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
* the administration settings panel), then the time will be used. The format
* will be year first and then month.
*
* If the path couldn't be created, then an error will be returned with the key
* 'error' containing the error message. The error suggests that the parent
* directory is not writable by the server.
*
* On success, the returned array will have many indices:
* 'path' - base directory and sub directory or full path to upload directory.
* 'url' - base url and sub directory or absolute URL to upload directory.
* 'subdir' - sub directory if uploads use year/month folders option is on.
* 'basedir' - path without subdir.
* 'baseurl' - URL path without subdir.
* 'error' - set to false.
*
* @since 2.0.0
* @uses apply_filters() Calls 'upload_dir' on returned array.
*
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array See above for description.
*/
function wp_upload_dir( $time = null ) {
global $switched;
$siteurl = get_option( 'siteurl' );
$upload_path = get_option( 'upload_path' );
$upload_path = trim($upload_path);
$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
if ( empty($upload_path) ) {
$dir = WP_CONTENT_DIR . '/uploads';
} else {
$dir = $upload_path;
if ( 'wp-content/uploads' == $upload_path ) {
$dir = WP_CONTENT_DIR . '/uploads';
} elseif ( 0 !== strpos($dir, ABSPATH) ) {
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
$dir = path_join( ABSPATH, $dir );
}
}
if ( !$url = get_option( 'upload_url_path' ) ) {
if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
$url = WP_CONTENT_URL . '/uploads';
else
$url = trailingslashit( $siteurl ) . $upload_path;
}
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
$dir = ABSPATH . UPLOADS;
$url = trailingslashit( $siteurl ) . UPLOADS;
}
if ( is_multisite() && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
if ( defined( 'BLOGUPLOADDIR' ) )
$dir = untrailingslashit(BLOGUPLOADDIR);
$url = str_replace( UPLOADS, 'files', $url );
}
$bdir = $dir;
$burl = $url;
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
if ( !$time )
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
$dir .= $subdir;
$url .= $subdir;
$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
// Make sure we have an uploads dir
if ( ! wp_mkdir_p( $uploads['path'] ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
return array( 'error' => $message );
}
return $uploads;
}
/**
* Get a filename that is sanitized and unique for the given directory.
*
* If the filename is not unique, then a number will be added to the filename
* before the extension, and will continue adding numbers until the filename is
* unique.
*
* The callback is passed three parameters, the first one is the directory, the
* second is the filename, and the third is the extension.
*
* @since 2.5.0
*
* @param string $dir
* @param string $filename
* @param mixed $unique_filename_callback Callback.
* @return string New filename, if given wasn't unique.
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// sanitize the file name before we begin processing
$filename = sanitize_file_name($filename);
// separate the filename into a name and extension
$info = pathinfo($filename);
$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
$name = basename($filename, $ext);
// edge case: if file is named '.ext', treat as an empty name
if ( $name === $ext )
$name = '';
// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
} else {
$number = '';
// change '.ext' to lower case
if ( $ext && strtolower($ext) != $ext ) {
$ext2 = strtolower($ext);
$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
// check for both lower and upper case extension or image sub-sizes may be overwritten
while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
$new_number = $number + 1;
$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
$number = $new_number;
}
return $filename2;
}
while ( file_exists( $dir . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
}
return $filename;
}
/**
* Create a file in the upload folder with given content.
*
* If there is an error, then the key 'error' will exist with the error message.
* If success, then the key 'file' will have the unique file path, the 'url' key
* will have the link to the new file. and the 'error' key will be set to false.
*
* This function will not move an uploaded file to the upload folder. It will
* create a new file with the content in $bits parameter. If you move the upload
* file, read the content of the uploaded file, and then you can give the
* filename and content to this function, which will add it to the upload
* folder.
*
* The permissions will be set on the new file automatically by this function.
*
* @since 2.0.0
*
* @param string $name
* @param null $deprecated Never used. Set to null.
* @param mixed $bits File content
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
if ( !empty( $deprecated ) )
_deprecated_argument( __FUNCTION__, '2.0' );
if ( empty( $name ) )
return array( 'error' => __( 'Empty filename' ) );
$wp_filetype = wp_check_filetype( $name );
if ( !$wp_filetype['ext'] )
return array( 'error' => __( 'Invalid file type' ) );
$upload = wp_upload_dir( $time );
if ( $upload['error'] !== false )
return $upload;
$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
if ( !is_array( $upload_bits_error ) ) {
$upload[ 'error' ] = $upload_bits_error;
return $upload;
}
$filename = wp_unique_filename( $upload['path'], $name );
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
return array( 'error' => $message );
}
$ifp = @ fopen( $new_file, 'wb' );
if ( ! $ifp )
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
$stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
clearstatcache();
// Compute the URL
$url = $upload['url'] . "/$filename";
return array( 'file' => $new_file, 'url' => $url, 'error' => false );
}
/**
* Retrieve the file type based on the extension name.
*
* @package WordPress
* @since 2.5.0
* @uses apply_filters() Calls 'ext2type' hook on default supported types.
*
* @param string $ext The extension to search.
* @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
*/
function wp_ext2type( $ext ) {
$ext2type = apply_filters( 'ext2type', array(
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsb', 'xlsm' ),
'interactive' => array( 'key', 'ppt', 'pptx', 'pptm', 'odp', 'swf' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
));
foreach ( $ext2type as $type => $exts )
if ( in_array( $ext, $exts ) )
return $type;
}
/**
* Retrieve the file type from the file name.
*
* You can optionally define the mime array, if needed.
*
* @since 2.0.4
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Attempt to determine the real file type of a file.
* If unable to, the file name extension will be used to determine type.
*
* If it's determined that the extension does not match the file's real type,
* then the "proper_filename" value will be set with a proper filename and extension.
*
* Currently this function only supports validating images known to getimagesize().
*
* @since 3.0.0
*
* @param string $file Full path to the image.
* @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
*/
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
$proper_filename = false;
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) )
return compact( 'ext', 'type', 'proper_filename' );
// We're able to validate images using GD
if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
// Attempt to figure out what type of image it actually is
$imgstats = @getimagesize( $file );
// If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
// This is a simplified array of MIMEs that getimagesize() can detect and their extensions
// You shouldn't need to use this filter, but it's here just in case
$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
) );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
$new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename )
$proper_filename = $new_filename; // Mark that it changed
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
extract( $wp_filetype );
}
}
}
// Let plugins try and validate other types of files
// Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
}
/**
* Retrieve list of allowed mime types and file extensions.
*
* @since 2.8.6
*
* @return array Array of mime types keyed by the file extension regex corresponding to those types.
*/
function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( 'upload_mimes', array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'bmp' => 'image/bmp',
'tif|tiff' => 'image/tiff',
'ico' => 'image/x-icon',
'asf|asx|wax|wmv|wmx' => 'video/asf',
'avi' => 'video/avi',
'divx' => 'video/divx',
'flv' => 'video/x-flv',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'txt|asc|c|cc|h' => 'text/plain',
'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'css' => 'text/css',
'htm|html' => 'text/html',
'mp3|m4a|m4b' => 'audio/mpeg',
'mp4|m4v' => 'video/mp4',
'ra|ram' => 'audio/x-realaudio',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
'ogv' => 'video/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/wma',
'mka' => 'audio/x-matroska',
'mkv' => 'video/x-matroska',
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'doc|docx' => 'application/msword',
'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docm|dotm' => 'application/vnd.ms-word',
'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'rar' => 'application/rar',
'7z' => 'application/x-7z-compressed',
'exe' => 'application/x-msdownload',
// openoffice formats
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
// wordperfect formats
'wp|wpd' => 'application/wordperfect',
) );
}
return $mimes;
}
/**
* Retrieve nonce action "Are you sure" message.
*
* The action is split by verb and noun. The action format is as follows:
* verb-action_extra. The verb is before the first dash and has the format of
* letters and no spaces and numbers. The noun is after the dash and before the
* underscore, if an underscore exists. The noun is also only letters.
*
* The filter will be called for any action, which is not defined by WordPress.
* You may use the filter for your plugin to explain nonce actions to the user,
* when they get the "Are you sure?" message. The filter is in the format of
* 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
* $noun replaced by the found noun. The two parameters that are given to the
* hook are the localized "Are you sure you want to do this?" message with the
* extra text (the text after the underscore).
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action Nonce action.
* @return string Are you sure message.
*/
function wp_explain_nonce( $action ) {
if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
$verb = $matches[1];
$noun = $matches[2];
$trans = array();
$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' );
$trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false );
$trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' );
$trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' );
$trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' );
$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' );
$trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' );
$trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' );
$trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
$trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false );
$trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' );
$trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' );
$trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false );
$trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false );
$trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' );
$trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' );
$trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' );
$trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' );
$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' );
$trans['upgrade']['plugin'] = array( __( 'Your attempt to update this plugin: “%s” has failed.' ), 'use_id' );
$trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false );
$trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' );
$trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' );
$trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false );
$trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false );
$trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false );
$trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false );
$trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
$trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' );
$trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' );
$trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' );
$trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
if ( isset( $trans[$verb][$noun] ) ) {
if ( !empty( $trans[$verb][$noun][1] ) ) {
$lookup = $trans[$verb][$noun][1];
if ( isset($trans[$verb][$noun][2]) )
$lookup_value = $trans[$verb][$noun][2];
$object = $matches[4];
if ( 'use_id' != $lookup ) {
if ( isset( $lookup_value ) )
$object = call_user_func( $lookup, $lookup_value, $object );
else
$object = call_user_func( $lookup, $object );
}
return sprintf( $trans[$verb][$noun][0], esc_html($object) );
} else {
return $trans[$verb][$noun][0];
}
}
return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
} else {
return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
}
}
/**
* Display "Are You Sure" message to confirm the action being taken.
*
* If the action has the nonce explain message, then it will be displayed along
* with the "Are you sure?" message.
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action The nonce action.
*/
function wp_nonce_ays( $action ) {
$title = __( 'WordPress Failure Notice' );
$html = esc_html( wp_explain_nonce( $action ) );
if ( 'log-out' == $action )
$html .= "" . sprintf( __( "Do you really want to log out?"), wp_logout_url() ); elseif ( wp_get_referer() ) $html .= "
" . __( 'Please try again.' ) . ""; wp_die( $html, $title, array('response' => 403) ); } /** * Kill WordPress execution and display HTML message with error message. * * This function complements the die() PHP function. The difference is that * HTML will be displayed to the user. It is recommended to use this function * only, when the execution should not continue any further. It is not * recommended to call this function very often and try to handle as many errors * as possible silently. * * @since 2.0.4 * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function wp_die( $message, $title = '', $args = array() ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) die('-1'); if ( function_exists( 'apply_filters' ) ) { $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); } else { $function = '_default_wp_die_handler'; } call_user_func( $function, $message, $title, $args ); } /** * Kill WordPress execution and display HTML message with error message. * * This is the default handler for wp_die if you want a custom one for your * site then you can overload using the wp_die_handler filter in wp_die * * @since 3.0.0 * @access private * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 500 ); $r = wp_parse_args($args, $defaults); $have_gettext = function_exists('__'); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( empty( $title ) ) { $error_data = $message->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['title'] ) ) $title = $error_data['title']; } $errors = $message->get_error_messages(); switch ( count( $errors ) ) : case 0 : $message = ''; break; case 1 : $message = "
{$errors[0]}
"; break; default : $message = "$message
"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { $back_text = $have_gettext? __('« Back') : '« Back'; $message .= "\n"; } if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : if ( !headers_sent() ) { status_header( $r['response'] ); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); } if ( empty($title) ) $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; $text_direction = 'ltr'; if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) $text_direction = 'rtl'; elseif ( function_exists( 'is_rtl' ) && is_rtl() ) $text_direction = 'rtl'; ?> >sys_get_temp_dir(), before finally defaulting to /tmp/
*
* In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
*
* @since 2.5.0
*
* @return string Writable temporary directory
*/
function get_temp_dir() {
static $temp;
if ( defined('WP_TEMP_DIR') )
return trailingslashit(WP_TEMP_DIR);
if ( $temp )
return trailingslashit($temp);
$temp = WP_CONTENT_DIR . '/';
if ( is_dir($temp) && @is_writable($temp) )
return $temp;
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_writable($temp) )
return trailingslashit($temp);
}
$temp = ini_get('upload_tmp_dir');
if ( is_dir($temp) && @is_writable($temp) )
return trailingslashit($temp);
$temp = '/tmp/';
return $temp;
}
/**
* Get an array containing the current upload directory's path and url.
*
* Checks the 'upload_path' option, which should be from the web root folder,
* and if it isn't empty it will be used. If it is empty, then the path will be
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
*
* The upload URL path is set either by the 'upload_url_path' option or by using
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
*
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
* the administration settings panel), then the time will be used. The format
* will be year first and then month.
*
* If the path couldn't be created, then an error will be returned with the key
* 'error' containing the error message. The error suggests that the parent
* directory is not writable by the server.
*
* On success, the returned array will have many indices:
* 'path' - base directory and sub directory or full path to upload directory.
* 'url' - base url and sub directory or absolute URL to upload directory.
* 'subdir' - sub directory if uploads use year/month folders option is on.
* 'basedir' - path without subdir.
* 'baseurl' - URL path without subdir.
* 'error' - set to false.
*
* @since 2.0.0
* @uses apply_filters() Calls 'upload_dir' on returned array.
*
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array See above for description.
*/
function wp_upload_dir( $time = null ) {
global $switched;
$siteurl = get_option( 'siteurl' );
$upload_path = get_option( 'upload_path' );
$upload_path = trim($upload_path);
$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
if ( empty($upload_path) ) {
$dir = WP_CONTENT_DIR . '/uploads';
} else {
$dir = $upload_path;
if ( 'wp-content/uploads' == $upload_path ) {
$dir = WP_CONTENT_DIR . '/uploads';
} elseif ( 0 !== strpos($dir, ABSPATH) ) {
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
$dir = path_join( ABSPATH, $dir );
}
}
if ( !$url = get_option( 'upload_url_path' ) ) {
if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
$url = WP_CONTENT_URL . '/uploads';
else
$url = trailingslashit( $siteurl ) . $upload_path;
}
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
$dir = ABSPATH . UPLOADS;
$url = trailingslashit( $siteurl ) . UPLOADS;
}
if ( is_multisite() && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
if ( defined( 'BLOGUPLOADDIR' ) )
$dir = untrailingslashit(BLOGUPLOADDIR);
$url = str_replace( UPLOADS, 'files', $url );
}
$bdir = $dir;
$burl = $url;
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
if ( !$time )
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
$dir .= $subdir;
$url .= $subdir;
$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
// Make sure we have an uploads dir
if ( ! wp_mkdir_p( $uploads['path'] ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
return array( 'error' => $message );
}
return $uploads;
}
/**
* Get a filename that is sanitized and unique for the given directory.
*
* If the filename is not unique, then a number will be added to the filename
* before the extension, and will continue adding numbers until the filename is
* unique.
*
* The callback is passed three parameters, the first one is the directory, the
* second is the filename, and the third is the extension.
*
* @since 2.5.0
*
* @param string $dir
* @param string $filename
* @param mixed $unique_filename_callback Callback.
* @return string New filename, if given wasn't unique.
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// sanitize the file name before we begin processing
$filename = sanitize_file_name($filename);
// separate the filename into a name and extension
$info = pathinfo($filename);
$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
$name = basename($filename, $ext);
// edge case: if file is named '.ext', treat as an empty name
if ( $name === $ext )
$name = '';
// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
} else {
$number = '';
// change '.ext' to lower case
if ( $ext && strtolower($ext) != $ext ) {
$ext2 = strtolower($ext);
$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
// check for both lower and upper case extension or image sub-sizes may be overwritten
while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
$new_number = $number + 1;
$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
$number = $new_number;
}
return $filename2;
}
while ( file_exists( $dir . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
}
return $filename;
}
/**
* Create a file in the upload folder with given content.
*
* If there is an error, then the key 'error' will exist with the error message.
* If success, then the key 'file' will have the unique file path, the 'url' key
* will have the link to the new file. and the 'error' key will be set to false.
*
* This function will not move an uploaded file to the upload folder. It will
* create a new file with the content in $bits parameter. If you move the upload
* file, read the content of the uploaded file, and then you can give the
* filename and content to this function, which will add it to the upload
* folder.
*
* The permissions will be set on the new file automatically by this function.
*
* @since 2.0.0
*
* @param string $name
* @param null $deprecated Never used. Set to null.
* @param mixed $bits File content
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
if ( !empty( $deprecated ) )
_deprecated_argument( __FUNCTION__, '2.0' );
if ( empty( $name ) )
return array( 'error' => __( 'Empty filename' ) );
$wp_filetype = wp_check_filetype( $name );
if ( !$wp_filetype['ext'] )
return array( 'error' => __( 'Invalid file type' ) );
$upload = wp_upload_dir( $time );
if ( $upload['error'] !== false )
return $upload;
$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
if ( !is_array( $upload_bits_error ) ) {
$upload[ 'error' ] = $upload_bits_error;
return $upload;
}
$filename = wp_unique_filename( $upload['path'], $name );
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
return array( 'error' => $message );
}
$ifp = @ fopen( $new_file, 'wb' );
if ( ! $ifp )
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
$stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
clearstatcache();
// Compute the URL
$url = $upload['url'] . "/$filename";
return array( 'file' => $new_file, 'url' => $url, 'error' => false );
}
/**
* Retrieve the file type based on the extension name.
*
* @package WordPress
* @since 2.5.0
* @uses apply_filters() Calls 'ext2type' hook on default supported types.
*
* @param string $ext The extension to search.
* @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
*/
function wp_ext2type( $ext ) {
$ext2type = apply_filters( 'ext2type', array(
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsb', 'xlsm' ),
'interactive' => array( 'key', 'ppt', 'pptx', 'pptm', 'odp', 'swf' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
));
foreach ( $ext2type as $type => $exts )
if ( in_array( $ext, $exts ) )
return $type;
}
/**
* Retrieve the file type from the file name.
*
* You can optionally define the mime array, if needed.
*
* @since 2.0.4
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Attempt to determine the real file type of a file.
* If unable to, the file name extension will be used to determine type.
*
* If it's determined that the extension does not match the file's real type,
* then the "proper_filename" value will be set with a proper filename and extension.
*
* Currently this function only supports validating images known to getimagesize().
*
* @since 3.0.0
*
* @param string $file Full path to the image.
* @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
*/
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
$proper_filename = false;
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) )
return compact( 'ext', 'type', 'proper_filename' );
// We're able to validate images using GD
if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
// Attempt to figure out what type of image it actually is
$imgstats = @getimagesize( $file );
// If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
// This is a simplified array of MIMEs that getimagesize() can detect and their extensions
// You shouldn't need to use this filter, but it's here just in case
$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
) );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
$new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename )
$proper_filename = $new_filename; // Mark that it changed
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
extract( $wp_filetype );
}
}
}
// Let plugins try and validate other types of files
// Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
}
/**
* Retrieve list of allowed mime types and file extensions.
*
* @since 2.8.6
*
* @return array Array of mime types keyed by the file extension regex corresponding to those types.
*/
function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( 'upload_mimes', array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'bmp' => 'image/bmp',
'tif|tiff' => 'image/tiff',
'ico' => 'image/x-icon',
'asf|asx|wax|wmv|wmx' => 'video/asf',
'avi' => 'video/avi',
'divx' => 'video/divx',
'flv' => 'video/x-flv',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'txt|asc|c|cc|h' => 'text/plain',
'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'css' => 'text/css',
'htm|html' => 'text/html',
'mp3|m4a|m4b' => 'audio/mpeg',
'mp4|m4v' => 'video/mp4',
'ra|ram' => 'audio/x-realaudio',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
'ogv' => 'video/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/wma',
'mka' => 'audio/x-matroska',
'mkv' => 'video/x-matroska',
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'doc|docx' => 'application/msword',
'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docm|dotm' => 'application/vnd.ms-word',
'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'exe' => 'application/x-msdownload',
// openoffice formats
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
// wordperfect formats
'wp|wpd' => 'application/wordperfect',
) );
}
return $mimes;
}
/**
* Retrieve nonce action "Are you sure" message.
*
* The action is split by verb and noun. The action format is as follows:
* verb-action_extra. The verb is before the first dash and has the format of
* letters and no spaces and numbers. The noun is after the dash and before the
* underscore, if an underscore exists. The noun is also only letters.
*
* The filter will be called for any action, which is not defined by WordPress.
* You may use the filter for your plugin to explain nonce actions to the user,
* when they get the "Are you sure?" message. The filter is in the format of
* 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
* $noun replaced by the found noun. The two parameters that are given to the
* hook are the localized "Are you sure you want to do this?" message with the
* extra text (the text after the underscore).
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action Nonce action.
* @return string Are you sure message.
*/
function wp_explain_nonce( $action ) {
if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
$verb = $matches[1];
$noun = $matches[2];
$trans = array();
$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' );
$trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false );
$trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' );
$trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' );
$trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' );
$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' );
$trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' );
$trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' );
$trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
$trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false );
$trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' );
$trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' );
$trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false );
$trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false );
$trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' );
$trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' );
$trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' );
$trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' );
$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' );
$trans['upgrade']['plugin'] = array( __( 'Your attempt to update this plugin: “%s” has failed.' ), 'use_id' );
$trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false );
$trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' );
$trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' );
$trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false );
$trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false );
$trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false );
$trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false );
$trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
$trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' );
$trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' );
$trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' );
$trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
if ( isset( $trans[$verb][$noun] ) ) {
if ( !empty( $trans[$verb][$noun][1] ) ) {
$lookup = $trans[$verb][$noun][1];
if ( isset($trans[$verb][$noun][2]) )
$lookup_value = $trans[$verb][$noun][2];
$object = $matches[4];
if ( 'use_id' != $lookup ) {
if ( isset( $lookup_value ) )
$object = call_user_func( $lookup, $lookup_value, $object );
else
$object = call_user_func( $lookup, $object );
}
return sprintf( $trans[$verb][$noun][0], esc_html($object) );
} else {
return $trans[$verb][$noun][0];
}
}
return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
} else {
return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
}
}
/**
* Display "Are You Sure" message to confirm the action being taken.
*
* If the action has the nonce explain message, then it will be displayed along
* with the "Are you sure?" message.
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action The nonce action.
*/
function wp_nonce_ays( $action ) {
$title = __( 'WordPress Failure Notice' );
$html = esc_html( wp_explain_nonce( $action ) );
if ( 'log-out' == $action )
$html .= "" . sprintf( __( "Do you really want to log out?"), wp_logout_url() ); elseif ( wp_get_referer() ) $html .= "
" . __( 'Please try again.' ) . ""; wp_die( $html, $title, array('response' => 403) ); } /** * Kill WordPress execution and display HTML message with error message. * * This function complements the die() PHP function. The difference is that * HTML will be displayed to the user. It is recommended to use this function * only, when the execution should not continue any further. It is not * recommended to call this function very often and try to handle as many errors * as possible siliently. * * @since 2.0.4 * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguements to control behaviour. */ function wp_die( $message, $title = '', $args = array() ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) die('-1'); if ( function_exists( 'apply_filters' ) ) { $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); } else { $function = '_default_wp_die_handler'; } call_user_func( $function, $message, $title, $args ); } /** * Kill WordPress execution and display HTML message with error message. * * This is the default handler for wp_die if you want a custom one for your * site then you can overload using the wp_die_handler filter in wp_die * * @since 3.0.0 * @access private * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguements to control behaviour. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 500 ); $r = wp_parse_args($args, $defaults); $have_gettext = function_exists('__'); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( empty( $title ) ) { $error_data = $message->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['title'] ) ) $title = $error_data['title']; } $errors = $message->get_error_messages(); switch ( count( $errors ) ) : case 0 : $message = ''; break; case 1 : $message = "
{$errors[0]}
"; break; default : $message = "$message
"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { $back_text = $have_gettext? __('« Back') : '« Back'; $message .= "\n"; } if ( defined( 'WP_SITEURL' ) && '' != WP_SITEURL ) $admin_dir = WP_SITEURL . '/wp-admin/'; elseif ( function_exists( 'get_bloginfo' ) && '' != get_bloginfo( 'wpurl' ) ) $admin_dir = get_bloginfo( 'wpurl' ) . '/wp-admin/'; elseif ( strpos( $_SERVER['PHP_SELF'], 'wp-admin' ) !== false ) $admin_dir = ''; else $admin_dir = 'wp-admin/'; if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : if ( !headers_sent() ) { status_header( $r['response'] ); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); } if ( empty($title) ) $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; $text_direction = 'ltr'; if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) $text_direction = 'rtl'; elseif ( function_exists( 'is_rtl' ) && is_rtl() ) $text_direction = 'rtl'; ?> >sys_get_temp_dir(), before finally defaulting to /tmp/
*
* In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
*
* @since 2.5.0
*
* @return string Writable temporary directory
*/
function get_temp_dir() {
static $temp;
if ( defined('WP_TEMP_DIR') )
return trailingslashit(WP_TEMP_DIR);
if ( $temp )
return trailingslashit($temp);
$temp = WP_CONTENT_DIR . '/';
if ( is_dir($temp) && @is_writable($temp) )
return $temp;
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_writable($temp) )
return trailingslashit($temp);
}
$temp = ini_get('upload_tmp_dir');
if ( is_dir($temp) && @is_writable($temp) )
return trailingslashit($temp);
$temp = '/tmp/';
return $temp;
}
/**
* Get an array containing the current upload directory's path and url.
*
* Checks the 'upload_path' option, which should be from the web root folder,
* and if it isn't empty it will be used. If it is empty, then the path will be
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
*
* The upload URL path is set either by the 'upload_url_path' option or by using
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
*
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
* the administration settings panel), then the time will be used. The format
* will be year first and then month.
*
* If the path couldn't be created, then an error will be returned with the key
* 'error' containing the error message. The error suggests that the parent
* directory is not writable by the server.
*
* On success, the returned array will have many indices:
* 'path' - base directory and sub directory or full path to upload directory.
* 'url' - base url and sub directory or absolute URL to upload directory.
* 'subdir' - sub directory if uploads use year/month folders option is on.
* 'basedir' - path without subdir.
* 'baseurl' - URL path without subdir.
* 'error' - set to false.
*
* @since 2.0.0
* @uses apply_filters() Calls 'upload_dir' on returned array.
*
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array See above for description.
*/
function wp_upload_dir( $time = null ) {
global $switched;
$siteurl = get_option( 'siteurl' );
$upload_path = get_option( 'upload_path' );
$upload_path = trim($upload_path);
$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
if ( empty($upload_path) ) {
$dir = WP_CONTENT_DIR . '/uploads';
} else {
$dir = $upload_path;
if ( 'wp-content/uploads' == $upload_path ) {
$dir = WP_CONTENT_DIR . '/uploads';
} elseif ( 0 !== strpos($dir, ABSPATH) ) {
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
$dir = path_join( ABSPATH, $dir );
}
}
if ( !$url = get_option( 'upload_url_path' ) ) {
if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
$url = WP_CONTENT_URL . '/uploads';
else
$url = trailingslashit( $siteurl ) . $upload_path;
}
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
$dir = ABSPATH . UPLOADS;
$url = trailingslashit( $siteurl ) . UPLOADS;
}
if ( is_multisite() && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
if ( defined( 'BLOGUPLOADDIR' ) )
$dir = untrailingslashit(BLOGUPLOADDIR);
$url = str_replace( UPLOADS, 'files', $url );
}
$bdir = $dir;
$burl = $url;
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
if ( !$time )
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
$dir .= $subdir;
$url .= $subdir;
$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
// Make sure we have an uploads dir
if ( ! wp_mkdir_p( $uploads['path'] ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
return array( 'error' => $message );
}
return $uploads;
}
/**
* Get a filename that is sanitized and unique for the given directory.
*
* If the filename is not unique, then a number will be added to the filename
* before the extension, and will continue adding numbers until the filename is
* unique.
*
* The callback is passed three parameters, the first one is the directory, the
* second is the filename, and the third is the extension.
*
* @since 2.5.0
*
* @param string $dir
* @param string $filename
* @param mixed $unique_filename_callback Callback.
* @return string New filename, if given wasn't unique.
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// sanitize the file name before we begin processing
$filename = sanitize_file_name($filename);
// separate the filename into a name and extension
$info = pathinfo($filename);
$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
$name = basename($filename, $ext);
// edge case: if file is named '.ext', treat as an empty name
if ( $name === $ext )
$name = '';
// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
} else {
$number = '';
// change '.ext' to lower case
if ( $ext && strtolower($ext) != $ext ) {
$ext2 = strtolower($ext);
$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
// check for both lower and upper case extension or image sub-sizes may be overwritten
while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
$new_number = $number + 1;
$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
$number = $new_number;
}
return $filename2;
}
while ( file_exists( $dir . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
}
return $filename;
}
/**
* Create a file in the upload folder with given content.
*
* If there is an error, then the key 'error' will exist with the error message.
* If success, then the key 'file' will have the unique file path, the 'url' key
* will have the link to the new file. and the 'error' key will be set to false.
*
* This function will not move an uploaded file to the upload folder. It will
* create a new file with the content in $bits parameter. If you move the upload
* file, read the content of the uploaded file, and then you can give the
* filename and content to this function, which will add it to the upload
* folder.
*
* The permissions will be set on the new file automatically by this function.
*
* @since 2.0.0
*
* @param string $name
* @param null $deprecated Never used. Set to null.
* @param mixed $bits File content
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
if ( !empty( $deprecated ) )
_deprecated_argument( __FUNCTION__, '2.0' );
if ( empty( $name ) )
return array( 'error' => __( 'Empty filename' ) );
$wp_filetype = wp_check_filetype( $name );
if ( !$wp_filetype['ext'] )
return array( 'error' => __( 'Invalid file type' ) );
$upload = wp_upload_dir( $time );
if ( $upload['error'] !== false )
return $upload;
$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
if ( !is_array( $upload_bits_error ) ) {
$upload[ 'error' ] = $upload_bits_error;
return $upload;
}
$filename = wp_unique_filename( $upload['path'], $name );
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
return array( 'error' => $message );
}
$ifp = @ fopen( $new_file, 'wb' );
if ( ! $ifp )
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
$stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
clearstatcache();
// Compute the URL
$url = $upload['url'] . "/$filename";
return array( 'file' => $new_file, 'url' => $url, 'error' => false );
}
/**
* Retrieve the file type based on the extension name.
*
* @package WordPress
* @since 2.5.0
* @uses apply_filters() Calls 'ext2type' hook on default supported types.
*
* @param string $ext The extension to search.
* @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
*/
function wp_ext2type( $ext ) {
$ext2type = apply_filters( 'ext2type', array(
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsb', 'xlsm' ),
'interactive' => array( 'key', 'ppt', 'pptx', 'pptm', 'odp', 'swf' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
));
foreach ( $ext2type as $type => $exts )
if ( in_array( $ext, $exts ) )
return $type;
}
/**
* Retrieve the file type from the file name.
*
* You can optionally define the mime array, if needed.
*
* @since 2.0.4
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Attempt to determine the real file type of a file.
* If unable to, the file name extension will be used to determine type.
*
* If it's determined that the extension does not match the file's real type,
* then the "proper_filename" value will be set with a proper filename and extension.
*
* Currently this function only supports validating images known to getimagesize().
*
* @since 3.0.0
*
* @param string $file Full path to the image.
* @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
*/
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
$proper_filename = false;
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) )
return compact( 'ext', 'type', 'proper_filename' );
// We're able to validate images using GD
if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
// Attempt to figure out what type of image it actually is
$imgstats = @getimagesize( $file );
// If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
// This is a simplified array of MIMEs that getimagesize() can detect and their extensions
// You shouldn't need to use this filter, but it's here just in case
$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
) );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
$new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename )
$proper_filename = $new_filename; // Mark that it changed
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
extract( $wp_filetype );
}
}
}
// Let plugins try and validate other types of files
// Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
}
/**
* Retrieve list of allowed mime types and file extensions.
*
* @since 2.8.6
*
* @return array Array of mime types keyed by the file extension regex corresponding to those types.
*/
function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( 'upload_mimes', array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'bmp' => 'image/bmp',
'tif|tiff' => 'image/tiff',
'ico' => 'image/x-icon',
'asf|asx|wax|wmv|wmx' => 'video/asf',
'avi' => 'video/avi',
'divx' => 'video/divx',
'flv' => 'video/x-flv',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'txt|asc|c|cc|h' => 'text/plain',
'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'css' => 'text/css',
'htm|html' => 'text/html',
'mp3|m4a|m4b' => 'audio/mpeg',
'mp4|m4v' => 'video/mp4',
'ra|ram' => 'audio/x-realaudio',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
'ogv' => 'video/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/wma',
'mka' => 'audio/x-matroska',
'mkv' => 'video/x-matroska',
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'doc|docx' => 'application/msword',
'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docm|dotm' => 'application/vnd.ms-word',
'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'rar' => 'application/rar',
'7z' => 'application/x-7z-compressed',
'exe' => 'application/x-msdownload',
// openoffice formats
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
// wordperfect formats
'wp|wpd' => 'application/wordperfect',
) );
}
return $mimes;
}
/**
* Retrieve nonce action "Are you sure" message.
*
* The action is split by verb and noun. The action format is as follows:
* verb-action_extra. The verb is before the first dash and has the format of
* letters and no spaces and numbers. The noun is after the dash and before the
* underscore, if an underscore exists. The noun is also only letters.
*
* The filter will be called for any action, which is not defined by WordPress.
* You may use the filter for your plugin to explain nonce actions to the user,
* when they get the "Are you sure?" message. The filter is in the format of
* 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
* $noun replaced by the found noun. The two parameters that are given to the
* hook are the localized "Are you sure you want to do this?" message with the
* extra text (the text after the underscore).
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action Nonce action.
* @return string Are you sure message.
*/
function wp_explain_nonce( $action ) {
if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
$verb = $matches[1];
$noun = $matches[2];
$trans = array();
$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' );
$trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false );
$trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' );
$trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' );
$trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' );
$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' );
$trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' );
$trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' );
$trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
$trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false );
$trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' );
$trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' );
$trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false );
$trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false );
$trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' );
$trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' );
$trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' );
$trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' );
$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' );
$trans['upgrade']['plugin'] = array( __( 'Your attempt to update this plugin: “%s” has failed.' ), 'use_id' );
$trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false );
$trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' );
$trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' );
$trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false );
$trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false );
$trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false );
$trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false );
$trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
$trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' );
$trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' );
$trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' );
$trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
if ( isset( $trans[$verb][$noun] ) ) {
if ( !empty( $trans[$verb][$noun][1] ) ) {
$lookup = $trans[$verb][$noun][1];
if ( isset($trans[$verb][$noun][2]) )
$lookup_value = $trans[$verb][$noun][2];
$object = $matches[4];
if ( 'use_id' != $lookup ) {
if ( isset( $lookup_value ) )
$object = call_user_func( $lookup, $lookup_value, $object );
else
$object = call_user_func( $lookup, $object );
}
return sprintf( $trans[$verb][$noun][0], esc_html($object) );
} else {
return $trans[$verb][$noun][0];
}
}
return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
} else {
return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
}
}
/**
* Display "Are You Sure" message to confirm the action being taken.
*
* If the action has the nonce explain message, then it will be displayed along
* with the "Are you sure?" message.
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action The nonce action.
*/
function wp_nonce_ays( $action ) {
$title = __( 'WordPress Failure Notice' );
$html = esc_html( wp_explain_nonce( $action ) );
if ( 'log-out' == $action )
$html .= "" . sprintf( __( "Do you really want to log out?"), wp_logout_url() ); elseif ( wp_get_referer() ) $html .= "
" . __( 'Please try again.' ) . ""; wp_die( $html, $title, array('response' => 403) ); } /** * Kill WordPress execution and display HTML message with error message. * * This function complements the die() PHP function. The difference is that * HTML will be displayed to the user. It is recommended to use this function * only, when the execution should not continue any further. It is not * recommended to call this function very often and try to handle as many errors * as possible silently. * * @since 2.0.4 * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function wp_die( $message, $title = '', $args = array() ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) die('-1'); if ( function_exists( 'apply_filters' ) ) { $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); } else { $function = '_default_wp_die_handler'; } call_user_func( $function, $message, $title, $args ); } /** * Kill WordPress execution and display HTML message with error message. * * This is the default handler for wp_die if you want a custom one for your * site then you can overload using the wp_die_handler filter in wp_die * * @since 3.0.0 * @access private * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 500 ); $r = wp_parse_args($args, $defaults); $have_gettext = function_exists('__'); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( empty( $title ) ) { $error_data = $message->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['title'] ) ) $title = $error_data['title']; } $errors = $message->get_error_messages(); switch ( count( $errors ) ) : case 0 : $message = ''; break; case 1 : $message = "
{$errors[0]}
"; break; default : $message = "$message
"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { $back_text = $have_gettext? __('« Back') : '« Back'; $message .= "\n"; } if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : if ( !headers_sent() ) { status_header( $r['response'] ); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); } if ( empty($title) ) $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; $text_direction = 'ltr'; if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) $text_direction = 'rtl'; elseif ( function_exists( 'is_rtl' ) && is_rtl() ) $text_direction = 'rtl'; ?> >sys_get_temp_dir(), before finally defaulting to /tmp/
*
* In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
*
* @since 2.5.0
*
* @return string Writable temporary directory
*/
function get_temp_dir() {
static $temp;
if ( defined('WP_TEMP_DIR') )
return trailingslashit(WP_TEMP_DIR);
if ( $temp )
return trailingslashit($temp);
$temp = WP_CONTENT_DIR . '/';
if ( is_dir($temp) && @is_writable($temp) )
return $temp;
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_writable($temp) )
return trailingslashit($temp);
}
$temp = ini_get('upload_tmp_dir');
if ( is_dir($temp) && @is_writable($temp) )
return trailingslashit($temp);
$temp = '/tmp/';
return $temp;
}
/**
* Get an array containing the current upload directory's path and url.
*
* Checks the 'upload_path' option, which should be from the web root folder,
* and if it isn't empty it will be used. If it is empty, then the path will be
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
*
* The upload URL path is set either by the 'upload_url_path' option or by using
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
*
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
* the administration settings panel), then the time will be used. The format
* will be year first and then month.
*
* If the path couldn't be created, then an error will be returned with the key
* 'error' containing the error message. The error suggests that the parent
* directory is not writable by the server.
*
* On success, the returned array will have many indices:
* 'path' - base directory and sub directory or full path to upload directory.
* 'url' - base url and sub directory or absolute URL to upload directory.
* 'subdir' - sub directory if uploads use year/month folders option is on.
* 'basedir' - path without subdir.
* 'baseurl' - URL path without subdir.
* 'error' - set to false.
*
* @since 2.0.0
* @uses apply_filters() Calls 'upload_dir' on returned array.
*
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array See above for description.
*/
function wp_upload_dir( $time = null ) {
global $switched;
$siteurl = get_option( 'siteurl' );
$upload_path = get_option( 'upload_path' );
$upload_path = trim($upload_path);
$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
if ( empty($upload_path) ) {
$dir = WP_CONTENT_DIR . '/uploads';
} else {
$dir = $upload_path;
if ( 'wp-content/uploads' == $upload_path ) {
$dir = WP_CONTENT_DIR . '/uploads';
} elseif ( 0 !== strpos($dir, ABSPATH) ) {
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
$dir = path_join( ABSPATH, $dir );
}
}
if ( !$url = get_option( 'upload_url_path' ) ) {
if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
$url = WP_CONTENT_URL . '/uploads';
else
$url = trailingslashit( $siteurl ) . $upload_path;
}
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
$dir = ABSPATH . UPLOADS;
$url = trailingslashit( $siteurl ) . UPLOADS;
}
if ( is_multisite() && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
if ( defined( 'BLOGUPLOADDIR' ) )
$dir = untrailingslashit(BLOGUPLOADDIR);
$url = str_replace( UPLOADS, 'files', $url );
}
$bdir = $dir;
$burl = $url;
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
if ( !$time )
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
$dir .= $subdir;
$url .= $subdir;
$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
// Make sure we have an uploads dir
if ( ! wp_mkdir_p( $uploads['path'] ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
return array( 'error' => $message );
}
return $uploads;
}
/**
* Get a filename that is sanitized and unique for the given directory.
*
* If the filename is not unique, then a number will be added to the filename
* before the extension, and will continue adding numbers until the filename is
* unique.
*
* The callback is passed three parameters, the first one is the directory, the
* second is the filename, and the third is the extension.
*
* @since 2.5.0
*
* @param string $dir
* @param string $filename
* @param mixed $unique_filename_callback Callback.
* @return string New filename, if given wasn't unique.
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// sanitize the file name before we begin processing
$filename = sanitize_file_name($filename);
// separate the filename into a name and extension
$info = pathinfo($filename);
$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
$name = basename($filename, $ext);
// edge case: if file is named '.ext', treat as an empty name
if ( $name === $ext )
$name = '';
// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
} else {
$number = '';
// change '.ext' to lower case
if ( $ext && strtolower($ext) != $ext ) {
$ext2 = strtolower($ext);
$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
// check for both lower and upper case extension or image sub-sizes may be overwritten
while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
$new_number = $number + 1;
$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
$number = $new_number;
}
return $filename2;
}
while ( file_exists( $dir . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
}
return $filename;
}
/**
* Create a file in the upload folder with given content.
*
* If there is an error, then the key 'error' will exist with the error message.
* If success, then the key 'file' will have the unique file path, the 'url' key
* will have the link to the new file. and the 'error' key will be set to false.
*
* This function will not move an uploaded file to the upload folder. It will
* create a new file with the content in $bits parameter. If you move the upload
* file, read the content of the uploaded file, and then you can give the
* filename and content to this function, which will add it to the upload
* folder.
*
* The permissions will be set on the new file automatically by this function.
*
* @since 2.0.0
*
* @param string $name
* @param null $deprecated Never used. Set to null.
* @param mixed $bits File content
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
if ( !empty( $deprecated ) )
_deprecated_argument( __FUNCTION__, '2.0' );
if ( empty( $name ) )
return array( 'error' => __( 'Empty filename' ) );
$wp_filetype = wp_check_filetype( $name );
if ( !$wp_filetype['ext'] )
return array( 'error' => __( 'Invalid file type' ) );
$upload = wp_upload_dir( $time );
if ( $upload['error'] !== false )
return $upload;
$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
if ( !is_array( $upload_bits_error ) ) {
$upload[ 'error' ] = $upload_bits_error;
return $upload;
}
$filename = wp_unique_filename( $upload['path'], $name );
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
return array( 'error' => $message );
}
$ifp = @ fopen( $new_file, 'wb' );
if ( ! $ifp )
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
$stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
clearstatcache();
// Compute the URL
$url = $upload['url'] . "/$filename";
return array( 'file' => $new_file, 'url' => $url, 'error' => false );
}
/**
* Retrieve the file type based on the extension name.
*
* @package WordPress
* @since 2.5.0
* @uses apply_filters() Calls 'ext2type' hook on default supported types.
*
* @param string $ext The extension to search.
* @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
*/
function wp_ext2type( $ext ) {
$ext2type = apply_filters( 'ext2type', array(
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsb', 'xlsm' ),
'interactive' => array( 'key', 'ppt', 'pptx', 'pptm', 'odp', 'swf' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
));
foreach ( $ext2type as $type => $exts )
if ( in_array( $ext, $exts ) )
return $type;
}
/**
* Retrieve the file type from the file name.
*
* You can optionally define the mime array, if needed.
*
* @since 2.0.4
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Attempt to determine the real file type of a file.
* If unable to, the file name extension will be used to determine type.
*
* If it's determined that the extension does not match the file's real type,
* then the "proper_filename" value will be set with a proper filename and extension.
*
* Currently this function only supports validating images known to getimagesize().
*
* @since 3.0.0
*
* @param string $file Full path to the image.
* @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
*/
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
$proper_filename = false;
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) )
return compact( 'ext', 'type', 'proper_filename' );
// We're able to validate images using GD
if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
// Attempt to figure out what type of image it actually is
$imgstats = @getimagesize( $file );
// If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
// This is a simplified array of MIMEs that getimagesize() can detect and their extensions
// You shouldn't need to use this filter, but it's here just in case
$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
) );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
$new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename )
$proper_filename = $new_filename; // Mark that it changed
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
extract( $wp_filetype );
}
}
}
// Let plugins try and validate other types of files
// Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
}
/**
* Retrieve list of allowed mime types and file extensions.
*
* @since 2.8.6
*
* @return array Array of mime types keyed by the file extension regex corresponding to those types.
*/
function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( 'upload_mimes', array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'bmp' => 'image/bmp',
'tif|tiff' => 'image/tiff',
'ico' => 'image/x-icon',
'asf|asx|wax|wmv|wmx' => 'video/asf',
'avi' => 'video/avi',
'divx' => 'video/divx',
'flv' => 'video/x-flv',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'txt|asc|c|cc|h' => 'text/plain',
'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'css' => 'text/css',
'htm|html' => 'text/html',
'mp3|m4a|m4b' => 'audio/mpeg',
'mp4|m4v' => 'video/mp4',
'ra|ram' => 'audio/x-realaudio',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
'ogv' => 'video/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/wma',
'mka' => 'audio/x-matroska',
'mkv' => 'video/x-matroska',
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'doc|docx' => 'application/msword',
'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docm|dotm' => 'application/vnd.ms-word',
'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'rar' => 'application/rar',
'7z' => 'application/x-7z-compressed',
'exe' => 'application/x-msdownload',
// openoffice formats
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
// wordperfect formats
'wp|wpd' => 'application/wordperfect',
) );
}
return $mimes;
}
/**
* Retrieve nonce action "Are you sure" message.
*
* The action is split by verb and noun. The action format is as follows:
* verb-action_extra. The verb is before the first dash and has the format of
* letters and no spaces and numbers. The noun is after the dash and before the
* underscore, if an underscore exists. The noun is also only letters.
*
* The filter will be called for any action, which is not defined by WordPress.
* You may use the filter for your plugin to explain nonce actions to the user,
* when they get the "Are you sure?" message. The filter is in the format of
* 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
* $noun replaced by the found noun. The two parameters that are given to the
* hook are the localized "Are you sure you want to do this?" message with the
* extra text (the text after the underscore).
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action Nonce action.
* @return string Are you sure message.
*/
function wp_explain_nonce( $action ) {
if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
$verb = $matches[1];
$noun = $matches[2];
$trans = array();
$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' );
$trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false );
$trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' );
$trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' );
$trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' );
$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' );
$trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' );
$trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' );
$trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
$trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false );
$trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' );
$trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' );
$trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false );
$trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false );
$trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' );
$trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' );
$trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' );
$trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' );
$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' );
$trans['upgrade']['plugin'] = array( __( 'Your attempt to update this plugin: “%s” has failed.' ), 'use_id' );
$trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false );
$trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' );
$trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' );
$trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false );
$trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false );
$trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false );
$trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false );
$trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
$trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' );
$trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' );
$trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' );
$trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
if ( isset( $trans[$verb][$noun] ) ) {
if ( !empty( $trans[$verb][$noun][1] ) ) {
$lookup = $trans[$verb][$noun][1];
if ( isset($trans[$verb][$noun][2]) )
$lookup_value = $trans[$verb][$noun][2];
$object = $matches[4];
if ( 'use_id' != $lookup ) {
if ( isset( $lookup_value ) )
$object = call_user_func( $lookup, $lookup_value, $object );
else
$object = call_user_func( $lookup, $object );
}
return sprintf( $trans[$verb][$noun][0], esc_html($object) );
} else {
return $trans[$verb][$noun][0];
}
}
return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
} else {
return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
}
}
/**
* Display "Are You Sure" message to confirm the action being taken.
*
* If the action has the nonce explain message, then it will be displayed along
* with the "Are you sure?" message.
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action The nonce action.
*/
function wp_nonce_ays( $action ) {
$title = __( 'WordPress Failure Notice' );
$html = esc_html( wp_explain_nonce( $action ) );
if ( 'log-out' == $action )
$html .= "" . sprintf( __( "Do you really want to log out?"), wp_logout_url() ); elseif ( wp_get_referer() ) $html .= "
" . __( 'Please try again.' ) . ""; wp_die( $html, $title, array('response' => 403) ); } /** * Kill WordPress execution and display HTML message with error message. * * This function complements the die() PHP function. The difference is that * HTML will be displayed to the user. It is recommended to use this function * only, when the execution should not continue any further. It is not * recommended to call this function very often and try to handle as many errors * as possible silently. * * @since 2.0.4 * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function wp_die( $message, $title = '', $args = array() ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) die('-1'); if ( function_exists( 'apply_filters' ) ) { $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); } else { $function = '_default_wp_die_handler'; } call_user_func( $function, $message, $title, $args ); } /** * Kill WordPress execution and display HTML message with error message. * * This is the default handler for wp_die if you want a custom one for your * site then you can overload using the wp_die_handler filter in wp_die * * @since 3.0.0 * @access private * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 500 ); $r = wp_parse_args($args, $defaults); $have_gettext = function_exists('__'); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( empty( $title ) ) { $error_data = $message->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['title'] ) ) $title = $error_data['title']; } $errors = $message->get_error_messages(); switch ( count( $errors ) ) : case 0 : $message = ''; break; case 1 : $message = "
{$errors[0]}
"; break; default : $message = "$message
"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { $back_text = $have_gettext? __('« Back') : '« Back'; $message .= "\n"; } if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : if ( !headers_sent() ) { status_header( $r['response'] ); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); } if ( empty($title) ) $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; $text_direction = 'ltr'; if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) $text_direction = 'rtl'; elseif ( function_exists( 'is_rtl' ) && is_rtl() ) $text_direction = 'rtl'; ?> >sys_get_temp_dir(), before finally defaulting to /tmp/
*
* In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
*
* @since 2.5.0
*
* @return string Writable temporary directory
*/
function get_temp_dir() {
static $temp;
if ( defined('WP_TEMP_DIR') )
return trailingslashit(WP_TEMP_DIR);
if ( $temp )
return trailingslashit($temp);
$temp = WP_CONTENT_DIR . '/';
if ( is_dir($temp) && @is_writable($temp) )
return $temp;
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_writable($temp) )
return trailingslashit($temp);
}
$temp = ini_get('upload_tmp_dir');
if ( is_dir($temp) && @is_writable($temp) )
return trailingslashit($temp);
$temp = '/tmp/';
return $temp;
}
/**
* Get an array containing the current upload directory's path and url.
*
* Checks the 'upload_path' option, which should be from the web root folder,
* and if it isn't empty it will be used. If it is empty, then the path will be
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
*
* The upload URL path is set either by the 'upload_url_path' option or by using
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
*
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
* the administration settings panel), then the time will be used. The format
* will be year first and then month.
*
* If the path couldn't be created, then an error will be returned with the key
* 'error' containing the error message. The error suggests that the parent
* directory is not writable by the server.
*
* On success, the returned array will have many indices:
* 'path' - base directory and sub directory or full path to upload directory.
* 'url' - base url and sub directory or absolute URL to upload directory.
* 'subdir' - sub directory if uploads use year/month folders option is on.
* 'basedir' - path without subdir.
* 'baseurl' - URL path without subdir.
* 'error' - set to false.
*
* @since 2.0.0
* @uses apply_filters() Calls 'upload_dir' on returned array.
*
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array See above for description.
*/
function wp_upload_dir( $time = null ) {
global $switched;
$siteurl = get_option( 'siteurl' );
$upload_path = get_option( 'upload_path' );
$upload_path = trim($upload_path);
$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
if ( empty($upload_path) ) {
$dir = WP_CONTENT_DIR . '/uploads';
} else {
$dir = $upload_path;
if ( 'wp-content/uploads' == $upload_path ) {
$dir = WP_CONTENT_DIR . '/uploads';
} elseif ( 0 !== strpos($dir, ABSPATH) ) {
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
$dir = path_join( ABSPATH, $dir );
}
}
if ( !$url = get_option( 'upload_url_path' ) ) {
if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
$url = WP_CONTENT_URL . '/uploads';
else
$url = trailingslashit( $siteurl ) . $upload_path;
}
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
$dir = ABSPATH . UPLOADS;
$url = trailingslashit( $siteurl ) . UPLOADS;
}
if ( is_multisite() && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
if ( defined( 'BLOGUPLOADDIR' ) )
$dir = untrailingslashit(BLOGUPLOADDIR);
$url = str_replace( UPLOADS, 'files', $url );
}
$bdir = $dir;
$burl = $url;
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
if ( !$time )
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
$dir .= $subdir;
$url .= $subdir;
$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
// Make sure we have an uploads dir
if ( ! wp_mkdir_p( $uploads['path'] ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
return array( 'error' => $message );
}
return $uploads;
}
/**
* Get a filename that is sanitized and unique for the given directory.
*
* If the filename is not unique, then a number will be added to the filename
* before the extension, and will continue adding numbers until the filename is
* unique.
*
* The callback is passed three parameters, the first one is the directory, the
* second is the filename, and the third is the extension.
*
* @since 2.5.0
*
* @param string $dir
* @param string $filename
* @param mixed $unique_filename_callback Callback.
* @return string New filename, if given wasn't unique.
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// sanitize the file name before we begin processing
$filename = sanitize_file_name($filename);
// separate the filename into a name and extension
$info = pathinfo($filename);
$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
$name = basename($filename, $ext);
// edge case: if file is named '.ext', treat as an empty name
if ( $name === $ext )
$name = '';
// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
} else {
$number = '';
// change '.ext' to lower case
if ( $ext && strtolower($ext) != $ext ) {
$ext2 = strtolower($ext);
$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
// check for both lower and upper case extension or image sub-sizes may be overwritten
while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
$new_number = $number + 1;
$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
$number = $new_number;
}
return $filename2;
}
while ( file_exists( $dir . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
}
return $filename;
}
/**
* Create a file in the upload folder with given content.
*
* If there is an error, then the key 'error' will exist with the error message.
* If success, then the key 'file' will have the unique file path, the 'url' key
* will have the link to the new file. and the 'error' key will be set to false.
*
* This function will not move an uploaded file to the upload folder. It will
* create a new file with the content in $bits parameter. If you move the upload
* file, read the content of the uploaded file, and then you can give the
* filename and content to this function, which will add it to the upload
* folder.
*
* The permissions will be set on the new file automatically by this function.
*
* @since 2.0.0
*
* @param string $name
* @param null $deprecated Never used. Set to null.
* @param mixed $bits File content
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
if ( !empty( $deprecated ) )
_deprecated_argument( __FUNCTION__, '2.0' );
if ( empty( $name ) )
return array( 'error' => __( 'Empty filename' ) );
$wp_filetype = wp_check_filetype( $name );
if ( !$wp_filetype['ext'] )
return array( 'error' => __( 'Invalid file type' ) );
$upload = wp_upload_dir( $time );
if ( $upload['error'] !== false )
return $upload;
$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
if ( !is_array( $upload_bits_error ) ) {
$upload[ 'error' ] = $upload_bits_error;
return $upload;
}
$filename = wp_unique_filename( $upload['path'], $name );
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
return array( 'error' => $message );
}
$ifp = @ fopen( $new_file, 'wb' );
if ( ! $ifp )
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
$stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
clearstatcache();
// Compute the URL
$url = $upload['url'] . "/$filename";
return array( 'file' => $new_file, 'url' => $url, 'error' => false );
}
/**
* Retrieve the file type based on the extension name.
*
* @package WordPress
* @since 2.5.0
* @uses apply_filters() Calls 'ext2type' hook on default supported types.
*
* @param string $ext The extension to search.
* @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
*/
function wp_ext2type( $ext ) {
$ext2type = apply_filters( 'ext2type', array(
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsb', 'xlsm' ),
'interactive' => array( 'key', 'ppt', 'pptx', 'pptm', 'odp', 'swf' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
));
foreach ( $ext2type as $type => $exts )
if ( in_array( $ext, $exts ) )
return $type;
}
/**
* Retrieve the file type from the file name.
*
* You can optionally define the mime array, if needed.
*
* @since 2.0.4
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Attempt to determine the real file type of a file.
* If unable to, the file name extension will be used to determine type.
*
* If it's determined that the extension does not match the file's real type,
* then the "proper_filename" value will be set with a proper filename and extension.
*
* Currently this function only supports validating images known to getimagesize().
*
* @since 3.0.0
*
* @param string $file Full path to the image.
* @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
*/
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
$proper_filename = false;
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) )
return compact( 'ext', 'type', 'proper_filename' );
// We're able to validate images using GD
if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
// Attempt to figure out what type of image it actually is
$imgstats = @getimagesize( $file );
// If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
// This is a simplified array of MIMEs that getimagesize() can detect and their extensions
// You shouldn't need to use this filter, but it's here just in case
$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
) );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
$new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename )
$proper_filename = $new_filename; // Mark that it changed
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
extract( $wp_filetype );
}
}
}
// Let plugins try and validate other types of files
// Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
}
/**
* Retrieve list of allowed mime types and file extensions.
*
* @since 2.8.6
*
* @return array Array of mime types keyed by the file extension regex corresponding to those types.
*/
function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( 'upload_mimes', array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'bmp' => 'image/bmp',
'tif|tiff' => 'image/tiff',
'ico' => 'image/x-icon',
'asf|asx|wax|wmv|wmx' => 'video/asf',
'avi' => 'video/avi',
'divx' => 'video/divx',
'flv' => 'video/x-flv',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'txt|asc|c|cc|h' => 'text/plain',
'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'css' => 'text/css',
'htm|html' => 'text/html',
'mp3|m4a|m4b' => 'audio/mpeg',
'mp4|m4v' => 'video/mp4',
'ra|ram' => 'audio/x-realaudio',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
'ogv' => 'video/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/wma',
'mka' => 'audio/x-matroska',
'mkv' => 'video/x-matroska',
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'doc|docx' => 'application/msword',
'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docm|dotm' => 'application/vnd.ms-word',
'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'rar' => 'application/rar',
'7z' => 'application/x-7z-compressed',
'exe' => 'application/x-msdownload',
// openoffice formats
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
// wordperfect formats
'wp|wpd' => 'application/wordperfect',
) );
}
return $mimes;
}
/**
* Retrieve nonce action "Are you sure" message.
*
* The action is split by verb and noun. The action format is as follows:
* verb-action_extra. The verb is before the first dash and has the format of
* letters and no spaces and numbers. The noun is after the dash and before the
* underscore, if an underscore exists. The noun is also only letters.
*
* The filter will be called for any action, which is not defined by WordPress.
* You may use the filter for your plugin to explain nonce actions to the user,
* when they get the "Are you sure?" message. The filter is in the format of
* 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
* $noun replaced by the found noun. The two parameters that are given to the
* hook are the localized "Are you sure you want to do this?" message with the
* extra text (the text after the underscore).
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action Nonce action.
* @return string Are you sure message.
*/
function wp_explain_nonce( $action ) {
if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
$verb = $matches[1];
$noun = $matches[2];
$trans = array();
$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' );
$trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false );
$trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' );
$trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' );
$trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' );
$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' );
$trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' );
$trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' );
$trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
$trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false );
$trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' );
$trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' );
$trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false );
$trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false );
$trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' );
$trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' );
$trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' );
$trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' );
$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' );
$trans['upgrade']['plugin'] = array( __( 'Your attempt to update this plugin: “%s” has failed.' ), 'use_id' );
$trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false );
$trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' );
$trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' );
$trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false );
$trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false );
$trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false );
$trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false );
$trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
$trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' );
$trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' );
$trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' );
$trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
if ( isset( $trans[$verb][$noun] ) ) {
if ( !empty( $trans[$verb][$noun][1] ) ) {
$lookup = $trans[$verb][$noun][1];
if ( isset($trans[$verb][$noun][2]) )
$lookup_value = $trans[$verb][$noun][2];
$object = $matches[4];
if ( 'use_id' != $lookup ) {
if ( isset( $lookup_value ) )
$object = call_user_func( $lookup, $lookup_value, $object );
else
$object = call_user_func( $lookup, $object );
}
return sprintf( $trans[$verb][$noun][0], esc_html($object) );
} else {
return $trans[$verb][$noun][0];
}
}
return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
} else {
return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
}
}
/**
* Display "Are You Sure" message to confirm the action being taken.
*
* If the action has the nonce explain message, then it will be displayed along
* with the "Are you sure?" message.
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action The nonce action.
*/
function wp_nonce_ays( $action ) {
$title = __( 'WordPress Failure Notice' );
$html = esc_html( wp_explain_nonce( $action ) );
if ( 'log-out' == $action )
$html .= "" . sprintf( __( "Do you really want to log out?"), wp_logout_url() ); elseif ( wp_get_referer() ) $html .= "
" . __( 'Please try again.' ) . ""; wp_die( $html, $title, array('response' => 403) ); } /** * Kill WordPress execution and display HTML message with error message. * * This function complements the die() PHP function. The difference is that * HTML will be displayed to the user. It is recommended to use this function * only, when the execution should not continue any further. It is not * recommended to call this function very often and try to handle as many errors * as possible silently. * * @since 2.0.4 * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function wp_die( $message, $title = '', $args = array() ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) die('-1'); if ( function_exists( 'apply_filters' ) ) { $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); } else { $function = '_default_wp_die_handler'; } call_user_func( $function, $message, $title, $args ); } /** * Kill WordPress execution and display HTML message with error message. * * This is the default handler for wp_die if you want a custom one for your * site then you can overload using the wp_die_handler filter in wp_die * * @since 3.0.0 * @access private * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 500 ); $r = wp_parse_args($args, $defaults); $have_gettext = function_exists('__'); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( empty( $title ) ) { $error_data = $message->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['title'] ) ) $title = $error_data['title']; } $errors = $message->get_error_messages(); switch ( count( $errors ) ) : case 0 : $message = ''; break; case 1 : $message = "
{$errors[0]}
"; break; default : $message = "$message
"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { $back_text = $have_gettext? __('« Back') : '« Back'; $message .= "\n"; } if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : if ( !headers_sent() ) { status_header( $r['response'] ); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); } if ( empty($title) ) $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; $text_direction = 'ltr'; if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) $text_direction = 'rtl'; elseif ( function_exists( 'is_rtl' ) && is_rtl() ) $text_direction = 'rtl'; ?> >sys_get_temp_dir(), before finally defaulting to /tmp/
*
* In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
*
* @since 2.5.0
*
* @return string Writable temporary directory
*/
function get_temp_dir() {
static $temp;
if ( defined('WP_TEMP_DIR') )
return trailingslashit(WP_TEMP_DIR);
if ( $temp )
return trailingslashit($temp);
$temp = WP_CONTENT_DIR . '/';
if ( is_dir($temp) && @is_writable($temp) )
return $temp;
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_writable($temp) )
return trailingslashit($temp);
}
$temp = ini_get('upload_tmp_dir');
if ( is_dir($temp) && @is_writable($temp) )
return trailingslashit($temp);
$temp = '/tmp/';
return $temp;
}
/**
* Get an array containing the current upload directory's path and url.
*
* Checks the 'upload_path' option, which should be from the web root folder,
* and if it isn't empty it will be used. If it is empty, then the path will be
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
*
* The upload URL path is set either by the 'upload_url_path' option or by using
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
*
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
* the administration settings panel), then the time will be used. The format
* will be year first and then month.
*
* If the path couldn't be created, then an error will be returned with the key
* 'error' containing the error message. The error suggests that the parent
* directory is not writable by the server.
*
* On success, the returned array will have many indices:
* 'path' - base directory and sub directory or full path to upload directory.
* 'url' - base url and sub directory or absolute URL to upload directory.
* 'subdir' - sub directory if uploads use year/month folders option is on.
* 'basedir' - path without subdir.
* 'baseurl' - URL path without subdir.
* 'error' - set to false.
*
* @since 2.0.0
* @uses apply_filters() Calls 'upload_dir' on returned array.
*
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array See above for description.
*/
function wp_upload_dir( $time = null ) {
global $switched;
$siteurl = get_option( 'siteurl' );
$upload_path = get_option( 'upload_path' );
$upload_path = trim($upload_path);
$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
if ( empty($upload_path) ) {
$dir = WP_CONTENT_DIR . '/uploads';
} else {
$dir = $upload_path;
if ( 'wp-content/uploads' == $upload_path ) {
$dir = WP_CONTENT_DIR . '/uploads';
} elseif ( 0 !== strpos($dir, ABSPATH) ) {
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
$dir = path_join( ABSPATH, $dir );
}
}
if ( !$url = get_option( 'upload_url_path' ) ) {
if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
$url = WP_CONTENT_URL . '/uploads';
else
$url = trailingslashit( $siteurl ) . $upload_path;
}
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
$dir = ABSPATH . UPLOADS;
$url = trailingslashit( $siteurl ) . UPLOADS;
}
if ( is_multisite() && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
if ( defined( 'BLOGUPLOADDIR' ) )
$dir = untrailingslashit(BLOGUPLOADDIR);
$url = str_replace( UPLOADS, 'files', $url );
}
$bdir = $dir;
$burl = $url;
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
if ( !$time )
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
$dir .= $subdir;
$url .= $subdir;
$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
// Make sure we have an uploads dir
if ( ! wp_mkdir_p( $uploads['path'] ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
return array( 'error' => $message );
}
return $uploads;
}
/**
* Get a filename that is sanitized and unique for the given directory.
*
* If the filename is not unique, then a number will be added to the filename
* before the extension, and will continue adding numbers until the filename is
* unique.
*
* The callback is passed three parameters, the first one is the directory, the
* second is the filename, and the third is the extension.
*
* @since 2.5.0
*
* @param string $dir
* @param string $filename
* @param mixed $unique_filename_callback Callback.
* @return string New filename, if given wasn't unique.
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// sanitize the file name before we begin processing
$filename = sanitize_file_name($filename);
// separate the filename into a name and extension
$info = pathinfo($filename);
$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
$name = basename($filename, $ext);
// edge case: if file is named '.ext', treat as an empty name
if ( $name === $ext )
$name = '';
// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
} else {
$number = '';
// change '.ext' to lower case
if ( $ext && strtolower($ext) != $ext ) {
$ext2 = strtolower($ext);
$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
// check for both lower and upper case extension or image sub-sizes may be overwritten
while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
$new_number = $number + 1;
$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
$number = $new_number;
}
return $filename2;
}
while ( file_exists( $dir . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
}
return $filename;
}
/**
* Create a file in the upload folder with given content.
*
* If there is an error, then the key 'error' will exist with the error message.
* If success, then the key 'file' will have the unique file path, the 'url' key
* will have the link to the new file. and the 'error' key will be set to false.
*
* This function will not move an uploaded file to the upload folder. It will
* create a new file with the content in $bits parameter. If you move the upload
* file, read the content of the uploaded file, and then you can give the
* filename and content to this function, which will add it to the upload
* folder.
*
* The permissions will be set on the new file automatically by this function.
*
* @since 2.0.0
*
* @param string $name
* @param null $deprecated Never used. Set to null.
* @param mixed $bits File content
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
if ( !empty( $deprecated ) )
_deprecated_argument( __FUNCTION__, '2.0' );
if ( empty( $name ) )
return array( 'error' => __( 'Empty filename' ) );
$wp_filetype = wp_check_filetype( $name );
if ( !$wp_filetype['ext'] )
return array( 'error' => __( 'Invalid file type' ) );
$upload = wp_upload_dir( $time );
if ( $upload['error'] !== false )
return $upload;
$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
if ( !is_array( $upload_bits_error ) ) {
$upload[ 'error' ] = $upload_bits_error;
return $upload;
}
$filename = wp_unique_filename( $upload['path'], $name );
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
return array( 'error' => $message );
}
$ifp = @ fopen( $new_file, 'wb' );
if ( ! $ifp )
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
$stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
clearstatcache();
// Compute the URL
$url = $upload['url'] . "/$filename";
return array( 'file' => $new_file, 'url' => $url, 'error' => false );
}
/**
* Retrieve the file type based on the extension name.
*
* @package WordPress
* @since 2.5.0
* @uses apply_filters() Calls 'ext2type' hook on default supported types.
*
* @param string $ext The extension to search.
* @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
*/
function wp_ext2type( $ext ) {
$ext2type = apply_filters( 'ext2type', array(
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsb', 'xlsm' ),
'interactive' => array( 'key', 'ppt', 'pptx', 'pptm', 'odp', 'swf' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
));
foreach ( $ext2type as $type => $exts )
if ( in_array( $ext, $exts ) )
return $type;
}
/**
* Retrieve the file type from the file name.
*
* You can optionally define the mime array, if needed.
*
* @since 2.0.4
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Attempt to determine the real file type of a file.
* If unable to, the file name extension will be used to determine type.
*
* If it's determined that the extension does not match the file's real type,
* then the "proper_filename" value will be set with a proper filename and extension.
*
* Currently this function only supports validating images known to getimagesize().
*
* @since 3.0.0
*
* @param string $file Full path to the image.
* @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
*/
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
$proper_filename = false;
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) )
return compact( 'ext', 'type', 'proper_filename' );
// We're able to validate images using GD
if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
// Attempt to figure out what type of image it actually is
$imgstats = @getimagesize( $file );
// If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
// This is a simplified array of MIMEs that getimagesize() can detect and their extensions
// You shouldn't need to use this filter, but it's here just in case
$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
) );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
$new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename )
$proper_filename = $new_filename; // Mark that it changed
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
extract( $wp_filetype );
}
}
}
// Let plugins try and validate other types of files
// Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
}
/**
* Retrieve list of allowed mime types and file extensions.
*
* @since 2.8.6
*
* @return array Array of mime types keyed by the file extension regex corresponding to those types.
*/
function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( 'upload_mimes', array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'bmp' => 'image/bmp',
'tif|tiff' => 'image/tiff',
'ico' => 'image/x-icon',
'asf|asx|wax|wmv|wmx' => 'video/asf',
'avi' => 'video/avi',
'divx' => 'video/divx',
'flv' => 'video/x-flv',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'txt|asc|c|cc|h' => 'text/plain',
'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'css' => 'text/css',
'htm|html' => 'text/html',
'mp3|m4a|m4b' => 'audio/mpeg',
'mp4|m4v' => 'video/mp4',
'ra|ram' => 'audio/x-realaudio',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
'ogv' => 'video/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/wma',
'mka' => 'audio/x-matroska',
'mkv' => 'video/x-matroska',
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'doc|docx' => 'application/msword',
'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docm|dotm' => 'application/vnd.ms-word',
'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'exe' => 'application/x-msdownload',
// openoffice formats
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
// wordperfect formats
'wp|wpd' => 'application/wordperfect',
) );
}
return $mimes;
}
/**
* Retrieve nonce action "Are you sure" message.
*
* The action is split by verb and noun. The action format is as follows:
* verb-action_extra. The verb is before the first dash and has the format of
* letters and no spaces and numbers. The noun is after the dash and before the
* underscore, if an underscore exists. The noun is also only letters.
*
* The filter will be called for any action, which is not defined by WordPress.
* You may use the filter for your plugin to explain nonce actions to the user,
* when they get the "Are you sure?" message. The filter is in the format of
* 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
* $noun replaced by the found noun. The two parameters that are given to the
* hook are the localized "Are you sure you want to do this?" message with the
* extra text (the text after the underscore).
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action Nonce action.
* @return string Are you sure message.
*/
function wp_explain_nonce( $action ) {
if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
$verb = $matches[1];
$noun = $matches[2];
$trans = array();
$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' );
$trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false );
$trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' );
$trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' );
$trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' );
$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' );
$trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' );
$trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' );
$trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
$trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false );
$trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' );
$trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' );
$trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false );
$trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false );
$trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' );
$trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' );
$trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' );
$trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' );
$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' );
$trans['upgrade']['plugin'] = array( __( 'Your attempt to update this plugin: “%s” has failed.' ), 'use_id' );
$trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false );
$trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' );
$trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' );
$trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false );
$trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false );
$trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false );
$trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false );
$trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
$trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' );
$trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' );
$trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' );
$trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
if ( isset( $trans[$verb][$noun] ) ) {
if ( !empty( $trans[$verb][$noun][1] ) ) {
$lookup = $trans[$verb][$noun][1];
if ( isset($trans[$verb][$noun][2]) )
$lookup_value = $trans[$verb][$noun][2];
$object = $matches[4];
if ( 'use_id' != $lookup ) {
if ( isset( $lookup_value ) )
$object = call_user_func( $lookup, $lookup_value, $object );
else
$object = call_user_func( $lookup, $object );
}
return sprintf( $trans[$verb][$noun][0], esc_html($object) );
} else {
return $trans[$verb][$noun][0];
}
}
return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
} else {
return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
}
}
/**
* Display "Are You Sure" message to confirm the action being taken.
*
* If the action has the nonce explain message, then it will be displayed along
* with the "Are you sure?" message.
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action The nonce action.
*/
function wp_nonce_ays( $action ) {
$title = __( 'WordPress Failure Notice' );
$html = esc_html( wp_explain_nonce( $action ) );
if ( 'log-out' == $action )
$html .= "" . sprintf( __( "Do you really want to log out?"), wp_logout_url() ); elseif ( wp_get_referer() ) $html .= "
" . __( 'Please try again.' ) . ""; wp_die( $html, $title, array('response' => 403) ); } /** * Kill WordPress execution and display HTML message with error message. * * This function complements the die() PHP function. The difference is that * HTML will be displayed to the user. It is recommended to use this function * only, when the execution should not continue any further. It is not * recommended to call this function very often and try to handle as many errors * as possible siliently. * * @since 2.0.4 * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguements to control behaviour. */ function wp_die( $message, $title = '', $args = array() ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) die('-1'); if ( function_exists( 'apply_filters' ) ) { $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); } else { $function = '_default_wp_die_handler'; } call_user_func( $function, $message, $title, $args ); } /** * Kill WordPress execution and display HTML message with error message. * * This is the default handler for wp_die if you want a custom one for your * site then you can overload using the wp_die_handler filter in wp_die * * @since 3.0.0 * @access private * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguements to control behaviour. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 500 ); $r = wp_parse_args($args, $defaults); $have_gettext = function_exists('__'); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( empty( $title ) ) { $error_data = $message->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['title'] ) ) $title = $error_data['title']; } $errors = $message->get_error_messages(); switch ( count( $errors ) ) : case 0 : $message = ''; break; case 1 : $message = "
{$errors[0]}
"; break; default : $message = "$message
"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { $back_text = $have_gettext? __('« Back') : '« Back'; $message .= "\n"; } if ( defined( 'WP_SITEURL' ) && '' != WP_SITEURL ) $admin_dir = WP_SITEURL . '/wp-admin/'; elseif ( function_exists( 'get_bloginfo' ) && '' != get_bloginfo( 'wpurl' ) ) $admin_dir = get_bloginfo( 'wpurl' ) . '/wp-admin/'; elseif ( strpos( $_SERVER['PHP_SELF'], 'wp-admin' ) !== false ) $admin_dir = ''; else $admin_dir = 'wp-admin/'; if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : if ( !headers_sent() ) { status_header( $r['response'] ); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); } if ( empty($title) ) $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; $text_direction = 'ltr'; if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) $text_direction = 'rtl'; elseif ( function_exists( 'is_rtl' ) && is_rtl() ) $text_direction = 'rtl'; ?> >sys_get_temp_dir(), before finally defaulting to /tmp/
*
* In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
*
* @since 2.5.0
*
* @return string Writable temporary directory
*/
function get_temp_dir() {
static $temp;
if ( defined('WP_TEMP_DIR') )
return trailingslashit(WP_TEMP_DIR);
if ( $temp )
return trailingslashit($temp);
$temp = WP_CONTENT_DIR . '/';
if ( is_dir($temp) && @is_writable($temp) )
return $temp;
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_writable($temp) )
return trailingslashit($temp);
}
$temp = ini_get('upload_tmp_dir');
if ( is_dir($temp) && @is_writable($temp) )
return trailingslashit($temp);
$temp = '/tmp/';
return $temp;
}
/**
* Get an array containing the current upload directory's path and url.
*
* Checks the 'upload_path' option, which should be from the web root folder,
* and if it isn't empty it will be used. If it is empty, then the path will be
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
*
* The upload URL path is set either by the 'upload_url_path' option or by using
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
*
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
* the administration settings panel), then the time will be used. The format
* will be year first and then month.
*
* If the path couldn't be created, then an error will be returned with the key
* 'error' containing the error message. The error suggests that the parent
* directory is not writable by the server.
*
* On success, the returned array will have many indices:
* 'path' - base directory and sub directory or full path to upload directory.
* 'url' - base url and sub directory or absolute URL to upload directory.
* 'subdir' - sub directory if uploads use year/month folders option is on.
* 'basedir' - path without subdir.
* 'baseurl' - URL path without subdir.
* 'error' - set to false.
*
* @since 2.0.0
* @uses apply_filters() Calls 'upload_dir' on returned array.
*
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array See above for description.
*/
function wp_upload_dir( $time = null ) {
global $switched;
$siteurl = get_option( 'siteurl' );
$upload_path = get_option( 'upload_path' );
$upload_path = trim($upload_path);
$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
if ( empty($upload_path) ) {
$dir = WP_CONTENT_DIR . '/uploads';
} else {
$dir = $upload_path;
if ( 'wp-content/uploads' == $upload_path ) {
$dir = WP_CONTENT_DIR . '/uploads';
} elseif ( 0 !== strpos($dir, ABSPATH) ) {
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
$dir = path_join( ABSPATH, $dir );
}
}
if ( !$url = get_option( 'upload_url_path' ) ) {
if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
$url = WP_CONTENT_URL . '/uploads';
else
$url = trailingslashit( $siteurl ) . $upload_path;
}
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
$dir = ABSPATH . UPLOADS;
$url = trailingslashit( $siteurl ) . UPLOADS;
}
if ( is_multisite() && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
if ( defined( 'BLOGUPLOADDIR' ) )
$dir = untrailingslashit(BLOGUPLOADDIR);
$url = str_replace( UPLOADS, 'files', $url );
}
$bdir = $dir;
$burl = $url;
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
if ( !$time )
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
$dir .= $subdir;
$url .= $subdir;
$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
// Make sure we have an uploads dir
if ( ! wp_mkdir_p( $uploads['path'] ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
return array( 'error' => $message );
}
return $uploads;
}
/**
* Get a filename that is sanitized and unique for the given directory.
*
* If the filename is not unique, then a number will be added to the filename
* before the extension, and will continue adding numbers until the filename is
* unique.
*
* The callback is passed three parameters, the first one is the directory, the
* second is the filename, and the third is the extension.
*
* @since 2.5.0
*
* @param string $dir
* @param string $filename
* @param mixed $unique_filename_callback Callback.
* @return string New filename, if given wasn't unique.
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// sanitize the file name before we begin processing
$filename = sanitize_file_name($filename);
// separate the filename into a name and extension
$info = pathinfo($filename);
$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
$name = basename($filename, $ext);
// edge case: if file is named '.ext', treat as an empty name
if ( $name === $ext )
$name = '';
// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
} else {
$number = '';
// change '.ext' to lower case
if ( $ext && strtolower($ext) != $ext ) {
$ext2 = strtolower($ext);
$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
// check for both lower and upper case extension or image sub-sizes may be overwritten
while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
$new_number = $number + 1;
$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
$number = $new_number;
}
return $filename2;
}
while ( file_exists( $dir . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
}
return $filename;
}
/**
* Create a file in the upload folder with given content.
*
* If there is an error, then the key 'error' will exist with the error message.
* If success, then the key 'file' will have the unique file path, the 'url' key
* will have the link to the new file. and the 'error' key will be set to false.
*
* This function will not move an uploaded file to the upload folder. It will
* create a new file with the content in $bits parameter. If you move the upload
* file, read the content of the uploaded file, and then you can give the
* filename and content to this function, which will add it to the upload
* folder.
*
* The permissions will be set on the new file automatically by this function.
*
* @since 2.0.0
*
* @param string $name
* @param null $deprecated Never used. Set to null.
* @param mixed $bits File content
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
if ( !empty( $deprecated ) )
_deprecated_argument( __FUNCTION__, '2.0' );
if ( empty( $name ) )
return array( 'error' => __( 'Empty filename' ) );
$wp_filetype = wp_check_filetype( $name );
if ( !$wp_filetype['ext'] )
return array( 'error' => __( 'Invalid file type' ) );
$upload = wp_upload_dir( $time );
if ( $upload['error'] !== false )
return $upload;
$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
if ( !is_array( $upload_bits_error ) ) {
$upload[ 'error' ] = $upload_bits_error;
return $upload;
}
$filename = wp_unique_filename( $upload['path'], $name );
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
return array( 'error' => $message );
}
$ifp = @ fopen( $new_file, 'wb' );
if ( ! $ifp )
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
$stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
clearstatcache();
// Compute the URL
$url = $upload['url'] . "/$filename";
return array( 'file' => $new_file, 'url' => $url, 'error' => false );
}
/**
* Retrieve the file type based on the extension name.
*
* @package WordPress
* @since 2.5.0
* @uses apply_filters() Calls 'ext2type' hook on default supported types.
*
* @param string $ext The extension to search.
* @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
*/
function wp_ext2type( $ext ) {
$ext2type = apply_filters( 'ext2type', array(
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsb', 'xlsm' ),
'interactive' => array( 'key', 'ppt', 'pptx', 'pptm', 'odp', 'swf' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
));
foreach ( $ext2type as $type => $exts )
if ( in_array( $ext, $exts ) )
return $type;
}
/**
* Retrieve the file type from the file name.
*
* You can optionally define the mime array, if needed.
*
* @since 2.0.4
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Attempt to determine the real file type of a file.
* If unable to, the file name extension will be used to determine type.
*
* If it's determined that the extension does not match the file's real type,
* then the "proper_filename" value will be set with a proper filename and extension.
*
* Currently this function only supports validating images known to getimagesize().
*
* @since 3.0.0
*
* @param string $file Full path to the image.
* @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
*/
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
$proper_filename = false;
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) )
return compact( 'ext', 'type', 'proper_filename' );
// We're able to validate images using GD
if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
// Attempt to figure out what type of image it actually is
$imgstats = @getimagesize( $file );
// If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
// This is a simplified array of MIMEs that getimagesize() can detect and their extensions
// You shouldn't need to use this filter, but it's here just in case
$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
) );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
$new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename )
$proper_filename = $new_filename; // Mark that it changed
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
extract( $wp_filetype );
}
}
}
// Let plugins try and validate other types of files
// Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
}
/**
* Retrieve list of allowed mime types and file extensions.
*
* @since 2.8.6
*
* @return array Array of mime types keyed by the file extension regex corresponding to those types.
*/
function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( 'upload_mimes', array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'bmp' => 'image/bmp',
'tif|tiff' => 'image/tiff',
'ico' => 'image/x-icon',
'asf|asx|wax|wmv|wmx' => 'video/asf',
'avi' => 'video/avi',
'divx' => 'video/divx',
'flv' => 'video/x-flv',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'txt|asc|c|cc|h' => 'text/plain',
'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'css' => 'text/css',
'htm|html' => 'text/html',
'mp3|m4a|m4b' => 'audio/mpeg',
'mp4|m4v' => 'video/mp4',
'ra|ram' => 'audio/x-realaudio',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
'ogv' => 'video/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/wma',
'mka' => 'audio/x-matroska',
'mkv' => 'video/x-matroska',
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'doc|docx' => 'application/msword',
'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docm|dotm' => 'application/vnd.ms-word',
'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'rar' => 'application/rar',
'7z' => 'application/x-7z-compressed',
'exe' => 'application/x-msdownload',
// openoffice formats
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
// wordperfect formats
'wp|wpd' => 'application/wordperfect',
) );
}
return $mimes;
}
/**
* Retrieve nonce action "Are you sure" message.
*
* The action is split by verb and noun. The action format is as follows:
* verb-action_extra. The verb is before the first dash and has the format of
* letters and no spaces and numbers. The noun is after the dash and before the
* underscore, if an underscore exists. The noun is also only letters.
*
* The filter will be called for any action, which is not defined by WordPress.
* You may use the filter for your plugin to explain nonce actions to the user,
* when they get the "Are you sure?" message. The filter is in the format of
* 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
* $noun replaced by the found noun. The two parameters that are given to the
* hook are the localized "Are you sure you want to do this?" message with the
* extra text (the text after the underscore).
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action Nonce action.
* @return string Are you sure message.
*/
function wp_explain_nonce( $action ) {
if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
$verb = $matches[1];
$noun = $matches[2];
$trans = array();
$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' );
$trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false );
$trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' );
$trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' );
$trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' );
$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' );
$trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' );
$trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' );
$trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
$trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false );
$trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' );
$trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' );
$trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false );
$trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false );
$trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' );
$trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' );
$trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' );
$trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' );
$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' );
$trans['upgrade']['plugin'] = array( __( 'Your attempt to update this plugin: “%s” has failed.' ), 'use_id' );
$trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false );
$trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' );
$trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' );
$trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false );
$trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false );
$trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false );
$trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false );
$trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
$trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' );
$trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' );
$trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' );
$trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
if ( isset( $trans[$verb][$noun] ) ) {
if ( !empty( $trans[$verb][$noun][1] ) ) {
$lookup = $trans[$verb][$noun][1];
if ( isset($trans[$verb][$noun][2]) )
$lookup_value = $trans[$verb][$noun][2];
$object = $matches[4];
if ( 'use_id' != $lookup ) {
if ( isset( $lookup_value ) )
$object = call_user_func( $lookup, $lookup_value, $object );
else
$object = call_user_func( $lookup, $object );
}
return sprintf( $trans[$verb][$noun][0], esc_html($object) );
} else {
return $trans[$verb][$noun][0];
}
}
return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
} else {
return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
}
}
/**
* Display "Are You Sure" message to confirm the action being taken.
*
* If the action has the nonce explain message, then it will be displayed along
* with the "Are you sure?" message.
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action The nonce action.
*/
function wp_nonce_ays( $action ) {
$title = __( 'WordPress Failure Notice' );
$html = esc_html( wp_explain_nonce( $action ) );
if ( 'log-out' == $action )
$html .= "" . sprintf( __( "Do you really want to log out?"), wp_logout_url() ); elseif ( wp_get_referer() ) $html .= "
" . __( 'Please try again.' ) . ""; wp_die( $html, $title, array('response' => 403) ); } /** * Kill WordPress execution and display HTML message with error message. * * This function complements the die() PHP function. The difference is that * HTML will be displayed to the user. It is recommended to use this function * only, when the execution should not continue any further. It is not * recommended to call this function very often and try to handle as many errors * as possible silently. * * @since 2.0.4 * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function wp_die( $message, $title = '', $args = array() ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) die('-1'); if ( function_exists( 'apply_filters' ) ) { $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); } else { $function = '_default_wp_die_handler'; } call_user_func( $function, $message, $title, $args ); } /** * Kill WordPress execution and display HTML message with error message. * * This is the default handler for wp_die if you want a custom one for your * site then you can overload using the wp_die_handler filter in wp_die * * @since 3.0.0 * @access private * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 500 ); $r = wp_parse_args($args, $defaults); $have_gettext = function_exists('__'); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( empty( $title ) ) { $error_data = $message->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['title'] ) ) $title = $error_data['title']; } $errors = $message->get_error_messages(); switch ( count( $errors ) ) : case 0 : $message = ''; break; case 1 : $message = "
{$errors[0]}
"; break; default : $message = "$message
"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { $back_text = $have_gettext? __('« Back') : '« Back'; $message .= "\n"; } if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : if ( !headers_sent() ) { status_header( $r['response'] ); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); } if ( empty($title) ) $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; $text_direction = 'ltr'; if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) $text_direction = 'rtl'; elseif ( function_exists( 'is_rtl' ) && is_rtl() ) $text_direction = 'rtl'; ?> >sys_get_temp_dir(), before finally defaulting to /tmp/
*
* In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
*
* @since 2.5.0
*
* @return string Writable temporary directory
*/
function get_temp_dir() {
static $temp;
if ( defined('WP_TEMP_DIR') )
return trailingslashit(WP_TEMP_DIR);
if ( $temp )
return trailingslashit($temp);
$temp = WP_CONTENT_DIR . '/';
if ( is_dir($temp) && @is_writable($temp) )
return $temp;
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_writable($temp) )
return trailingslashit($temp);
}
$temp = ini_get('upload_tmp_dir');
if ( is_dir($temp) && @is_writable($temp) )
return trailingslashit($temp);
$temp = '/tmp/';
return $temp;
}
/**
* Get an array containing the current upload directory's path and url.
*
* Checks the 'upload_path' option, which should be from the web root folder,
* and if it isn't empty it will be used. If it is empty, then the path will be
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
*
* The upload URL path is set either by the 'upload_url_path' option or by using
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
*
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
* the administration settings panel), then the time will be used. The format
* will be year first and then month.
*
* If the path couldn't be created, then an error will be returned with the key
* 'error' containing the error message. The error suggests that the parent
* directory is not writable by the server.
*
* On success, the returned array will have many indices:
* 'path' - base directory and sub directory or full path to upload directory.
* 'url' - base url and sub directory or absolute URL to upload directory.
* 'subdir' - sub directory if uploads use year/month folders option is on.
* 'basedir' - path without subdir.
* 'baseurl' - URL path without subdir.
* 'error' - set to false.
*
* @since 2.0.0
* @uses apply_filters() Calls 'upload_dir' on returned array.
*
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array See above for description.
*/
function wp_upload_dir( $time = null ) {
global $switched;
$siteurl = get_option( 'siteurl' );
$upload_path = get_option( 'upload_path' );
$upload_path = trim($upload_path);
$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
if ( empty($upload_path) ) {
$dir = WP_CONTENT_DIR . '/uploads';
} else {
$dir = $upload_path;
if ( 'wp-content/uploads' == $upload_path ) {
$dir = WP_CONTENT_DIR . '/uploads';
} elseif ( 0 !== strpos($dir, ABSPATH) ) {
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
$dir = path_join( ABSPATH, $dir );
}
}
if ( !$url = get_option( 'upload_url_path' ) ) {
if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
$url = WP_CONTENT_URL . '/uploads';
else
$url = trailingslashit( $siteurl ) . $upload_path;
}
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
$dir = ABSPATH . UPLOADS;
$url = trailingslashit( $siteurl ) . UPLOADS;
}
if ( is_multisite() && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
if ( defined( 'BLOGUPLOADDIR' ) )
$dir = untrailingslashit(BLOGUPLOADDIR);
$url = str_replace( UPLOADS, 'files', $url );
}
$bdir = $dir;
$burl = $url;
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
if ( !$time )
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
$dir .= $subdir;
$url .= $subdir;
$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
// Make sure we have an uploads dir
if ( ! wp_mkdir_p( $uploads['path'] ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
return array( 'error' => $message );
}
return $uploads;
}
/**
* Get a filename that is sanitized and unique for the given directory.
*
* If the filename is not unique, then a number will be added to the filename
* before the extension, and will continue adding numbers until the filename is
* unique.
*
* The callback is passed three parameters, the first one is the directory, the
* second is the filename, and the third is the extension.
*
* @since 2.5.0
*
* @param string $dir
* @param string $filename
* @param mixed $unique_filename_callback Callback.
* @return string New filename, if given wasn't unique.
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// sanitize the file name before we begin processing
$filename = sanitize_file_name($filename);
// separate the filename into a name and extension
$info = pathinfo($filename);
$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
$name = basename($filename, $ext);
// edge case: if file is named '.ext', treat as an empty name
if ( $name === $ext )
$name = '';
// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
} else {
$number = '';
// change '.ext' to lower case
if ( $ext && strtolower($ext) != $ext ) {
$ext2 = strtolower($ext);
$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
// check for both lower and upper case extension or image sub-sizes may be overwritten
while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
$new_number = $number + 1;
$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
$number = $new_number;
}
return $filename2;
}
while ( file_exists( $dir . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
}
return $filename;
}
/**
* Create a file in the upload folder with given content.
*
* If there is an error, then the key 'error' will exist with the error message.
* If success, then the key 'file' will have the unique file path, the 'url' key
* will have the link to the new file. and the 'error' key will be set to false.
*
* This function will not move an uploaded file to the upload folder. It will
* create a new file with the content in $bits parameter. If you move the upload
* file, read the content of the uploaded file, and then you can give the
* filename and content to this function, which will add it to the upload
* folder.
*
* The permissions will be set on the new file automatically by this function.
*
* @since 2.0.0
*
* @param string $name
* @param null $deprecated Never used. Set to null.
* @param mixed $bits File content
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
if ( !empty( $deprecated ) )
_deprecated_argument( __FUNCTION__, '2.0' );
if ( empty( $name ) )
return array( 'error' => __( 'Empty filename' ) );
$wp_filetype = wp_check_filetype( $name );
if ( !$wp_filetype['ext'] )
return array( 'error' => __( 'Invalid file type' ) );
$upload = wp_upload_dir( $time );
if ( $upload['error'] !== false )
return $upload;
$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
if ( !is_array( $upload_bits_error ) ) {
$upload[ 'error' ] = $upload_bits_error;
return $upload;
}
$filename = wp_unique_filename( $upload['path'], $name );
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
return array( 'error' => $message );
}
$ifp = @ fopen( $new_file, 'wb' );
if ( ! $ifp )
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
$stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
clearstatcache();
// Compute the URL
$url = $upload['url'] . "/$filename";
return array( 'file' => $new_file, 'url' => $url, 'error' => false );
}
/**
* Retrieve the file type based on the extension name.
*
* @package WordPress
* @since 2.5.0
* @uses apply_filters() Calls 'ext2type' hook on default supported types.
*
* @param string $ext The extension to search.
* @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
*/
function wp_ext2type( $ext ) {
$ext2type = apply_filters( 'ext2type', array(
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsb', 'xlsm' ),
'interactive' => array( 'key', 'ppt', 'pptx', 'pptm', 'odp', 'swf' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
));
foreach ( $ext2type as $type => $exts )
if ( in_array( $ext, $exts ) )
return $type;
}
/**
* Retrieve the file type from the file name.
*
* You can optionally define the mime array, if needed.
*
* @since 2.0.4
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Attempt to determine the real file type of a file.
* If unable to, the file name extension will be used to determine type.
*
* If it's determined that the extension does not match the file's real type,
* then the "proper_filename" value will be set with a proper filename and extension.
*
* Currently this function only supports validating images known to getimagesize().
*
* @since 3.0.0
*
* @param string $file Full path to the image.
* @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
*/
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
$proper_filename = false;
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) )
return compact( 'ext', 'type', 'proper_filename' );
// We're able to validate images using GD
if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
// Attempt to figure out what type of image it actually is
$imgstats = @getimagesize( $file );
// If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
// This is a simplified array of MIMEs that getimagesize() can detect and their extensions
// You shouldn't need to use this filter, but it's here just in case
$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
) );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
$new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename )
$proper_filename = $new_filename; // Mark that it changed
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
extract( $wp_filetype );
}
}
}
// Let plugins try and validate other types of files
// Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
}
/**
* Retrieve list of allowed mime types and file extensions.
*
* @since 2.8.6
*
* @return array Array of mime types keyed by the file extension regex corresponding to those types.
*/
function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( 'upload_mimes', array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'bmp' => 'image/bmp',
'tif|tiff' => 'image/tiff',
'ico' => 'image/x-icon',
'asf|asx|wax|wmv|wmx' => 'video/asf',
'avi' => 'video/avi',
'divx' => 'video/divx',
'flv' => 'video/x-flv',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'txt|asc|c|cc|h' => 'text/plain',
'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'css' => 'text/css',
'htm|html' => 'text/html',
'mp3|m4a|m4b' => 'audio/mpeg',
'mp4|m4v' => 'video/mp4',
'ra|ram' => 'audio/x-realaudio',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
'ogv' => 'video/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/wma',
'mka' => 'audio/x-matroska',
'mkv' => 'video/x-matroska',
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'doc|docx' => 'application/msword',
'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docm|dotm' => 'application/vnd.ms-word',
'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'rar' => 'application/rar',
'7z' => 'application/x-7z-compressed',
'exe' => 'application/x-msdownload',
// openoffice formats
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
// wordperfect formats
'wp|wpd' => 'application/wordperfect',
) );
}
return $mimes;
}
/**
* Retrieve nonce action "Are you sure" message.
*
* The action is split by verb and noun. The action format is as follows:
* verb-action_extra. The verb is before the first dash and has the format of
* letters and no spaces and numbers. The noun is after the dash and before the
* underscore, if an underscore exists. The noun is also only letters.
*
* The filter will be called for any action, which is not defined by WordPress.
* You may use the filter for your plugin to explain nonce actions to the user,
* when they get the "Are you sure?" message. The filter is in the format of
* 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
* $noun replaced by the found noun. The two parameters that are given to the
* hook are the localized "Are you sure you want to do this?" message with the
* extra text (the text after the underscore).
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action Nonce action.
* @return string Are you sure message.
*/
function wp_explain_nonce( $action ) {
if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
$verb = $matches[1];
$noun = $matches[2];
$trans = array();
$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' );
$trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false );
$trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' );
$trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' );
$trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' );
$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' );
$trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' );
$trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' );
$trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
$trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false );
$trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' );
$trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' );
$trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false );
$trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false );
$trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' );
$trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' );
$trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' );
$trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' );
$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' );
$trans['upgrade']['plugin'] = array( __( 'Your attempt to update this plugin: “%s” has failed.' ), 'use_id' );
$trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false );
$trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' );
$trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' );
$trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false );
$trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false );
$trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false );
$trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' );
$trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false );
$trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
$trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' );
$trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' );
$trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' );
$trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
if ( isset( $trans[$verb][$noun] ) ) {
if ( !empty( $trans[$verb][$noun][1] ) ) {
$lookup = $trans[$verb][$noun][1];
if ( isset($trans[$verb][$noun][2]) )
$lookup_value = $trans[$verb][$noun][2];
$object = $matches[4];
if ( 'use_id' != $lookup ) {
if ( isset( $lookup_value ) )
$object = call_user_func( $lookup, $lookup_value, $object );
else
$object = call_user_func( $lookup, $object );
}
return sprintf( $trans[$verb][$noun][0], esc_html($object) );
} else {
return $trans[$verb][$noun][0];
}
}
return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
} else {
return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
}
}
/**
* Display "Are You Sure" message to confirm the action being taken.
*
* If the action has the nonce explain message, then it will be displayed along
* with the "Are you sure?" message.
*
* @package WordPress
* @subpackage Security
* @since 2.0.4
*
* @param string $action The nonce action.
*/
function wp_nonce_ays( $action ) {
$title = __( 'WordPress Failure Notice' );
$html = esc_html( wp_explain_nonce( $action ) );
if ( 'log-out' == $action )
$html .= "" . sprintf( __( "Do you really want to log out?"), wp_logout_url() ); elseif ( wp_get_referer() ) $html .= "
" . __( 'Please try again.' ) . ""; wp_die( $html, $title, array('response' => 403) ); } /** * Kill WordPress execution and display HTML message with error message. * * This function complements the die() PHP function. The difference is that * HTML will be displayed to the user. It is recommended to use this function * only, when the execution should not continue any further. It is not * recommended to call this function very often and try to handle as many errors * as possible silently. * * @since 2.0.4 * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function wp_die( $message, $title = '', $args = array() ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) die('-1'); if ( function_exists( 'apply_filters' ) ) { $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); } else { $function = '_default_wp_die_handler'; } call_user_func( $function, $message, $title, $args ); } /** * Kill WordPress execution and display HTML message with error message. * * This is the default handler for wp_die if you want a custom one for your * site then you can overload using the wp_die_handler filter in wp_die * * @since 3.0.0 * @access private * * @param string $message Error message. * @param string $title Error title. * @param string|array $args Optional arguments to control behavior. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 500 ); $r = wp_parse_args($args, $defaults); $have_gettext = function_exists('__'); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( empty( $title ) ) { $error_data = $message->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['title'] ) ) $title = $error_data['title']; } $errors = $message->get_error_messages(); switch ( count( $errors ) ) : case 0 : $message = ''; break; case 1 : $message = "
{$errors[0]}
"; break; default : $message = "$message
"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { $back_text = $have_gettext? __('« Back') : '« Back'; $message .= "\n"; } if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : if ( !headers_sent() ) { status_header( $r['response'] ); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); } if ( empty($title) ) $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; $text_direction = 'ltr'; if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) $text_direction = 'rtl'; elseif ( function_exists( 'is_rtl' ) && is_rtl() ) $text_direction = 'rtl'; ?> >