Exemplo n.º 1
0
function seems_utf8($str)
{
    mbstring_binary_safe_encoding();
    $length = strlen($str);
    reset_mbstring_encoding();
    for ($i = 0; $i < $length; $i++) {
        $c = ord($str[$i]);
        if ($c < 0x80) {
            $n = 0;
        } elseif (($c & 0xe0) == 0xc0) {
            $n = 1;
        } elseif (($c & 0xf0) == 0xe0) {
            $n = 2;
        } elseif (($c & 0xf8) == 0xf0) {
            $n = 3;
        } elseif (($c & 0xfc) == 0xf8) {
            $n = 4;
        } elseif (($c & 0xfe) == 0xfc) {
            $n = 5;
        } else {
            return false;
        }
        // Does not match any model
        for ($j = 0; $j < $n; $j++) {
            // n bytes matching 10bbbbbb follow ?
            if (++$i == $length || (ord($str[$i]) & 0xc0) != 0x80) {
                return false;
            }
        }
    }
    return true;
}
Exemplo n.º 2
0
 /**
  * array (size=23)
  * 0 =>
  * array (size=11)
  * 'filename' => string 'akismet/' (length=8)
  * 'stored_filename' => string 'akismet/' (length=8)
  * 'size' => int 0
  * 'compressed_size' => int 0
  * 'mtime' => int 1443138698
  * 'comment' => string '' (length=0)
  * 'folder' => boolean true
  * 'index' => int 0
  * 'status' => string 'ok' (length=2)
  * 'crc' => int 0
  * 'content' => string '' (length=0)
  * 1 =>
  * array (size=11)
  * 'filename' => string 'akismet/akismet.php' (length=19)
  * 'stored_filename' => string 'akismet/akismet.php' (length=19)
  * 'size' => int 2438
  * 'compressed_size' => int 1184
  * 'mtime' => int 1443138698
  * 'comment' => string '' (length=0)
  * 'folder' => boolean false
  * 'index' => int 1
  * 'status' => string 'ok' (length=2)
  * 'crc' => int 1640791883
  * 'content' => string ''
  */
 public static function read($filePath)
 {
     if (function_exists('mbstring_binary_safe_encoding')) {
         mbstring_binary_safe_encoding();
     }
     $archive = new PclZip($filePath);
     $archive_files = $archive->extract(PCLZIP_OPT_EXTRACT_AS_STRING);
     if (function_exists('reset_mbstring_encoding')) {
         reset_mbstring_encoding();
     }
     return $archive_files;
 }
 /**
  * Write a string to a file
  *
  * @param string $file Remote path to the file where to write the data.
  * @param string $contents The data to write.
  * @param int $mode (optional) The file permissions as octal number, usually 0644.
  * @return bool False upon failure.
  */
 function put_contents($file, $contents, $mode = false)
 {
     $fp = @fopen($file, 'wb');
     if (!$fp) {
         return false;
     }
     mbstring_binary_safe_encoding();
     $data_length = strlen($contents);
     $bytes_written = fwrite($fp, $contents);
     reset_mbstring_encoding();
     fclose($fp);
     if ($data_length !== $bytes_written) {
         return false;
     }
     $this->chmod($file, $mode);
     return true;
 }
Exemplo n.º 4
0
 private function bwg_wp_read_image_metadata($file)
 {
     if (!file_exists($file)) {
         return false;
     }
     list(, , $sourceImageType) = getimagesize($file);
     $meta = array('aperture' => 0, 'credit' => '', 'camera' => '', 'caption' => '', 'created_timestamp' => 0, 'copyright' => '', 'focal_length' => 0, 'iso' => 0, 'shutter_speed' => 0, 'title' => '', 'orientation' => 0);
     if (is_callable('iptcparse')) {
         getimagesize($file, $info);
         if (!empty($info['APP13'])) {
             $iptc = iptcparse($info['APP13']);
             if (!empty($iptc['2#105'][0])) {
                 $meta['title'] = trim($iptc['2#105'][0]);
             } elseif (!empty($iptc['2#005'][0])) {
                 $meta['title'] = trim($iptc['2#005'][0]);
             }
             if (!empty($iptc['2#120'][0])) {
                 $caption = trim($iptc['2#120'][0]);
                 if (empty($meta['title'])) {
                     mbstring_binary_safe_encoding();
                     $caption_length = strlen($caption);
                     reset_mbstring_encoding();
                     if ($caption_length < 80) {
                         $meta['title'] = $caption;
                     } else {
                         $meta['caption'] = $caption;
                     }
                 } elseif ($caption != $meta['title']) {
                     $meta['caption'] = $caption;
                 }
             }
             if (!empty($iptc['2#110'][0])) {
                 $meta['credit'] = trim($iptc['2#110'][0]);
             } elseif (!empty($iptc['2#080'][0])) {
                 $meta['credit'] = trim($iptc['2#080'][0]);
             }
             if (!empty($iptc['2#055'][0]) and !empty($iptc['2#060'][0])) {
                 $meta['created_timestamp'] = strtotime($iptc['2#055'][0] . ' ' . $iptc['2#060'][0]);
             }
             if (!empty($iptc['2#116'][0])) {
                 $meta['copyright'] = trim($iptc['2#116'][0]);
             }
         }
     }
     if (is_callable('exif_read_data') && in_array($sourceImageType, apply_filters('wp_read_image_metadata_types', array(IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM)))) {
         $exif = @exif_read_data($file);
         if (empty($meta['title']) && !empty($exif['Title'])) {
             $meta['title'] = trim($exif['Title']);
         }
         if (!empty($exif['ImageDescription'])) {
             mbstring_binary_safe_encoding();
             $description_length = strlen($exif['ImageDescription']);
             reset_mbstring_encoding();
             if (empty($meta['title']) && $description_length < 80) {
                 $meta['title'] = trim($exif['ImageDescription']);
                 if (empty($meta['caption']) && !empty($exif['COMPUTED']['UserComment']) && trim($exif['COMPUTED']['UserComment']) != $meta['title']) {
                     $meta['caption'] = trim($exif['COMPUTED']['UserComment']);
                 }
             } elseif (empty($meta['caption']) && trim($exif['ImageDescription']) != $meta['title']) {
                 $meta['caption'] = trim($exif['ImageDescription']);
             }
         } elseif (empty($meta['caption']) && !empty($exif['Comments']) && trim($exif['Comments']) != $meta['title']) {
             $meta['caption'] = trim($exif['Comments']);
         }
         if (empty($meta['credit'])) {
             if (!empty($exif['Artist'])) {
                 $meta['credit'] = trim($exif['Artist']);
             } elseif (!empty($exif['Author'])) {
                 $meta['credit'] = trim($exif['Author']);
             }
         }
         if (empty($meta['copyright']) && !empty($exif['Copyright'])) {
             $meta['copyright'] = trim($exif['Copyright']);
         }
         if (!empty($exif['FNumber'])) {
             $meta['aperture'] = round(wp_exif_frac2dec($exif['FNumber']), 2);
         }
         if (!empty($exif['Model'])) {
             $meta['camera'] = trim($exif['Model']);
         }
         if (empty($meta['created_timestamp']) && !empty($exif['DateTimeDigitized'])) {
             $meta['created_timestamp'] = wp_exif_date2ts($exif['DateTimeDigitized']);
         }
         if (!empty($exif['FocalLength'])) {
             $meta['focal_length'] = (string) wp_exif_frac2dec($exif['FocalLength']);
         }
         if (!empty($exif['ISOSpeedRatings'])) {
             $meta['iso'] = is_array($exif['ISOSpeedRatings']) ? reset($exif['ISOSpeedRatings']) : $exif['ISOSpeedRatings'];
             $meta['iso'] = trim($meta['iso']);
         }
         if (!empty($exif['ExposureTime'])) {
             $meta['shutter_speed'] = (string) wp_exif_frac2dec($exif['ExposureTime']);
         }
         if (!empty($exif['Orientation'])) {
             $meta['orientation'] = $exif['Orientation'];
         }
     }
     foreach (array('title', 'caption', 'credit', 'copyright', 'camera', 'iso') as $key) {
         if ($meta[$key] && !seems_utf8($meta[$key])) {
             $meta[$key] = utf8_encode($meta[$key]);
         }
     }
     foreach ($meta as &$value) {
         if (is_string($value)) {
             $value = wp_kses_post($value);
         }
     }
     return $meta;
 }
 /**
  * @param string $path
  * @param bool $include_hidden
  * @param bool $recursive
  * @return bool|array
  */
 public function dirlist($path = '.', $include_hidden = true, $recursive = false)
 {
     if ($this->is_file($path)) {
         $limit_file = basename($path);
         $path = dirname($path) . '/';
     } else {
         $limit_file = false;
     }
     mbstring_binary_safe_encoding();
     $list = $this->ftp->dirlist($path);
     if (empty($list) && !$this->exists($path)) {
         reset_mbstring_encoding();
         return false;
     }
     $ret = array();
     foreach ($list as $struc) {
         if ('.' == $struc['name'] || '..' == $struc['name']) {
             continue;
         }
         if (!$include_hidden && '.' == $struc['name'][0]) {
             continue;
         }
         if ($limit_file && $struc['name'] != $limit_file) {
             continue;
         }
         if ('d' == $struc['type']) {
             if ($recursive) {
                 $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
             } else {
                 $struc['files'] = array();
             }
         }
         // Replace symlinks formatted as "source -> target" with just the source name
         if ($struc['islink']) {
             $struc['name'] = preg_replace('/(\\s*->\\s*.*)$/', '', $struc['name']);
         }
         $ret[$struc['name']] = $struc;
     }
     reset_mbstring_encoding();
     return $ret;
 }
Exemplo n.º 6
0
 /**
  * Update or append the requested file with the supplied contents.
  *
  * @since 1.15.0
  *
  * @param string $file     Full path to config file to update.
  * @param string $contents Contents to write to the file.
  * @param bool   $append   Optional. Set to true to append contents to the file. Defaults to false.
  * @return bool|WP_Error Boolean true on success, WP_Error object otherwise.
  */
 public static function write($file, $contents, $append = false)
 {
     $callable = array();
     if (ITSEC_Lib_Utility::is_callable_function('fopen') && ITSEC_Lib_Utility::is_callable_function('fwrite') && ITSEC_Lib_Utility::is_callable_function('flock')) {
         $callable[] = 'fopen';
     }
     if (ITSEC_Lib_Utility::is_callable_function('file_put_contents')) {
         $callable[] = 'file_put_contents';
     }
     if (empty($callable)) {
         return new WP_Error('itsec-lib-file-write-no-callable-functions', sprintf(__('%s could not be written. Both the fopen/fwrite/flock and file_put_contents functions are disabled on the server. This is a server configuration issue that must be resolved before iThemes Security can write files.', 'it-l10n-better-wp-security'), $file));
     }
     if (ITSEC_Lib_Directory::is_dir($file)) {
         return new WP_Error('itsec-lib-file-write-path-exists-as-directory', sprintf(__('%s could not be written as a file. The requested path already exists as a directory. The directory must be removed or a new file name must be chosen before the file can be written.', 'it-l10n-better-wp-security'), $file));
     }
     if (!ITSEC_Lib_Directory::is_dir(dirname($file))) {
         $result = ITSEC_Lib_Directory::create(dirname($file));
         if (is_wp_error($result)) {
             return $result;
         }
     }
     $file_existed = self::is_file($file);
     $success = false;
     // Different permissions to try in case the starting set of permissions are prohibiting write.
     $trial_perms = array(false, 0644, 0664, 0666);
     foreach ($trial_perms as $perms) {
         if (false !== $perms) {
             if (!isset($original_file_perms)) {
                 $original_file_perms = self::get_permissions($file);
             }
             self::chmod($file, $perms);
         }
         if (in_array('fopen', $callable)) {
             if ($append) {
                 $mode = 'ab';
             } else {
                 $mode = 'wb';
             }
             if (false !== ($fh = @fopen($file, $mode))) {
                 flock($fh, LOCK_EX);
                 mbstring_binary_safe_encoding();
                 $data_length = strlen($contents);
                 $bytes_written = @fwrite($fh, $contents);
                 reset_mbstring_encoding();
                 @flock($fh, LOCK_UN);
                 @fclose($fh);
                 if ($data_length === $bytes_written) {
                     $success = true;
                 }
             }
         }
         if (!$success && in_array('file_put_contents', $callable)) {
             if ($append) {
                 $flags = FILE_APPEND;
             } else {
                 $flags = 0;
             }
             mbstring_binary_safe_encoding();
             $data_length = strlen($contents);
             $bytes_written = @file_put_contents($file, $contents, $flags);
             reset_mbstring_encoding();
             if ($data_length === $bytes_written) {
                 $success = true;
             }
         }
         if ($success) {
             if (!$file_existed) {
                 // Set default file permissions for the new file.
                 self::chmod($file, self::get_default_permissions());
             } else {
                 if (isset($original_file_perms) && !is_wp_error($original_file_perms)) {
                     // Reset the original file permissions if they were modified.
                     self::chmod($file, $original_file_perms);
                 }
             }
             return true;
         }
         if (!$file_existed) {
             // If the file is new, there is no point attempting different permissions.
             break;
         }
     }
     return new WP_Error('itsec-lib-file-write-file-put-contents-failed', sprintf(__('%s could not be written. This could be due to a permissions issue. Ensure that PHP runs as a user that has permission to write to this location.', 'it-l10n-better-wp-security'), $file));
 }
Exemplo n.º 7
0
/**
 * This function should not be called directly, use unzip_file instead. Attempts to unzip an archive using the PclZip library.
 * Assumes that WP_Filesystem() has already been called and set up.
 *
 * @since 3.0.0
 * @see unzip_file
 * @access private
 *
 * @global WP_Filesystem_Base $wp_filesystem Subclass
 *
 * @param string $file Full path and filename of zip archive
 * @param string $to Full path on the filesystem to extract archive to
 * @param array $needed_dirs A partial list of required folders needed to be created.
 * @return mixed WP_Error on failure, True on success
 */
function _unzip_file_pclzip($file, $to, $needed_dirs = array()) {
	global $wp_filesystem;

	mbstring_binary_safe_encoding();

	require_once(ABSPATH . 'wp-admin/includes/class-pclzip.php');

	$archive = new PclZip($file);

	$archive_files = $archive->extract(PCLZIP_OPT_EXTRACT_AS_STRING);

	reset_mbstring_encoding();

	// Is the archive valid?
	if ( !is_array($archive_files) )
		return new WP_Error('incompatible_archive', __('Incompatible Archive.'), $archive->errorInfo(true));

	if ( 0 == count($archive_files) )
		return new WP_Error( 'empty_archive_pclzip', __( 'Empty archive.' ) );

	$uncompressed_size = 0;

	// Determine any children directories needed (From within the archive)
	foreach ( $archive_files as $file ) {
		if ( '__MACOSX/' === substr($file['filename'], 0, 9) ) // Skip the OS X-created __MACOSX directory
			continue;

		$uncompressed_size += $file['size'];

		$needed_dirs[] = $to . untrailingslashit( $file['folder'] ? $file['filename'] : dirname($file['filename']) );
	}

	/*
	 * disk_free_space() could return false. Assume that any falsey value is an error.
	 * A disk that has zero free bytes has bigger problems.
	 * Require we have enough space to unzip the file and copy its contents, with a 10% buffer.
	 */
	if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
		$available_space = @disk_free_space( WP_CONTENT_DIR );
		if ( $available_space && ( $uncompressed_size * 2.1 ) > $available_space )
			return new WP_Error( 'disk_full_unzip_file', __( 'Could not copy files. You may have run out of disk space.' ), compact( 'uncompressed_size', 'available_space' ) );
	}

	$needed_dirs = array_unique($needed_dirs);
	foreach ( $needed_dirs as $dir ) {
		// Check the parent folders of the folders all exist within the creation array.
		if ( untrailingslashit($to) == $dir ) // Skip over the working directory, We know this exists (or will exist)
			continue;
		if ( strpos($dir, $to) === false ) // If the directory is not within the working directory, Skip it
			continue;

		$parent_folder = dirname($dir);
		while ( !empty($parent_folder) && untrailingslashit($to) != $parent_folder && !in_array($parent_folder, $needed_dirs) ) {
			$needed_dirs[] = $parent_folder;
			$parent_folder = dirname($parent_folder);
		}
	}
	asort($needed_dirs);

	// Create those directories if need be:
	foreach ( $needed_dirs as $_dir ) {
		// Only check to see if the dir exists upon creation failure. Less I/O this way.
		if ( ! $wp_filesystem->mkdir( $_dir, FS_CHMOD_DIR ) && ! $wp_filesystem->is_dir( $_dir ) )
			return new WP_Error( 'mkdir_failed_pclzip', __( 'Could not create directory.' ), substr( $_dir, strlen( $to ) ) );
	}
	unset($needed_dirs);

	// Extract the files from the zip
	foreach ( $archive_files as $file ) {
		if ( $file['folder'] )
			continue;

		if ( '__MACOSX/' === substr($file['filename'], 0, 9) ) // Don't extract the OS X-created __MACOSX directory files
			continue;

		if ( ! $wp_filesystem->put_contents( $to . $file['filename'], $file['content'], FS_CHMOD_FILE) )
			return new WP_Error( 'copy_failed_pclzip', __( 'Could not copy file.' ), $file['filename'] );
	}
	return true;
}
Exemplo n.º 8
0
    /**
     * Strips any invalid characters based on value/charset pairs.
     *
     * @since 4.2.0
     * @access protected
     *
     * @param array $data Array of value arrays. Each value array has the keys
     *                    'value' and 'charset'. An optional 'ascii' key can be
     *                    set to false to avoid redundant ASCII checks.
     * @return array|WP_Error The $data parameter, with invalid characters removed from
     *                        each value. This works as a passthrough: any additional keys
     *                        such as 'field' are retained in each value array. If we cannot
     *                        remove invalid characters, a WP_Error object is returned.
     */
    protected function strip_invalid_text($data)
    {
        $db_check_string = false;
        foreach ($data as &$value) {
            $charset = $value['charset'];
            if (is_array($value['length'])) {
                $length = $value['length']['length'];
                $truncate_by_byte_length = 'byte' === $value['length']['type'];
            } else {
                $length = false;
                // Since we have no length, we'll never truncate.
                // Initialize the variable to false. true would take us
                // through an unnecessary (for this case) codepath below.
                $truncate_by_byte_length = false;
            }
            // There's no charset to work with.
            if (false === $charset) {
                continue;
            }
            // Column isn't a string.
            if (!is_string($value['value'])) {
                continue;
            }
            $needs_validation = true;
            if ('latin1' === $charset || !isset($value['ascii']) && $this->check_ascii($value['value'])) {
                $truncate_by_byte_length = true;
                $needs_validation = false;
            }
            if ($truncate_by_byte_length) {
                mbstring_binary_safe_encoding();
                if (false !== $length && strlen($value['value']) > $length) {
                    $value['value'] = substr($value['value'], 0, $length);
                }
                reset_mbstring_encoding();
                if (!$needs_validation) {
                    continue;
                }
            }
            // utf8 can be handled by regex, which is a bunch faster than a DB lookup.
            if (('utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset) && function_exists('mb_strlen')) {
                $regex = '/
					(
						(?: [\\x00-\\x7F]                  # single-byte sequences   0xxxxxxx
						|   [\\xC2-\\xDF][\\x80-\\xBF]       # double-byte sequences   110xxxxx 10xxxxxx
						|   \\xE0[\\xA0-\\xBF][\\x80-\\xBF]   # triple-byte sequences   1110xxxx 10xxxxxx * 2
						|   [\\xE1-\\xEC][\\x80-\\xBF]{2}
						|   \\xED[\\x80-\\x9F][\\x80-\\xBF]
						|   [\\xEE-\\xEF][\\x80-\\xBF]{2}';
                if ('utf8mb4' === $charset) {
                    $regex .= '
						|    \\xF0[\\x90-\\xBF][\\x80-\\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
						|    [\\xF1-\\xF3][\\x80-\\xBF]{3}
						|    \\xF4[\\x80-\\x8F][\\x80-\\xBF]{2}
					';
                }
                $regex .= '){1,40}                          # ...one or more times
					)
					| .                                  # anything else
					/x';
                $value['value'] = preg_replace($regex, '$1', $value['value']);
                if (false !== $length && mb_strlen($value['value'], 'UTF-8') > $length) {
                    $value['value'] = mb_substr($value['value'], 0, $length, 'UTF-8');
                }
                continue;
            }
            // We couldn't use any local conversions, send it to the DB.
            $value['db'] = $db_check_string = true;
        }
        unset($value);
        // Remove by reference.
        if ($db_check_string) {
            $queries = array();
            foreach ($data as $col => $value) {
                if (!empty($value['db'])) {
                    // We're going to need to truncate by characters or bytes, depending on the length value we have.
                    if ('byte' === $value['length']['type']) {
                        // Using binary causes LEFT() to truncate by bytes.
                        $charset = 'binary';
                    } else {
                        $charset = $value['charset'];
                    }
                    if (is_array($value['length'])) {
                        $queries[$col] = $this->prepare("CONVERT( LEFT( CONVERT( %s USING {$charset} ), %.0f ) USING {$this->charset} )", $value['value'], $value['length']['length']);
                    } else {
                        if ('binary' !== $charset) {
                            // If we don't have a length, there's no need to convert binary - it will always return the same result.
                            $queries[$col] = $this->prepare("CONVERT( CONVERT( %s USING {$charset} ) USING {$this->charset} )", $value['value']);
                        }
                    }
                    unset($data[$col]['db']);
                }
            }
            $sql = array();
            foreach ($queries as $column => $query) {
                if (!$query) {
                    continue;
                }
                $sql[] = $query . " AS x_{$column}";
            }
            $this->check_current_query = false;
            $row = $this->get_row("SELECT " . implode(', ', $sql), ARRAY_A);
            if (!$row) {
                return new WP_Error('wpdb_strip_invalid_text_failure');
            }
            foreach (array_keys($data) as $column) {
                $data[$column]['value'] = $row["x_{$column}"];
            }
        }
        return $data;
    }
Exemplo n.º 9
0
    /**
     * Strips any invalid characters based on value/charset pairs.
     *
     * @since 4.2.0
     * @access protected
     *
     * @param array $data Array of value arrays. Each value array has the keys
     *                    'value' and 'charset'. An optional 'ascii' key can be
     *                    set to false to avoid redundant ASCII checks.
     * @return array|WP_Error The $data parameter, with invalid characters removed from
     *                        each value. This works as a passthrough: any additional keys
     *                        such as 'field' are retained in each value array. If we cannot
     *                        remove invalid characters, a WP_Error object is returned.
     */
    protected function strip_invalid_text($data)
    {
        $db_check_string = false;
        foreach ($data as &$value) {
            $charset = $value['charset'];
            if (is_array($value['length'])) {
                $length = $value['length']['length'];
            } else {
                $length = false;
            }
            // There's no charset to work with.
            if (false === $charset) {
                continue;
            }
            // Column isn't a string.
            if (!is_string($value['value'])) {
                continue;
            }
            $truncate_by_byte_length = 'byte' === $value['length']['type'];
            $needs_validation = true;
            if ('latin1' === $charset || !isset($value['ascii']) && $this->check_ascii($value['value'])) {
                $truncate_by_byte_length = true;
                $needs_validation = false;
            }
            if ($truncate_by_byte_length) {
                mbstring_binary_safe_encoding();
                if (false !== $length && strlen($value['value']) > $length) {
                    $value['value'] = substr($value['value'], 0, $length);
                }
                reset_mbstring_encoding();
                if (!$needs_validation) {
                    continue;
                }
            }
            // utf8 can be handled by regex, which is a bunch faster than a DB lookup.
            if (('utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset) && function_exists('mb_strlen')) {
                $regex = '/
					(
						(?: [\\x00-\\x7F]                  # single-byte sequences   0xxxxxxx
						|   [\\xC2-\\xDF][\\x80-\\xBF]       # double-byte sequences   110xxxxx 10xxxxxx
						|   \\xE0[\\xA0-\\xBF][\\x80-\\xBF]   # triple-byte sequences   1110xxxx 10xxxxxx * 2
						|   [\\xE1-\\xEC][\\x80-\\xBF]{2}
						|   \\xED[\\x80-\\x9F][\\x80-\\xBF]
						|   [\\xEE-\\xEF][\\x80-\\xBF]{2}';
                if ('utf8mb4' === $charset) {
                    $regex .= '
						|    \\xF0[\\x90-\\xBF][\\x80-\\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
						|    [\\xF1-\\xF3][\\x80-\\xBF]{3}
						|    \\xF4[\\x80-\\x8F][\\x80-\\xBF]{2}
					';
                }
                $regex .= '){1,40}                          # ...one or more times
					)
					| .                                  # anything else
					/x';
                $value['value'] = preg_replace($regex, '$1', $value['value']);
                if (false !== $length && mb_strlen($value['value'], 'UTF-8') > $length) {
                    $value['value'] = mb_substr($value['value'], 0, $length, 'UTF-8');
                }
                continue;
            }
            // We couldn't use any local conversions, send it to the DB.
            $value['db'] = $db_check_string = true;
        }
        unset($value);
        // Remove by reference.
        if ($db_check_string) {
            $queries = array();
            foreach ($data as $col => $value) {
                if (!empty($value['db'])) {
                    if (!isset($queries[$value['charset']])) {
                        $queries[$value['charset']] = array();
                    }
                    // We're going to need to truncate by characters or bytes, depending on the length value we have.
                    if ('byte' === $value['length']['type']) {
                        // Split the CONVERT() calls by charset, so we can make sure the connection is right
                        $queries[$value['charset']][$col] = $this->prepare("CONVERT( LEFT( CONVERT( %s USING binary ), %d ) USING {$value['charset']} )", $value['value'], $value['length']['length']);
                    } else {
                        $queries[$value['charset']][$col] = $this->prepare("LEFT( CONVERT( %s USING {$value['charset']} ), %d )", $value['value'], $value['length']['length']);
                    }
                    unset($data[$col]['db']);
                }
            }
            $connection_charset = $this->charset;
            foreach ($queries as $charset => $query) {
                if (!$query) {
                    continue;
                }
                // Change the charset to match the string(s) we're converting
                if ($charset !== $connection_charset) {
                    $connection_charset = $charset;
                    $this->set_charset($this->dbh, $charset);
                }
                $this->check_current_query = false;
                $sql = array();
                foreach ($query as $column => $column_query) {
                    $sql[] = $column_query . " AS x_{$column}";
                }
                $row = $this->get_row("SELECT " . implode(', ', $sql), ARRAY_A);
                if (!$row) {
                    $this->set_charset($this->dbh, $connection_charset);
                    return new WP_Error('wpdb_strip_invalid_text_failure');
                }
                foreach (array_keys($query) as $column) {
                    $data[$column]['value'] = $row["x_{$column}"];
                }
            }
            // Don't forget to change the charset back!
            if ($connection_charset !== $this->charset) {
                $this->set_charset($this->dbh);
            }
        }
        return $data;
    }
 public function zip_export_data($is_backup = false)
 {
     $uploads_path = $this->get_wp_upload_dir();
     $zip_path = $this->get_upload_dir();
     if ($is_backup) {
         $zip_path = $uploads_path . 'tmm_backup/';
     }
     $tables = $this->get_wp_tables();
     $zip_filename = $zip_path . self::folder_key . '.zip';
     global $wpdb;
     file_put_contents($zip_path . 'wpdb.prfx', $wpdb->prefix);
     mbstring_binary_safe_encoding();
     require_once ABSPATH . 'wp-admin/includes/class-pclzip.php';
     $zip = new PclZip($zip_filename);
     if (!empty($tables)) {
         foreach ($tables as $table) {
             $file = $table . '.dat';
             $zip->add($zip_path . $file, PCLZIP_OPT_REMOVE_PATH, $zip_path);
             $file = $table . '.dsc';
             $zip->add($zip_path . $file, PCLZIP_OPT_REMOVE_PATH, $zip_path);
         }
     }
     $zip->add($zip_path . 'wpdb.prfx', PCLZIP_OPT_REMOVE_PATH, $zip_path);
     @$zip->create();
     reset_mbstring_encoding();
     foreach ($tables as $table) {
         if (file_exists($zip_path . $table . '.dsc')) {
             unlink($zip_path . $table . '.dsc');
         }
         if (file_exists($zip_path . $table . '.dat')) {
             unlink($zip_path . $table . '.dat');
         }
     }
     if (file_exists($zip_path . 'wpdb.prfx')) {
         unlink($zip_path . 'wpdb.prfx');
     }
     if (!$is_backup) {
         wp_die($this->get_zip_file_url());
     }
 }
/**
 * Encode the Unicode values to be used in the URI.
 *
 * @since 1.5.0
 *
 * @param string $utf8_string
 * @param int $length Max length of the string
 * @return string String with Unicode encoded for URI.
 */
function utf8_uri_encode( $utf8_string, $length = 0 ) {
	$unicode = '';
	$values = array();
	$num_octets = 1;
	$unicode_length = 0;

	mbstring_binary_safe_encoding();
	$string_length = strlen( $utf8_string );
	reset_mbstring_encoding();

	for ($i = 0; $i < $string_length; $i++ ) {

		$value = ord( $utf8_string[ $i ] );

		if ( $value < 128 ) {
			if ( $length && ( $unicode_length >= $length ) )
				break;
			$unicode .= chr($value);
			$unicode_length++;
		} else {
			if ( count( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3;

			$values[] = $value;

			if ( $length && ( $unicode_length + ($num_octets * 3) ) > $length )
				break;
			if ( count( $values ) == $num_octets ) {
				if ($num_octets == 3) {
					$unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]);
					$unicode_length += 9;
				} else {
					$unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]);
					$unicode_length += 6;
				}

				$values = array();
				$num_octets = 1;
			}
		}
	}

	return $unicode;
}
Exemplo n.º 12
0
 function export_zip_file($file, $source)
 {
     if (file_exists($file)) {
         unlink($file);
     }
     mbstring_binary_safe_encoding();
     // PclZip ships with WordPress
     require_once ABSPATH . 'wp-admin/includes/class-pclzip.php';
     $archive = new PclZip($file);
     if ($response = $archive->create($source, PCLZIP_OPT_REMOVE_PATH, dirname($source))) {
         reset_mbstring_encoding();
         header('Content-Description: File Transfer');
         header('Content-Type: application/octet-stream');
         header('Content-Length: ' . filesize($file));
         header('Content-Disposition: attachment; filename=' . basename($file));
         header('Expires: 0');
         header('Cache-Control: must-revalidate');
         header('Pragma: public');
         readfile($file);
         unlink($file);
         die;
     } else {
         $this->errors[] = __('PclZip returned zero bytes.', 'child-theme-configurator');
     }
 }
 /**
  * Truncate string as utf8
  *
  * @see http://jetpack.wp-a2z.org/oik_api/mbstring_binary_safe_encoding/
  * @link https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php
  * @link https://core.trac.wordpress.org/browser/trunk/src/wp-includes/functions.php
  */
 private static function truncate_utf8($str, $regexp = NULL, $replace = '', $len = IP_GEO_BLOCK_MAX_STR_LEN)
 {
     // remove unnecessary characters
     $str = preg_replace('/[\\x00-\\x1f\\x7f]/', '', $str);
     if ($regexp) {
         $str = preg_replace($regexp, $replace, $str);
     }
     // limit the length of the string
     if (function_exists('mb_strcut')) {
         mbstring_binary_safe_encoding();
         // @since 3.7.0
         if (strlen($str) > $len) {
             $str = mb_strcut($str, 0, $len) . '…';
         }
         reset_mbstring_encoding();
         // @since 3.7.0
     } else {
         // https://core.trac.wordpress.org/ticket/25259
         mbstring_binary_safe_encoding();
         // @since 3.7.0
         $original = strlen($str);
         $str = substr($str, 0, $len);
         $length = strlen($str);
         reset_mbstring_encoding();
         // @since 3.7.0
         if ($length !== $original) {
             // bit pattern from seems_utf8() in wp-includes/formatting.php
             static $code = array(array(0x80, 0x0), array(0xe0, 0xc0), array(0xf0, 0xe0), array(0xf8, 0xf0), array(0xfc, 0xf8), array(0xfe, 0xfc));
             // truncate extra characters
             $len = min($length, 6);
             for ($i = 0; $i < $len; $i++) {
                 $c = ord($str[$length - 1 - $i]);
                 for ($j = $i; $j < 6; $j++) {
                     if (($c & $code[$j][0]) == $code[$j][1]) {
                         mbstring_binary_safe_encoding();
                         // @since 3.7.0
                         $str = substr($str, 0, $length - (int) ($j > 0) - $i);
                         reset_mbstring_encoding();
                         // @since 3.7.0
                         // validate whole characters
                         $str = self::validate_utf8($str);
                         return '…' !== $str ? "{$str}…" : '…';
                     }
                 }
             }
             // $str may not fit utf8
             return '…';
         }
     }
     // validate whole characters
     return self::validate_utf8($str);
 }
Exemplo n.º 14
0
/**
 * This function should not be called directly, use unzip_file instead. Attempts to unzip an archive using the PclZip library.
 * Assumes that WP_Filesystem() has already been called and set up.
 *
 * @since 3.0.0
 * @see unzip_file
 * @access private
 *
 * @param string $file Full path and filename of zip archive
 * @param string $to Full path on the filesystem to extract archive to
 * @param array $needed_dirs A partial list of required folders needed to be created.
 * @return mixed WP_Error on failure, True on success
 */
function _unzip_file_pclzip($file, $to, $needed_dirs = array())
{
    global $wp_filesystem;
    mbstring_binary_safe_encoding();
    require_once ABSPATH . 'wp-admin/includes/class-pclzip.php';
    $archive = new PclZip($file);
    $archive_files = $archive->extract(PCLZIP_OPT_EXTRACT_AS_STRING);
    reset_mbstring_encoding();
    // Is the archive valid?
    if (!is_array($archive_files)) {
        return new WP_Error('incompatible_archive', __('Incompatible Archive.'), $archive->errorInfo(true));
    }
    if (0 == count($archive_files)) {
        return new WP_Error('empty_archive', __('Empty archive.'));
    }
    // Determine any children directories needed (From within the archive)
    foreach ($archive_files as $file) {
        if ('__MACOSX/' === substr($file['filename'], 0, 9)) {
            // Skip the OS X-created __MACOSX directory
            continue;
        }
        $needed_dirs[] = $to . untrailingslashit($file['folder'] ? $file['filename'] : dirname($file['filename']));
    }
    $needed_dirs = array_unique($needed_dirs);
    foreach ($needed_dirs as $dir) {
        // Check the parent folders of the folders all exist within the creation array.
        if (untrailingslashit($to) == $dir) {
            // Skip over the working directory, We know this exists (or will exist)
            continue;
        }
        if (strpos($dir, $to) === false) {
            // If the directory is not within the working directory, Skip it
            continue;
        }
        $parent_folder = dirname($dir);
        while (!empty($parent_folder) && untrailingslashit($to) != $parent_folder && !in_array($parent_folder, $needed_dirs)) {
            $needed_dirs[] = $parent_folder;
            $parent_folder = dirname($parent_folder);
        }
    }
    asort($needed_dirs);
    // Create those directories if need be:
    foreach ($needed_dirs as $_dir) {
        if (!$wp_filesystem->mkdir($_dir, FS_CHMOD_DIR) && !$wp_filesystem->is_dir($_dir)) {
            // Only check to see if the dir exists upon creation failure. Less I/O this way.
            return new WP_Error('mkdir_failed', __('Could not create directory.'), $_dir);
        }
    }
    unset($needed_dirs);
    // Extract the files from the zip
    foreach ($archive_files as $file) {
        if ($file['folder']) {
            continue;
        }
        if ('__MACOSX/' === substr($file['filename'], 0, 9)) {
            // Don't extract the OS X-created __MACOSX directory files
            continue;
        }
        if (!$wp_filesystem->put_contents($to . $file['filename'], $file['content'], FS_CHMOD_FILE)) {
            return new WP_Error('copy_failed', __('Could not copy file.'), $to . $file['filename']);
        }
    }
    return true;
}
 /**
  * Send an HTTP request to a URI.
  *
  * Please note: The only URI that are supported in the HTTP Transport implementation
  * are the HTTP and HTTPS protocols.
  *
  * @access public
  * @since 2.7.0
  *
  * @param string       $url  The request URL.
  * @param string|array $args {
  *     Optional. Array or string of HTTP request arguments.
  *
  *     @type string       $method              Request method. Accepts 'GET', 'POST', 'HEAD', or 'PUT'.
  *                                             Some transports technically allow others, but should not be
  *                                             assumed. Default 'GET'.
  *     @type int          $timeout             How long the connection should stay open in seconds. Default 5.
  *     @type int          $redirection         Number of allowed redirects. Not supported by all transports
  *                                             Default 5.
  *     @type string       $httpversion         Version of the HTTP protocol to use. Accepts '1.0' and '1.1'.
  *                                             Default '1.0'.
  *     @type string       $user-agent          User-agent value sent.
  *                                             Default WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ).
  *     @type bool         $reject_unsafe_urls  Whether to pass URLs through wp_http_validate_url().
  *                                             Default false.
  *     @type bool         $blocking            Whether the calling code requires the result of the request.
  *                                             If set to false, the request will be sent to the remote server,
  *                                             and processing returned to the calling code immediately, the caller
  *                                             will know if the request succeeded or failed, but will not receive
  *                                             any response from the remote server. Default true.
  *     @type string|array $headers             Array or string of headers to send with the request.
  *                                             Default empty array.
  *     @type array        $cookies             List of cookies to send with the request. Default empty array.
  *     @type string|array $body                Body to send with the request. Default null.
  *     @type bool         $compress            Whether to compress the $body when sending the request.
  *                                             Default false.
  *     @type bool         $decompress          Whether to decompress a compressed response. If set to false and
  *                                             compressed content is returned in the response anyway, it will
  *                                             need to be separately decompressed. Default true.
  *     @type bool         $sslverify           Whether to verify SSL for the request. Default true.
  *     @type string       sslcertificates      Absolute path to an SSL certificate .crt file.
  *                                             Default ABSPATH . WPINC . '/certificates/ca-bundle.crt'.
  *     @type bool         $stream              Whether to stream to a file. If set to true and no filename was
  *                                             given, it will be droped it in the WP temp dir and its name will
  *                                             be set using the basename of the URL. Default false.
  *     @type string       $filename            Filename of the file to write to when streaming. $stream must be
  *                                             set to true. Default null.
  *     @type int          $limit_response_size Size in bytes to limit the response to. Default null.
  *
  * }
  * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'.
  *                        A WP_Error instance upon error.
  */
 public function request($url, $args = array())
 {
     $defaults = array('method' => 'GET', 'timeout' => apply_filters('http_request_timeout', 5), 'redirection' => apply_filters('http_request_redirection_count', 5), 'httpversion' => apply_filters('http_request_version', '1.0'), 'user-agent' => apply_filters('http_headers_useragent', 'WordPress/' . get_bloginfo('version') . '; ' . get_bloginfo('url')), 'reject_unsafe_urls' => apply_filters('http_request_reject_unsafe_urls', false), 'blocking' => true, 'headers' => array(), 'cookies' => array(), 'body' => null, 'compress' => false, 'decompress' => true, 'sslverify' => true, 'sslcertificates' => ABSPATH . WPINC . '/certificates/ca-bundle.crt', 'stream' => false, 'filename' => null, 'limit_response_size' => null);
     // Pre-parse for the HEAD checks.
     $args = wp_parse_args($args);
     // By default, Head requests do not cause redirections.
     if (isset($args['method']) && 'HEAD' == $args['method']) {
         $defaults['redirection'] = 0;
     }
     $r = wp_parse_args($args, $defaults);
     /**
      * Filters the arguments used in an HTTP request.
      *
      * @since 2.7.0
      *
      * @param array  $r   An array of HTTP request arguments.
      * @param string $url The request URL.
      */
     $r = apply_filters('http_request_args', $r, $url);
     // The transports decrement this, store a copy of the original value for loop purposes.
     if (!isset($r['_redirection'])) {
         $r['_redirection'] = $r['redirection'];
     }
     /**
      * Filters whether to preempt an HTTP request's return value.
      *
      * Returning a non-false value from the filter will short-circuit the HTTP request and return
      * early with that value. A filter should return either:
      *
      *  - An array containing 'headers', 'body', 'response', 'cookies', and 'filename' elements
      *  - A WP_Error instance
      *  - boolean false (to avoid short-circuiting the response)
      *
      * Returning any other value may result in unexpected behaviour.
      *
      * @since 2.9.0
      *
      * @param false|array|WP_Error $preempt Whether to preempt an HTTP request's return value. Default false.
      * @param array               $r        HTTP request arguments.
      * @param string              $url      The request URL.
      */
     $pre = apply_filters('pre_http_request', false, $r, $url);
     if (false !== $pre) {
         return $pre;
     }
     if (function_exists('wp_kses_bad_protocol')) {
         if ($r['reject_unsafe_urls']) {
             $url = wp_http_validate_url($url);
         }
         if ($url) {
             $url = wp_kses_bad_protocol($url, array('http', 'https', 'ssl'));
         }
     }
     $arrURL = @parse_url($url);
     if (empty($url) || empty($arrURL['scheme'])) {
         return new WP_Error('http_request_failed', __('A valid URL was not provided.'));
     }
     if ($this->block_request($url)) {
         return new WP_Error('http_request_failed', __('User has blocked requests through HTTP.'));
     }
     // If we are streaming to a file but no filename was given drop it in the WP temp dir
     // and pick its name using the basename of the $url
     if ($r['stream']) {
         if (empty($r['filename'])) {
             $r['filename'] = get_temp_dir() . basename($url);
         }
         // Force some settings if we are streaming to a file and check for existence and perms of destination directory
         $r['blocking'] = true;
         if (!wp_is_writable(dirname($r['filename']))) {
             return new WP_Error('http_request_failed', __('Destination directory for file streaming does not exist or is not writable.'));
         }
     }
     if (is_null($r['headers'])) {
         $r['headers'] = array();
     }
     // WP allows passing in headers as a string, weirdly.
     if (!is_array($r['headers'])) {
         $processedHeaders = WP_Http::processHeaders($r['headers']);
         $r['headers'] = $processedHeaders['headers'];
     }
     // Setup arguments
     $headers = $r['headers'];
     $data = $r['body'];
     $type = $r['method'];
     $options = array('timeout' => $r['timeout'], 'useragent' => $r['user-agent'], 'blocking' => $r['blocking'], 'hooks' => new WP_HTTP_Requests_Hooks($url, $r));
     // Ensure redirects follow browser behaviour.
     $options['hooks']->register('requests.before_redirect', array(get_class(), 'browser_redirect_compatibility'));
     if ($r['stream']) {
         $options['filename'] = $r['filename'];
     }
     if (empty($r['redirection'])) {
         $options['follow_redirects'] = false;
     } else {
         $options['redirects'] = $r['redirection'];
     }
     // Use byte limit, if we can
     if (isset($r['limit_response_size'])) {
         $options['max_bytes'] = $r['limit_response_size'];
     }
     // If we've got cookies, use and convert them to Requests_Cookie.
     if (!empty($r['cookies'])) {
         $options['cookies'] = WP_Http::normalize_cookies($r['cookies']);
     }
     // SSL certificate handling
     if (!$r['sslverify']) {
         $options['verify'] = false;
         $options['verifyname'] = false;
     } else {
         $options['verify'] = $r['sslcertificates'];
     }
     // All non-GET/HEAD requests should put the arguments in the form body.
     if ('HEAD' !== $type && 'GET' !== $type) {
         $options['data_format'] = 'body';
     }
     /**
      * Filters whether SSL should be verified for non-local requests.
      *
      * @since 2.8.0
      *
      * @param bool $ssl_verify Whether to verify the SSL connection. Default true.
      */
     $options['verify'] = apply_filters('https_ssl_verify', $options['verify']);
     // Check for proxies.
     $proxy = new WP_HTTP_Proxy();
     if ($proxy->is_enabled() && $proxy->send_through_proxy($url)) {
         $options['proxy'] = new Requests_Proxy_HTTP($proxy->host() . ':' . $proxy->port());
         if ($proxy->use_authentication()) {
             $options['proxy']->use_authentication = true;
             $options['proxy']->user = $proxy->username();
             $options['proxy']->pass = $proxy->password();
         }
     }
     // Avoid issues where mbstring.func_overload is enabled
     mbstring_binary_safe_encoding();
     try {
         $requests_response = Requests::request($url, $headers, $data, $type, $options);
         // Convert the response into an array
         $http_response = new WP_HTTP_Requests_Response($requests_response, $r['filename']);
         $response = $http_response->to_array();
         // Add the original object to the array.
         $response['http_response'] = $http_response;
     } catch (Requests_Exception $e) {
         $response = new WP_Error('http_request_failed', $e->getMessage());
     }
     reset_mbstring_encoding();
     /**
      * Fires after an HTTP API response is received and before the response is returned.
      *
      * @since 2.8.0
      *
      * @param array|WP_Error $response HTTP response or WP_Error object.
      * @param string         $context  Context under which the hook is fired.
      * @param string         $class    HTTP transport used.
      * @param array          $args     HTTP request arguments.
      * @param string         $url      The request URL.
      */
     do_action('http_api_debug', $response, 'response', 'Requests', $r, $url);
     if (is_wp_error($response)) {
         return $response;
     }
     if (!$r['blocking']) {
         return array('headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array(), 'http_response' => null);
     }
     /**
      * Filters the HTTP API response immediately before the response is returned.
      *
      * @since 2.9.0
      *
      * @param array  $response HTTP response.
      * @param array  $r        HTTP request arguments.
      * @param string $url      The request URL.
      */
     return apply_filters('http_response', $response, $r, $url);
 }
 /**
  * @access public
  *
  * @param string $file
  * @param string $contents
  * @param int|bool $mode
  * @return bool
  */
 public function put_contents($file, $contents, $mode = false)
 {
     $temp = wp_tempnam($file);
     if (!($temphandle = @fopen($temp, 'w+'))) {
         unlink($temp);
         return false;
     }
     // The FTP class uses string functions internally during file download/upload
     mbstring_binary_safe_encoding();
     $bytes_written = fwrite($temphandle, $contents);
     if (false === $bytes_written || $bytes_written != strlen($contents)) {
         fclose($temphandle);
         unlink($temp);
         reset_mbstring_encoding();
         return false;
     }
     fseek($temphandle, 0);
     // Skip back to the start of the file being written to
     $ret = $this->ftp->fput($file, $temphandle);
     reset_mbstring_encoding();
     fclose($temphandle);
     unlink($temp);
     $this->chmod($file, $mode);
     return $ret;
 }
Exemplo n.º 17
0
/**
 * Encode the Unicode values to be used in the URI.
 *
 * @since 1.5.0
 *
 * @param string $utf8_string
 * @param int    $length Max  length of the string
 * @return string String with Unicode encoded for URI.
 */
function utf8_uri_encode($utf8_string, $length = 0)
{
    $unicode = '';
    $values = array();
    $num_octets = 1;
    $unicode_length = 0;
    mbstring_binary_safe_encoding();
    $string_length = strlen($utf8_string);
    reset_mbstring_encoding();
    for ($i = 0; $i < $string_length; $i++) {
        $value = ord($utf8_string[$i]);
        if ($value < 128) {
            if ($length && $unicode_length >= $length) {
                break;
            }
            $unicode .= chr($value);
            $unicode_length++;
        } else {
            if (count($values) == 0) {
                if ($value < 224) {
                    $num_octets = 2;
                } elseif ($value < 240) {
                    $num_octets = 3;
                } else {
                    $num_octets = 4;
                }
            }
            $values[] = $value;
            if ($length && $unicode_length + $num_octets * 3 > $length) {
                break;
            }
            if (count($values) == $num_octets) {
                for ($j = 0; $j < $num_octets; $j++) {
                    $unicode .= '%' . dechex($values[$j]);
                }
                $unicode_length += $num_octets * 3;
                $values = array();
                $num_octets = 1;
            }
        }
    }
    return $unicode;
}
Exemplo n.º 18
0
/**
 * Get extended image metadata, exif or iptc as available.
 *
 * Retrieves the EXIF metadata aperture, credit, camera, caption, copyright, iso
 * created_timestamp, focal_length, shutter_speed, and title.
 *
 * The IPTC metadata that is retrieved is APP13, credit, byline, created date
 * and time, caption, copyright, and title. Also includes FNumber, Model,
 * DateTimeDigitized, FocalLength, ISOSpeedRatings, and ExposureTime.
 *
 * @todo Try other exif libraries if available.
 * @since 2.5.0
 *
 * @param string $file
 * @return bool|array False on failure. Image metadata array on success.
 */
function wp_read_image_metadata($file)
{
    if (!file_exists($file)) {
        return false;
    }
    list(, , $sourceImageType) = getimagesize($file);
    /*
     * EXIF contains a bunch of data we'll probably never need formatted in ways
     * that are difficult to use. We'll normalize it and just extract the fields
     * that are likely to be useful. Fractions and numbers are converted to
     * floats, dates to unix timestamps, and everything else to strings.
     */
    $meta = array('aperture' => 0, 'credit' => '', 'camera' => '', 'caption' => '', 'created_timestamp' => 0, 'copyright' => '', 'focal_length' => 0, 'iso' => 0, 'shutter_speed' => 0, 'title' => '', 'orientation' => 0, 'keywords' => array());
    $iptc = array();
    /*
     * Read IPTC first, since it might contain data not available in exif such
     * as caption, description etc.
     */
    if (is_callable('iptcparse')) {
        getimagesize($file, $info);
        if (!empty($info['APP13'])) {
            $iptc = iptcparse($info['APP13']);
            // Headline, "A brief synopsis of the caption."
            if (!empty($iptc['2#105'][0])) {
                $meta['title'] = trim($iptc['2#105'][0]);
                /*
                 * Title, "Many use the Title field to store the filename of the image,
                 * though the field may be used in many ways."
                 */
            } elseif (!empty($iptc['2#005'][0])) {
                $meta['title'] = trim($iptc['2#005'][0]);
            }
            if (!empty($iptc['2#120'][0])) {
                // description / legacy caption
                $caption = trim($iptc['2#120'][0]);
                mbstring_binary_safe_encoding();
                $caption_length = strlen($caption);
                reset_mbstring_encoding();
                if (empty($meta['title']) && $caption_length < 80) {
                    // Assume the title is stored in 2:120 if it's short.
                    $meta['title'] = $caption;
                }
                $meta['caption'] = $caption;
            }
            if (!empty($iptc['2#110'][0])) {
                // credit
                $meta['credit'] = trim($iptc['2#110'][0]);
            } elseif (!empty($iptc['2#080'][0])) {
                // creator / legacy byline
                $meta['credit'] = trim($iptc['2#080'][0]);
            }
            if (!empty($iptc['2#055'][0]) && !empty($iptc['2#060'][0])) {
                // created date and time
                $meta['created_timestamp'] = strtotime($iptc['2#055'][0] . ' ' . $iptc['2#060'][0]);
            }
            if (!empty($iptc['2#116'][0])) {
                // copyright
                $meta['copyright'] = trim($iptc['2#116'][0]);
            }
            if (!empty($iptc['2#025'][0])) {
                // keywords array
                $meta['keywords'] = array_values($iptc['2#025']);
            }
        }
    }
    /**
     * Filter the image types to check for exif data.
     *
     * @since 2.5.0
     *
     * @param array $image_types Image types to check for exif data.
     */
    if (is_callable('exif_read_data') && in_array($sourceImageType, apply_filters('wp_read_image_metadata_types', array(IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM)))) {
        $exif = @exif_read_data($file);
        if (!empty($exif['ImageDescription'])) {
            mbstring_binary_safe_encoding();
            $description_length = strlen($exif['ImageDescription']);
            reset_mbstring_encoding();
            if (empty($meta['title']) && $description_length < 80) {
                // Assume the title is stored in ImageDescription
                $meta['title'] = trim($exif['ImageDescription']);
            }
            if (empty($meta['caption']) && !empty($exif['COMPUTED']['UserComment'])) {
                $meta['caption'] = trim($exif['COMPUTED']['UserComment']);
            }
            if (empty($meta['caption'])) {
                $meta['caption'] = trim($exif['ImageDescription']);
            }
        } elseif (empty($meta['caption']) && !empty($exif['Comments'])) {
            $meta['caption'] = trim($exif['Comments']);
        }
        if (empty($meta['credit'])) {
            if (!empty($exif['Artist'])) {
                $meta['credit'] = trim($exif['Artist']);
            } elseif (!empty($exif['Author'])) {
                $meta['credit'] = trim($exif['Author']);
            }
        }
        if (empty($meta['copyright']) && !empty($exif['Copyright'])) {
            $meta['copyright'] = trim($exif['Copyright']);
        }
        if (!empty($exif['FNumber'])) {
            $meta['aperture'] = round(wp_exif_frac2dec($exif['FNumber']), 2);
        }
        if (!empty($exif['Model'])) {
            $meta['camera'] = trim($exif['Model']);
        }
        if (empty($meta['created_timestamp']) && !empty($exif['DateTimeDigitized'])) {
            $meta['created_timestamp'] = wp_exif_date2ts($exif['DateTimeDigitized']);
        }
        if (!empty($exif['FocalLength'])) {
            $meta['focal_length'] = (string) wp_exif_frac2dec($exif['FocalLength']);
        }
        if (!empty($exif['ISOSpeedRatings'])) {
            $meta['iso'] = is_array($exif['ISOSpeedRatings']) ? reset($exif['ISOSpeedRatings']) : $exif['ISOSpeedRatings'];
            $meta['iso'] = trim($meta['iso']);
        }
        if (!empty($exif['ExposureTime'])) {
            $meta['shutter_speed'] = (string) wp_exif_frac2dec($exif['ExposureTime']);
        }
        if (!empty($exif['Orientation'])) {
            $meta['orientation'] = $exif['Orientation'];
        }
    }
    foreach (array('title', 'caption', 'credit', 'copyright', 'camera', 'iso') as $key) {
        if ($meta[$key] && !seems_utf8($meta[$key])) {
            $meta[$key] = utf8_encode($meta[$key]);
        }
    }
    foreach ($meta['keywords'] as $key => $keyword) {
        if (!seems_utf8($keyword)) {
            $meta['keywords'][$key] = utf8_encode($keyword);
        }
    }
    $meta = wp_kses_post_deep($meta);
    /**
     * Filter the array of meta data read from an image's exif data.
     *
     * @since 2.5.0
     * @since 4.4.0 The `$iptc` parameter was added.
     *
     * @param array  $meta            Image meta data.
     * @param string $file            Path to image file.
     * @param int    $sourceImageType Type of image.
     * @param array  $iptc            IPTC data.
     */
    return apply_filters('wp_read_image_metadata', $meta, $file, $sourceImageType, $iptc);
}
 /**
  * @param string $file
  * @param string $contents
  * @param bool|int $mode
  * @return bool
  */
 public function put_contents($file, $contents, $mode = false)
 {
     $tempfile = wp_tempnam($file);
     $temp = fopen($tempfile, 'wb+');
     if (!$temp) {
         return false;
     }
     mbstring_binary_safe_encoding();
     $data_length = strlen($contents);
     $bytes_written = fwrite($temp, $contents);
     reset_mbstring_encoding();
     if ($data_length !== $bytes_written) {
         fclose($temp);
         unlink($tempfile);
         return false;
     }
     fseek($temp, 0);
     // Skip back to the start of the file being written to
     $ret = @ftp_fput($this->link, $file, $temp, FTP_BINARY);
     fclose($temp);
     unlink($tempfile);
     $this->chmod($file, $mode);
     return $ret;
 }
 function export_zip()
 {
     if (($child = $this->get('child')) && ($dir = $this->css->is_file_ok(dirname($this->css->get_child_target('style.css')), 'search')) && ($version = preg_replace("%[^\\w\\.\\-]%", '', $this->get('version')))) {
         // use php system upload dir to store temp files so that we can use pclzip
         $tmpdir = ini_get('upload_tmp_dir') ? ini_get('upload_tmp_dir') : sys_get_temp_dir();
         $file = trailingslashit($tmpdir) . $child . '-' . $version . '.zip';
         mbstring_binary_safe_encoding();
         require_once ABSPATH . 'wp-admin/includes/class-pclzip.php';
         $archive = new PclZip($file);
         if ($archive->create($dir, PCLZIP_OPT_REMOVE_PATH, dirname($dir)) == 0) {
             return FALSE;
         }
         reset_mbstring_encoding();
         header('Content-Description: File Transfer');
         header('Content-Type: application/octet-stream');
         header('Content-Length: ' . filesize($file));
         header('Content-Disposition: attachment; filename=' . basename($file));
         header('Expires: 0');
         header('Cache-Control: must-revalidate');
         header('Pragma: public');
         readfile($file);
         unlink($file);
         die;
     }
 }
 /**
  * Send an HTTP request to a URI.
  *
  * Please note: The only URI that are supported in the HTTP Transport implementation
  * are the HTTP and HTTPS protocols.
  *
  * @access public
  * @since 2.7.0
  *
  * @global string $wp_version
  *
  * @param string       $url  The request URL.
  * @param string|array $args {
  *     Optional. Array or string of HTTP request arguments.
  *
  *     @type string       $method              Request method. Accepts 'GET', 'POST', 'HEAD', or 'PUT'.
  *                                             Some transports technically allow others, but should not be
  *                                             assumed. Default 'GET'.
  *     @type int          $timeout             How long the connection should stay open in seconds. Default 5.
  *     @type int          $redirection         Number of allowed redirects. Not supported by all transports
  *                                             Default 5.
  *     @type string       $httpversion         Version of the HTTP protocol to use. Accepts '1.0' and '1.1'.
  *                                             Default '1.0'.
  *     @type string       $user-agent          User-agent value sent.
  *                                             Default WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ).
  *     @type bool         $reject_unsafe_urls  Whether to pass URLs through {@see wp_http_validate_url()}.
  *                                             Default false.
  *     @type bool         $blocking            Whether the calling code requires the result of the request.
  *                                             If set to false, the request will be sent to the remote server,
  *                                             and processing returned to the calling code immediately, the caller
  *                                             will know if the request succeeded or failed, but will not receive
  *                                             any response from the remote server. Default true.
  *     @type string|array $headers             Array or string of headers to send with the request.
  *                                             Default empty array.
  *     @type array        $cookies             List of cookies to send with the request. Default empty array.
  *     @type string|array $body                Body to send with the request. Default null.
  *     @type bool         $compress            Whether to compress the $body when sending the request.
  *                                             Default false.
  *     @type bool         $decompress          Whether to decompress a compressed response. If set to false and
  *                                             compressed content is returned in the response anyway, it will
  *                                             need to be separately decompressed. Default true.
  *     @type bool         $sslverify           Whether to verify SSL for the request. Default true.
  *     @type string       sslcertificates      Absolute path to an SSL certificate .crt file.
  *                                             Default ABSPATH . WPINC . '/certificates/ca-bundle.crt'.
  *     @type bool         $stream              Whether to stream to a file. If set to true and no filename was
  *                                             given, it will be droped it in the WP temp dir and its name will
  *                                             be set using the basename of the URL. Default false.
  *     @type string       $filename            Filename of the file to write to when streaming. $stream must be
  *                                             set to true. Default null.
  *     @type int          $limit_response_size Size in bytes to limit the response to. Default null.
  *
  * }
  * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'.
  *                        A WP_Error instance upon error.
  */
 public function request($url, $args = array())
 {
     global $wp_version;
     $defaults = array('method' => 'GET', 'timeout' => apply_filters('http_request_timeout', 5), 'redirection' => apply_filters('http_request_redirection_count', 5), 'httpversion' => apply_filters('http_request_version', '1.0'), 'user-agent' => apply_filters('http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo('url')), 'reject_unsafe_urls' => apply_filters('http_request_reject_unsafe_urls', false), 'blocking' => true, 'headers' => array(), 'cookies' => array(), 'body' => null, 'compress' => false, 'decompress' => true, 'sslverify' => true, 'sslcertificates' => ABSPATH . WPINC . '/certificates/ca-bundle.crt', 'stream' => false, 'filename' => null, 'limit_response_size' => null);
     // Pre-parse for the HEAD checks.
     $args = wp_parse_args($args);
     // By default, Head requests do not cause redirections.
     if (isset($args['method']) && 'HEAD' == $args['method']) {
         $defaults['redirection'] = 0;
     }
     $r = wp_parse_args($args, $defaults);
     /**
      * Filter the arguments used in an HTTP request.
      *
      * @since 2.7.0
      *
      * @param array  $r   An array of HTTP request arguments.
      * @param string $url The request URL.
      */
     $r = apply_filters('http_request_args', $r, $url);
     // The transports decrement this, store a copy of the original value for loop purposes.
     if (!isset($r['_redirection'])) {
         $r['_redirection'] = $r['redirection'];
     }
     /**
      * Filter whether to preempt an HTTP request's return value.
      *
      * Returning a non-false value from the filter will short-circuit the HTTP request and return
      * early with that value. A filter should return either:
      *
      *  - An array containing 'headers', 'body', 'response', 'cookies', and 'filename' elements
      *  - A WP_Error instance
      *  - boolean false (to avoid short-circuiting the response)
      *
      * Returning any other value may result in unexpected behaviour.
      *
      * @since 2.9.0
      *
      * @param false|array|WP_Error $preempt Whether to preempt an HTTP request's return value. Default false.
      * @param array               $r        HTTP request arguments.
      * @param string              $url      The request URL.
      */
     $pre = apply_filters('pre_http_request', false, $r, $url);
     if (false !== $pre) {
         return $pre;
     }
     if (function_exists('wp_kses_bad_protocol')) {
         if ($r['reject_unsafe_urls']) {
             $url = wp_http_validate_url($url);
         }
         if ($url) {
             $url = wp_kses_bad_protocol($url, array('http', 'https', 'ssl'));
         }
     }
     $arrURL = @parse_url($url);
     if (empty($url) || empty($arrURL['scheme'])) {
         return new WP_Error('http_request_failed', __('A valid URL was not provided.'));
     }
     if ($this->block_request($url)) {
         return new WP_Error('http_request_failed', __('User has blocked requests through HTTP.'));
     }
     /*
      * Determine if this is a https call and pass that on to the transport functions
      * so that we can blacklist the transports that do not support ssl verification
      */
     $r['ssl'] = $arrURL['scheme'] == 'https' || $arrURL['scheme'] == 'ssl';
     // Determine if this request is to OUR install of WordPress.
     $homeURL = parse_url(get_bloginfo('url'));
     $r['local'] = 'localhost' == $arrURL['host'] || isset($homeURL['host']) && $homeURL['host'] == $arrURL['host'];
     unset($homeURL);
     /*
      * If we are streaming to a file but no filename was given drop it in the WP temp dir
      * and pick its name using the basename of the $url.
      */
     if ($r['stream'] && empty($r['filename'])) {
         $r['filename'] = get_temp_dir() . wp_unique_filename(get_temp_dir(), basename($url));
     }
     /*
      * Force some settings if we are streaming to a file and check for existence and perms
      * of destination directory.
      */
     if ($r['stream']) {
         $r['blocking'] = true;
         if (!wp_is_writable(dirname($r['filename']))) {
             return new WP_Error('http_request_failed', __('Destination directory for file streaming does not exist or is not writable.'));
         }
     }
     if (is_null($r['headers'])) {
         $r['headers'] = array();
     }
     if (!is_array($r['headers'])) {
         $processedHeaders = self::processHeaders($r['headers'], $url);
         $r['headers'] = $processedHeaders['headers'];
     }
     if (isset($r['headers']['User-Agent'])) {
         $r['user-agent'] = $r['headers']['User-Agent'];
         unset($r['headers']['User-Agent']);
     }
     if (isset($r['headers']['user-agent'])) {
         $r['user-agent'] = $r['headers']['user-agent'];
         unset($r['headers']['user-agent']);
     }
     if ('1.1' == $r['httpversion'] && !isset($r['headers']['connection'])) {
         $r['headers']['connection'] = 'close';
     }
     // Construct Cookie: header if any cookies are set.
     self::buildCookieHeader($r);
     // Avoid issues where mbstring.func_overload is enabled.
     mbstring_binary_safe_encoding();
     if (!isset($r['headers']['Accept-Encoding'])) {
         if ($encoding = WP_Http_Encoding::accept_encoding($url, $r)) {
             $r['headers']['Accept-Encoding'] = $encoding;
         }
     }
     if (!is_null($r['body']) && '' != $r['body'] || 'POST' == $r['method'] || 'PUT' == $r['method']) {
         if (is_array($r['body']) || is_object($r['body'])) {
             $r['body'] = http_build_query($r['body'], null, '&');
             if (!isset($r['headers']['Content-Type'])) {
                 $r['headers']['Content-Type'] = 'application/x-www-form-urlencoded; charset=' . get_option('blog_charset');
             }
         }
         if ('' === $r['body']) {
             $r['body'] = null;
         }
         if (!isset($r['headers']['Content-Length']) && !isset($r['headers']['content-length'])) {
             $r['headers']['Content-Length'] = strlen($r['body']);
         }
     }
     $response = $this->_dispatch_request($url, $r);
     reset_mbstring_encoding();
     if (is_wp_error($response)) {
         return $response;
     }
     // Append cookies that were used in this request to the response
     if (!empty($r['cookies'])) {
         $cookies_set = wp_list_pluck($response['cookies'], 'name');
         foreach ($r['cookies'] as $cookie) {
             if (!in_array($cookie->name, $cookies_set) && $cookie->test($url)) {
                 $response['cookies'][] = $cookie;
             }
         }
     }
     return $response;
 }
Exemplo n.º 22
0
 /**
  * Get extended image metadata, exif or iptc as available.
  * Retrieves the EXIF metadata aperture, credit, camera, caption, copyright, iso
  * created_timestamp, focal_length, shutter_speed, and title.
  * The IPTC metadata that is retrieved is APP13, credit, byline, created date
  * and time, caption, copyright, and title. Also includes FNumber, Model,
  * DateTimeDigitized, FocalLength, ISOSpeedRatings, and ExposureTime.
  * @todo  Try other exif libraries if available.
  * @since 2.5.0
  *
  * @param string $file
  *
  * @return bool|array False on failure. Image metadata array on success.
  */
 function wp_read_image_metadata($file)
 {
     if (!is_file($file)) {
         return false;
     }
     list(, , $sourceImageType) = getimagesize($file);
     $meta = array();
     /*
      * Read IPTC first, since it might contain data not available in exif such
      * as caption, description etc.
      */
     if (is_callable('iptcparse')) {
         getimagesize($file, $info);
         if (!empty($info['APP13'])) {
             $iptc = iptcparse($info['APP13']);
             // Headline, "A brief synopsis of the caption."
             if (!empty($iptc['2#105'][0])) {
                 $meta['title'] = trim($iptc['2#105'][0]);
                 /*
                  * Title, "Many use the Title field to store the filename of the image,
                  * though the field may be used in many ways."
                  */
             } elseif (!empty($iptc['2#005'][0])) {
                 $meta['title'] = trim($iptc['2#005'][0]);
             }
             if (!empty($iptc['2#120'][0])) {
                 // description / legacy caption
                 $caption = trim($iptc['2#120'][0]);
                 if (empty($meta['title'])) {
                     mbstring_binary_safe_encoding();
                     $caption_length = strlen($caption);
                     reset_mbstring_encoding();
                     // Assume the title is stored in 2:120 if it's short.
                     if ($caption_length < 80) {
                         $meta['title'] = $caption;
                     } else {
                         $meta['caption'] = $caption;
                     }
                 } elseif ($caption != $meta['title']) {
                     $meta['caption'] = $caption;
                 }
             }
             if (!empty($iptc['2#110'][0])) {
                 $meta['credit'] = trim($iptc['2#110'][0]);
             } elseif (!empty($iptc['2#080'][0])) {
                 $meta['credit'] = trim($iptc['2#080'][0]);
             }
             if (!empty($iptc['2#055'][0]) and !empty($iptc['2#060'][0])) {
                 $meta['created_timestamp'] = strtotime($iptc['2#055'][0] . ' ' . $iptc['2#060'][0]);
             }
             if (!empty($iptc['2#116'][0])) {
                 $meta['copyright'] = trim($iptc['2#116'][0]);
             }
             if (!empty($iptc['2#025'])) {
                 $meta['keywords'] = $iptc['2#025'];
             }
         }
     }
     /**
      * Filter the image types to check for exif data.
      * @since 2.5.0
      *
      * @param array $image_types Image types to check for exif data.
      */
     if (is_callable('exif_read_data') && in_array($sourceImageType, apply_filters('wp_read_image_metadata_types', array(IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM)))) {
         $exif = @exif_read_data($file);
         unset($exif['MakerNote']);
         // Title
         if (empty($meta['title']) && !empty($exif['Title'])) {
             $meta['title'] = trim($exif['Title']);
         }
         // Descrioption
         if (!empty($exif['ImageDescription'])) {
             mbstring_binary_safe_encoding();
             $description_length = strlen($exif['ImageDescription']);
             reset_mbstring_encoding();
             if (empty($meta['title']) && $description_length < 80) {
                 // Assume the title is stored in ImageDescription
                 $meta['title'] = trim($exif['ImageDescription']);
                 if (empty($meta['caption']) && !empty($exif['COMPUTED']['UserComment']) && trim($exif['COMPUTED']['UserComment']) != $meta['title']) {
                     $meta['caption'] = trim($exif['COMPUTED']['UserComment']);
                 }
             } elseif (empty($meta['caption']) && trim($exif['ImageDescription']) != $meta['title']) {
                 $meta['caption'] = trim($exif['ImageDescription']);
             }
         } elseif (empty($meta['caption']) && !empty($exif['Comments']) && trim($exif['Comments']) != $meta['title']) {
             $meta['caption'] = trim($exif['Comments']);
         }
         // Credit
         if (empty($meta['credit'])) {
             if (!empty($exif['Artist'])) {
                 $meta['credit'] = trim($exif['Artist']);
             } elseif (!empty($exif['Author'])) {
                 $meta['credit'] = trim($exif['Author']);
             }
         }
         // Copyright
         if (empty($meta['copyright']) && !empty($exif['Copyright'])) {
             $meta['copyright'] = trim($exif['Copyright']);
         }
         // Camera Make
         if (!empty($exif['Make'])) {
             $meta['make'] = $exif['Make'];
         }
         // Camera Model
         if (!empty($exif['Model'])) {
             $meta['model'] = trim($exif['Model']);
         }
         // Exposure Time (shutter speed)
         if (!empty($exif['ExposureTime'])) {
             $meta['exposure'] = $exif['ExposureTime'] . 's';
             $meta['shutter_speed'] = (string) wp_exif_frac2dec($exif['ExposureTime']) . 's';
         }
         // Aperture
         if (!empty($exif['COMPUTED']['ApertureFNumber'])) {
             $meta['aperture'] = $exif['COMPUTED']['ApertureFNumber'];
         } elseif (!empty($exif['FNumber'])) {
             $meta['aperture'] = 'f/' . (string) round(wp_exif_frac2dec($exif['FNumber']), 2);
         }
         // ISO
         if (!empty($exif['ISOSpeedRatings'])) {
             $meta['iso'] = is_array($exif['ISOSpeedRatings']) ? reset($exif['ISOSpeedRatings']) : $exif['ISOSpeedRatings'];
             $meta['iso'] = trim($meta['iso']);
         }
         // Date
         if (!empty($exif['DateTime'])) {
             $meta['date'] = $exif['DateTime'];
         }
         // Created TimeStamp
         if (empty($meta['created_timestamp']) && !empty($exif['DateTimeDigitized'])) {
             $meta['created_timestamp'] = wp_exif_date2ts($exif['DateTimeDigitized']);
         }
         // Lens
         if (!empty($exif['UndefinedTag:0xA434'])) {
             $meta['lens'] = $exif['UndefinedTag:0xA434'];
         }
         // Focus Distance
         if (!empty($exif['COMPUTED']['FocusDistance'])) {
             $meta['distance'] = $exif['COMPUTED']['FocusDistance'];
         }
         // Focal Length
         if (!empty($exif['FocalLength'])) {
             $meta['focallength'] = (string) round(wp_exif_frac2dec($exif['FocalLength'])) . 'mm';
         }
         // Focal Length 35mm
         if (!empty($exif['FocalLengthIn35mmFilm'])) {
             $meta['focallength35'] = $exif['FocalLengthIn35mmFilm'] . 'mm';
         }
         // Flash data
         if (!empty($exif['Flash'])) {
             // we need to interpret the result - it's given as a number and we want a human-readable description.
             $fdata = $exif['Flash'];
             switch ($fdata) {
                 case 0:
                     $fdata = 'No Flash';
                     break;
                 case 1:
                     $fdata = 'Flash';
                     break;
                 case 5:
                     $fdata = 'Flash, strobe return light not detected';
                     break;
                 case 7:
                     $fdata = 'Flash, strob return light detected';
                     break;
                 case 9:
                     $fdata = 'Compulsory Flash';
                     break;
                 case 13:
                     $fdata = 'Compulsory Flash, Return light not detected';
                     break;
                 case 15:
                     $fdata = 'Compulsory Flash, Return light detected';
                     break;
                 case 16:
                     $fdata = 'No Flash';
                     break;
                 case 24:
                     $fdata = 'No Flash';
                     break;
                 case 25:
                     $fdata = 'Flash, Auto-Mode';
                     break;
                 case 29:
                     $fdata = 'Flash, Auto-Mode, Return light not detected';
                     break;
                 case 31:
                     $fdata = 'Flash, Auto-Mode, Return light detected';
                     break;
                 case 32:
                     $fdata = 'No Flash';
                     break;
                 case 65:
                     $fdata = 'Red Eye';
                     break;
                 case 69:
                     $fdata = 'Red Eye, Return light not detected';
                     break;
                 case 71:
                     $fdata = 'Red Eye, Return light detected';
                     break;
                 case 73:
                     $fdata = 'Red Eye, Compulsory Flash';
                     break;
                 case 77:
                     $fdata = 'Red Eye, Compulsory Flash, Return light not detected';
                     break;
                 case 79:
                     $fdata = 'Red Eye, Compulsory Flash, Return light detected';
                     break;
                 case 89:
                     $fdata = 'Red Eye, Auto-Mode';
                     break;
                 case 93:
                     $fdata = 'Red Eye, Auto-Mode, Return light not detected';
                     break;
                 case 95:
                     $fdata = 'Red Eye, Auto-Mode, Return light detected';
                     break;
                 default:
                     $fdata = 'Unknown: ' . $fdata;
                     break;
             }
             $meta['flashdata'] = $fdata;
         }
         // Lens Make
         if (!empty($exif['UndefinedTag:0xA433'])) {
             $meta['lensmake'] = $exif['UndefinedTag:0xA433'];
         }
         // Software
         if (!empty($exif['Software'])) {
             $meta['software'] = $exif['Software'];
         }
         // Orientation
         if (!empty($exif['Orientation'])) {
             $meta['orientation'] = $exif['Orientation'];
         }
         $exif_sections = @exif_read_data($file, null, true);
         if (isset($exif_sections['GPS'])) {
             $meta['GPS'] = $this->getGPSfromExif($exif_sections['GPS']);
         }
         unset($exif_sections);
         //$meta['exif'] = $exif;
     }
     foreach (array('title', 'caption', 'credit', 'copyright', 'model', 'iso', 'software') as $key) {
         if (!empty($meta[$key]) && !seems_utf8($meta[$key])) {
             $meta[$key] = utf8_encode($meta[$key]);
         }
     }
     if (!empty($meta['keywords'])) {
         foreach ($meta['keywords'] as $i => $key) {
             if (!seems_utf8($key)) {
                 $meta['keywords'][$i] = utf8_encode($key);
             }
         }
     }
     foreach ($meta as &$value) {
         if (is_string($value)) {
             $value = wp_kses_post($value);
         }
     }
     /**
      * Filter the array of meta data read from an image's exif data.
      * @since 2.5.0
      *
      * @param array  $meta            Image meta data.
      * @param string $file            Path to image file.
      * @param int    $sourceImageType Type of image.
      */
     return apply_filters('wp_read_image_metadata', $meta, $file, $sourceImageType);
 }