%PDF- %PDF-
| Direktori : /home1/lightco1/www/plugins/content/sigplus/core/ |
| Current File : //home1/lightco1/www/plugins/content/sigplus/core/filesystem.php |
<?php
/**
* @file
* @brief sigplus Image Gallery Plus file system functions
* @author Levente Hunyadi
* @version 1.5.0
* @remarks Copyright (C) 2009-2017 Levente Hunyadi
* @remarks Licensed under GNU/GPLv3, see http://www.gnu.org/licenses/gpl-3.0.html
* @see http://hunyadi.info.hu/sigplus
*/
/*
* sigplus Image Gallery Plus plug-in for Joomla
* Copyright 2009-2017 Levente Hunyadi
*
* sigplus is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sigplus is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************
* UTF-8 file system compatibility layer
*****************************************************************************/
if (!interface_exists('fsx_functions') && !class_exists('fsx')) {
/**
* UTF-8 compatibility layer for filesystem functions.
*
* This layer exposes PHP 5 filesystem functions like file_exists, filesize, filemtime, readfile,
* etc. that support files whose filename contains UTF-8 (non-ASCII) characters. Prefix function
* names with the static class name "fsx" to unlock functionality. For instance, the statement
*
* $size = fsx::filesize($file);
*
* returns the file size in bytes even if the variable $file contains non-ASCII characters.
*
* Normally, PHP 4/5 filesystem functions use ANSI versions of Windows filesystem functions, which
* fail with non-ASCII characters in filenames. This thin layer uses COM scripting services to
* interact with the Windows filesystem in a way that makes it possible to pass UTF-8 characters
* in filenames.
*/
interface fsx_functions {
public function scandir($dir);
public function scandir_files($dir);
public function scandir_folders($dir);
public function scandir_mtime($dir);
public function get_files_with_extension($dir, array $ext, $rev = false);
public function file_exists($path);
public function filemtime($file);
public function filesize($file);
public function file_get_contents($file);
public function file_put_contents($file, $data);
public function readfile($file);
}
class fsx_windows implements fsx_functions {
/**
* A COM file system object in Windows.
*/
private $fs = null;
public function __construct($fs) {
$this->fs = $fs;
}
public function __destruct() {
unset($this->fs);
}
private static function is_ascii($string) {
return !preg_match('/[\\x80-\\xff]+/', $string);
}
public function get_short_path($path) {
try {
if ($this->fs->FileExists($path)) {
return $this->fs->GetFile($path)->ShortPath;
}
if ($this->fs->FolderExists($path)) {
return $this->fs->GetFolder($path)->ShortPath;
}
} catch (com_exception $e) {}
return $path; // no short path available
}
public function scandir($dir) {
$results = array();
try {
$fsdir = $this->fs->GetFolder($dir);
foreach ($fsdir->SubFolders as $fsfolder) {
$results[] = $fsfolder->Name;
}
foreach ($fsdir->Files as $fsfile) {
$results[] = $fsfile->Name;
}
unset($fsdir);
return $results;
} catch (com_exception $e) { }
return false;
}
public function scandir_files($dir) {
$results = array();
try {
$fsdir = $this->fs->GetFolder($dir);
foreach ($fsdir->Files as $fsfile) {
$results[] = $fsfile->Name;
}
unset($fsdir);
return $results;
} catch (com_exception $e) { }
return false;
}
public function scandir_folders($dir) {
$results = array();
try {
$fsdir = $this->fs->GetFolder($dir);
foreach ($fsdir->SubFolders as $fsfolder) {
$results[] = $fsfolder->Name;
}
unset($fsdir);
return $results;
} catch (com_exception $e) { }
return false;
}
public function scandir_mtime($dir) {
$results = array();
try {
$fsdir = $this->fs->GetFolder($dir);
foreach ($fsdir->Files as $fsfile) {
$results[$fsfile->Name] = $fsfile->DateLastModified;
}
unset($fsdir);
return $results;
} catch (com_exception $e) { }
return false;
}
/**
* Get a directory listing in character set UTF-8.
*/
public function get_files_with_extension($dir, array $ext, $rev = false) {
$results = array();
try {
$fsdir = $this->fs->getFolder($dir);
foreach ($fsdir->Files as $fsfile) {
$fsname = $fsfile->Name;
$fsext = '';
if (($pos = strrpos($fsname, '.')) !== false) {
$fsext = substr($fsname, $pos + 1); // skip dot (.)
}
if (in_array($fsext, $ext)) {
$results[] = $fsname;
}
}
unset($fsdir);
return $results;
} catch (com_exception $e) { }
return false;
}
public function file_exists($path) {
return $this->fs->FileExists($path) || $this->fs->FolderExists($path);
}
public function filemtime($file) {
try {
if ($this->fs->FileExists($file)) {
return variant_date_to_timestamp($this->fs->GetFile($file)->DateLastModified);
}
if ($this->fs->FolderExists($file)) {
return variant_date_to_timestamp($this->fs->GetFolder($file)->DateLastModified);
}
} catch (com_exception $e) {}
return false;
}
public function filesize($file) {
try {
if ($this->fs->FileExists($file)) {
return $this->fs->GetFile($file)->Size;
}
} catch (com_exception $e) {}
return false;
}
public function file_get_contents($file) {
if (self::is_ascii($file)) {
return file_get_contents($file);
}
$is_output_buffered = false;
try {
$stream = new COM('ADODB.Stream', null, CP_UTF8); // use UTF-8 code page for communicating with COM object
$stream->Mode = 3; // adModeReadWrite
$stream->Type = 1; // adTypeBinary
$stream->Open();
$stream->LoadFromFile($file); // read file into Stream object
$data = $stream->Read(); // convert to PHP Traversable
$is_output_buffered = ob_start();
foreach ($data as $item) { // iterate COM SAFEARRAY as character codes and print each character
print chr($item);
}
$string = ob_get_clean();
$stream->Close();
return $string;
} catch (com_exception $e) {
if ($is_output_buffered) {
ob_end_clean();
}
return file_get_contents($this->get_short_path($file));
}
}
public function file_put_contents($file, $data) {
try {
$tempfile = tempnam(dirname($file), 'fsx');
$result = file_put_contents($tempfile, $data);
if ($this->fs->FileExists($file)) {
$this->fs->DeleteFile($file);
}
$this->fs->MoveFile($tempfile, $file);
return $result;
} catch (com_exception $e) {
if (isset($tempfile) && file_exists($tempfile)) {
unlink($tempfile);
}
return false;
}
}
public function readfile($file) {
if (self::is_ascii($file)) {
return readfile($file);
}
try {
$stream = new COM('ADODB.Stream', null, CP_UTF8); // use UTF-8 code page for communicating with COM object
$stream->Mode = 3; // adModeReadWrite
$stream->Type = 1; // binary
$stream->Open();
$stream->LoadFromFile($file); // read file into Stream object
$data = $stream->Read(); // convert to PHP Traversable
foreach ($data as $item) { // iterate COM SAFEARRAY as character codes and print each character
print chr($item);
}
$stream->Close();
return true;
} catch (com_exception $e) {
return readfile($this->get_short_path($file));
}
}
public function getimagesize($file, &$info = null) {
if (function_exists('getimagesizefromstring')) {
return getimagesizefromstring($this->file_get_contents($file), $info);
} else {
return getimagesize($this->get_short_path($file), $info);
}
}
public function imagecreatefromjpeg($file) {
$content = $this->file_get_contents($file);
return @imagecreatefromstring($content);
}
public function imagecreatefromgif($file) {
$content = $this->file_get_contents($file);
return @imagecreatefromstring($content);
}
public function imagecreatefrompng($file) {
$content = $this->file_get_contents($file);
return @imagecreatefromstring($content);
}
public function imagejpeg($image, $file, $quality) {
ob_start();
imagejpeg($image, null, $quality);
$data = ob_get_clean();
if ($data !== false) {
$this->file_put_contents($file, $data);
return true;
} else {
return false;
}
}
public function imagegif($image, $file) {
ob_start();
imagegif($image);
$data = ob_get_clean();
if ($data !== false) {
$this->file_put_contents($file, $data);
return true;
} else {
return false;
}
}
public function imagepng($image, $file, $quality) {
ob_start();
imagepng($image, null, $quality);
$data = ob_get_clean();
if ($data !== false) {
$this->file_put_contents($file, $data);
return true;
} else {
return false;
}
}
}
class fsx_unix implements fsx_functions {
public function scandir($dir) {
return scandir($dir);
}
public function scandir_files($dir) {
$entries = scandir($dir);
if ($entries !== false) {
$results = array();
foreach ($entries as $entry) {
if (is_file($dir.DIRECTORY_SEPARATOR.$entry)) {
$results[] = $entry;
}
}
return $results;
} else {
return false;
}
}
public function scandir_folders($dir) {
$entries = scandir($dir);
if ($entries !== false) {
$results = array();
foreach ($entries as $entry) {
if (is_dir($dir.DIRECTORY_SEPARATOR.$entry)) {
$results[] = $entry;
}
}
return $results;
} else {
return false;
}
}
/**
* List files and directories inside the specified path with modification time.
* @return An associative array with filenames as keys and timestamps as values.
*/
public function scandir_mtime($dir) {
$dh = @opendir($dir);
if ($dh === false) { // cannot open directory
return false;
}
$files = array();
while (false !== ($filename = readdir($dh))) {
if (!is_regular_file($filename)) {
continue;
}
$files[$filename] = filemtime($dir.DIRECTORY_SEPARATOR.$filename);
}
closedir($dh);
return $files;
}
/**
* Get all files in a directory that have the specified extension.
* @param {string} $dir Absolute path to a directory.
* @param {string} $ext Extension to check file names against.
* @param {boolean} $rev True if file names are to be sorted in reverse order.
*/
public function get_files_with_extension($dir, array $ext, $rev = false) {
$results = array();
$files = scandir($dir, $rev);
foreach ($files as $file) {
if (in_array(pathinfo($file, PATHINFO_EXTENSION), $ext)) {
$results[] = $file;
}
}
return $results;
}
public function file_exists($path) {
return file_exists($path);
}
public function filemtime($file) {
return filemtime($file);
}
public function filesize($file) {
return filesize($file);
}
public function file_get_contents($file) {
return file_get_contents($file);
}
public function file_put_contents($file, $data) {
return file_put_contents($file, $data);
}
public function readfile($file) {
return readfile($file);
}
public function getimagesize($file, &$info = null) {
return getimagesize($file, $info); // no special wrapper is required for UNIX-style operating systems
}
public function imagecreatefromjpeg($file) {
return imagecreatefromjpeg($file); // no special wrapper is required for UNIX-style operating systems
}
public function imagecreatefromgif($file) {
return imagecreatefromgif($file); // no special wrapper is required for UNIX-style operating systems
}
public function imagecreatefrompng($file) {
return imagecreatefrompng($file); // no special wrapper is required for UNIX-style operating systems
}
public function imagejpeg($image, $file, $quality) {
return imagejpeg($image, $file, $quality);
}
public function imagegif($image, $file) {
return imagegif($image, $file);
}
public function imagepng($image, $file, $quality) {
return imagepng($image, $file, $quality);
}
}
/**
* File system extensions.
* File system portability layer for Windows and UNIX-based systems.
*/
class fsx {
private static $instance;
public static function initialize() {
$fs = false;
if (class_exists('COM')) {
try {
$fs = new COM('Scripting.FileSystemObject', null, CP_UTF8);
} catch (com_exception $e) { }
}
if ($fs !== false) {
self::$instance = new fsx_windows($fs); // use Windows FileSystemObject
} else { // COM Scripting not available
self::$instance = new fsx_unix(); // use PHP's own functions with a thin wrapper
}
}
public static function scandir($dir) {
return self::$instance->scandir($dir);
}
public static function scandir_files($dir) {
return self::$instance->scandir_files($dir);
}
public static function scandir_folders($dir) {
return self::$instance->scandir_folders($dir);
}
public static function scandir_mtime($dir) {
return self::$instance->scandir_mtime($dir);
}
public static function get_files_with_extension($dir, $ext, $rev = false) {
if (!is_array($ext)) {
$ext = array($ext);
}
return self::$instance->get_files_with_extension($dir, $ext, $rev);
}
/**
* Get all files in a directory that have the specified extension sorted by last modified time.
* @param {string} $dir Absolute path to a directory.
* @param {string} $ext Extension to check file names against.
* @param {boolean} $rev True if file names are to be sorted in reverse order.
*/
public static function get_files_with_extension_time($dir, $ext, $rev = false) {
$files = self::$instance->get_files_with_extension($dir, $ext, $rev);
// fetch last modified date for each file
$times = array();
foreach ($files as $file) {
$times[] = self::filemtime($dir.DIRECTORY_SEPARATOR.$file);
}
// sort file array based on timestamp values
$sortorder = $rev ? SORT_DESC : SORT_ASC;
array_multisort($times, $sortorder, SORT_NUMERIC, $files, $sortorder, SORT_STRING);
return $files;
}
public static function file_exists($path) {
return self::$instance->file_exists($path);
}
public static function filemtime($file) {
return self::$instance->filemtime($file);
}
public static function filesize($file) {
return self::$instance->filesize($file);
}
public static function file_get_contents($file) {
return self::$instance->file_get_contents($file);
}
public static function file_put_contents($file, $data) {
return self::$instance->file_put_contents($file, $data);
}
public static function readfile($file) {
return self::$instance->readfile($file);
}
public static function getimagesize($file, &$info = null) {
return self::$instance->getimagesize($file, $info);
}
public static function imagecreatefromjpeg($file) {
return self::$instance->imagecreatefromjpeg($file);
}
public static function imagecreatefromgif($file) {
return self::$instance->imagecreatefromgif($file);
}
public static function imagecreatefrompng($file) {
return self::$instance->imagecreatefrompng($file);
}
public static function imagejpeg($image, $file, $quality) {
return self::$instance->imagejpeg($image, $file, $quality);
}
public static function imagegif($image, $file) {
return self::$instance->imagegif($image, $file);
}
public static function imagepng($image, $file, $quality) {
return self::$instance->imagepng($image, $file, $quality);
}
public static function filemdate($file) {
return gmdate('Y-m-d H:i:s', fsx::filemtime($file));
}
}
fsx::initialize();
} // if (!interface_exists('fsx_functions') && !class_exists('fsx'))
/*****************************************************************************
* Directory listing
*****************************************************************************/
if (!function_exists('walkdir')) {
/**
* List files and directories inside the specified path recursively.
* @param {string} $path The directory whose files and subdirectories to list.
* @param {array} $exclude Subdirectories to exclude from the listing.
* @param {int} $depth Maximum depth to traverse the directory hierarchy; >0 for recursive directory listing with a limit, 0 for flat listing, or -1 for listing with no limit.
* @param $callback Callback function to invoke for each directory hierarchy level.
* @param {array} $ancestors Breadcrumbs for current directory ancestors returned by the callback function
*/
function walkdir($path, array $exclude = array(), $depth = 0, $callback = null, $ancestors = null) {
$folders = fsx::scandir_folders($path);
$files = fsx::scandir_files($path);
if ($folders === false || $files === false) {
return;
}
foreach ($folders as $key => $folder) {
if ($folder == '.' || $folder == '..' || in_array($folder, $exclude)) { // skip special directory entries "." and "..", as well as excluded entries
unset($folders[$key]);
}
}
foreach ($files as $key => $file) {
if ($file{0} == '.' && in_array($file, $exclude)) { // skip hidden files and excluded entries
unset($files[$key]);
}
}
// invoke callback function
if (isset($callback)) {
if (is_array($callback)) {
$object = $callback[0];
$params = $callback[1];
$func = array($object, $params);
} else {
$func = $callback;
}
if (isset($ancestors)) {
$ancestor = call_user_func($func, $path, $files, $folders, $ancestors);
array_unshift($ancestors, $ancestor); // add current folder to list of ancestors
} else {
call_user_func($func, $path, $files, $folders);
}
}
// scan descandant folders
if ($depth < 0 || $depth > 0) {
foreach ($folders as $folder) {
if (isset($ancestors)) {
walkdir($path.DIRECTORY_SEPARATOR.$folder, $exclude, $depth - 1, $callback, $ancestors);
} else {
walkdir($path.DIRECTORY_SEPARATOR.$folder, $exclude, $depth - 1, $callback);
}
}
}
}
} // if (!function_exists('walkdir'))
/*****************************************************************************
* Miscellaneous file system management.
*****************************************************************************/
/**
* Ensure that a string is a relative path, removing leading and trailing space and slashes from a path string.
*/
function relativepath($path) {
return str_replace('\\', '/', trim($path, "\t\n\r /")); // remove leading and trailing spaces and slashes
}
/**
* Ensures that all components of a URL are URL-encoded.
*/
function safe_url_encode($url) {
$urlparts = parse_url($url);
$pattern = '#^([0-9A-Za-z!"$&\'()*+,.:;=@_-]|%[0-9A-Za-z]{2})+$#';
$segments = explode('/', $urlparts['path']);
foreach ($segments as &$segment) {
if (!preg_match($pattern, $segment)) { // path segment contains a character that has not been URL-encoded
$segment = rawurlencode($segment);
}
}
$urlparts['path'] = implode('/', $segments);
if (!empty($urlparts['query'])) {
if (!preg_match($pattern, $urlparts['query'])) { // query contains a character that has not been URL-encoded
$urlparts['query'] = rawurlencode($urlparts['query']);
}
}
return
$urlparts['scheme'].'://'.
( empty($urlparts['user']) ? '' : $urlparts['user'].( empty($urlparts['pass']) ? '' : ':'.$urlparts['pass'] ).'@' ).
$urlparts['host'].$urlparts['path'].
( empty($urlparts['query']) ? '' : '?'.$urlparts['query'] ).
( empty($urlparts['fragment']) ? '' : '#'.$urlparts['fragment'] );
}
/**
* URL-encodes all components of a path.
*/
function path_url_encode($path) {
$parts = explode('/', strtr($path, DIRECTORY_SEPARATOR, '/'));
if (preg_match('#^[A-Za-z0-9]:$#S', $parts[0])) { // a Windows-style path with drive letter
$firstpart = array_shift($parts); // do not URL-encode drive letter
foreach ($parts as &$part) {
$part = rawurlencode($part);
}
array_unshift($parts, $firstpart);
} else {
foreach ($parts as &$part) {
$part = rawurlencode($part);
}
}
return implode('/', $parts);
}
/**
* URL-decodes all components of a path.
*/
function path_url_decode($path) {
$parts = explode('/', $path);
foreach ($parts as &$part) {
$part = rawurldecode($part);
}
return implode(DIRECTORY_SEPARATOR, $parts);
}
/**
* Tests whether a string is a HTTP URL.
*/
function is_url_http($string) {
return preg_match('#^https?://#', $string);
}
/**
* Check if a path is a UNIX- or Windows-style absolute file system path.
*/
function is_absolute_path($path) {
return (bool) preg_match('#^(/|([A-Za-z0-9]:)?\\\\)#S', $path);
}
/**
* Filters regular files, skipping those that are hidden.
* The filename of a hidden file starts with a dot.
*/
function is_regular_file($filename) {
return $filename{0} != '.';
}
function is_filename($filename) {
return strpos(strtr($filename, DIRECTORY_SEPARATOR, '/'), '/') === false;
}
/**
* Checks whether a file or directory exists accepting both lowercase and uppercase extension.
* @return The file name with extension as found in the file system.
*/
function file_exists_case_insensitive($path) {
$realpath = realpath($path);
if ($realpath !== false) {
return pathinfo($realpath, PATHINFO_BASENAME); // file name possibly with extension
}
$filename = pathinfo($path, PATHINFO_BASENAME); // file name possibly with extension
if (fsx::file_exists($path)) { // file exists as-is, no inspection of extension is necessary
return $filename;
}
$extension = pathinfo($path, PATHINFO_EXTENSION); // file extension if present
if ($extension) { // if file has extension
$p = strrpos($path, '.'); // starting position of extension (incl. dot)
$base = substr($path, 0, $p); // everything up to extension
$extension = substr($path, $p); // extension (incl. dot)
$p = strrpos($filename, '.');
$filename = substr($filename, 0, $p); // drop extension from filename
$extension = strtolower($extension);
if (fsx::file_exists($base.$extension)) { // file with lowercase extension
return $filename.$extension;
}
$extension = strtoupper($extension);
if (fsx::file_exists($base.$extension)) { // file with uppercase extension
return $filename.$extension;
}
}
return false; // file not found
}
/**
* Escapes characters with special meaning to `glob`.
*/
function glob_escape($str) {
return str_replace(array('[', ']'), array('\\[', '\\]'), $str);
}
/**
* Returns a canonicalized absolute pathname with case-insensitive search.
* @param path The path to canonicalize with case-insensitive search.
* @return The expanded path string, with character case matching the version stored in the file system.
*/
function realpath_case_insensitive($path) {
// check if path exists with case-sensitive match
$real_path = realpath($path);
if ($real_path !== false) {
return $real_path;
}
// check if path exists with case-insensitive match
$dir = dirname($path);
if ($dir === $path) {
return false;
}
$dir = realpath_case_insensitive($dir);
if ($dir === false) {
return false;
}
$basename = basename($path);
$lower = strtolower($basename);
$upper = strtoupper($basename);
$pattern = '';
for ($pos = 0, $len = strlen($lower); $pos < $len; ++$pos) {
if ($lower[$pos] != $upper[$pos]) {
$pattern .= sprintf('[%s%s]', glob_escape($lower[$pos]), glob_escape($upper[$pos]));
} else {
$pattern .= glob_escape($lower[$pos]);
}
}
return current(glob($dir . DIRECTORY_SEPARATOR . $pattern, GLOB_NOSORT));
}
/**
* Returns a canonicalized absolute pathname with case-insensitive search.
* @param path The path to canonicalize with case-insensitive search.
* @return The expanded path string, with character case matching the version stored in the file system.
*/
function realpathi($path) {
$path = rtrim(preg_replace('#[/\\\\]+#', DIRECTORY_SEPARATOR, $path), DIRECTORY_SEPARATOR);
return realpath_case_insensitive($path);
}
/**
* Get the lastest time the folder or one of its descendants has been modified.
* @param {string} $dir An absolute path to a folder.
* @param {int} $depth 0 for current folder only, 1 for current and children, n (>1) for descandants until the given limit, -1 for all descendants.
*/
function get_folder_last_modified($dir, $depth = 0) {
$mtime = fsx::filemtime($dir);
if ($depth != 0) {
// scan directory for last modified descandant folder
if ($dh = @opendir($dir)) {
while (($entry = readdir($dh)) !== false) {
if ($entry != '.' && $entry != '..' && is_dir($dir.DIRECTORY_SEPARATOR.$entry)) {
$mtime = max($mtime, get_folder_last_modified($dir.DIRECTORY_SEPARATOR.$entry, $depth - 1));
}
}
closedir($dh);
}
}
return $mtime;
}
/**
* Fetch a resource, validating it against a (weak) entity tag.
* If the resource pointed to by the entity tag has expired, the resource is fetched.
* @param {string} $url The URL to retrieve.
* @param {string} $last_modified Last modified UTC date in format YYYY-MM-DD HH:MM:SS.
* @param {string} $etag A (weak) entity tag.
* @param {array} $request_headers HTTP request headers.
*/
function http_get_modified($url, $last_modified = null, $etag = null, $method = 'GET', $request_headers = array()) {
$data = false;
$response_headers = false;
// add If-Modified-Since header
if (!empty($last_modified)) {
$date = DateTime::createFromFormat('Y-m-d H:i:s', $last_modified, new DateTimeZone('UTC'));
$request_headers[] = 'If-Modified-Since: '.$date->format('D, d M Y H:i:s T');
}
// add If-None-Match header (a.k.a ETag)
if (!empty($etag)) {
$request_headers[] = 'If-None-Match: '.$etag;
}
// create stream context
if (!empty($request_headers)) {
$options = array(
'http' => array(
'method' => $method,
'header' => implode("\r\n", $request_headers)."\r\n"
)
);
$context = stream_context_create($options);
$stream = fopen($url, 'r', false, $context);
} else {
$stream = fopen($url, 'r');
}
// test for HTTP ETag match, $http_response_header is a predefined PHP variable
if (!isset($http_response_header)) { // HTTP wrappers are disabled
$data = false; // cannot access resource
} elseif (!preg_match('#^HTTP/[\d.]+\s+(\d+)#S', $http_response_header[0], $matches) || $matches[1] != '304') { // HTTP 304 "Not modified" indicates ETag match
$response_headers = $http_response_header;
foreach ($http_response_header as $header) { // go through header lines, looking for HTTP ETag
if (preg_match('#^ETag:\s+(\S+)#iS', $header, $matches)) { // locate ETag header
$response_headers['ETag'] = $matches[1]; // extract and update ETag value
break;
} elseif (preg_match('#^Last-Modified:\s+(.+)$#iS', $header, $matches)) {
$timestring = $matches[1];
if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
$date = DateTime::createFromFormat('D, d M Y H:i:s T', $timestring); // parse HTTP date format (RFC 822, updated by RFC 1123)
} else {
$unixtime = strtotime($timestring);
if ($unixtime !== false && $unixtime !== -1) {
$date = new DateTime('@'.$unixtime);
} else {
$date = false;
}
}
if ($date !== false) {
$response_headers['Last-Modified'] = $date->format('Y-m-d H:i:s'); // generate database date format
}
} elseif (preg_match('#^Content-Length:\s+(\d+)$#iS', $header, $matches)) {
$response_headers['Content-Length'] = (int)($matches[1]); // extract and update ETag value
}
}
if ($stream !== false) {
// read data if HTTP ETag does not match
$data = stream_get_contents($stream);
} else {
$data = false; // cannot access resource
}
} else {
$data = true; // resource not modified
}
// close stream
if ($stream !== false) {
fclose($stream);
}
return array($data, $response_headers);
}
/**
* Compute an image hash.
*/
function image_hash($imagepath, $userdata = false, $secret = false, $size = false) {
if ($size === false) {
$size = @fsx::getimagesize($imagepath);
}
if ($size !== false) {
return sha1($secret.$userdata.$imagepath.'_'.$size[0].'x'.$size[1]);
} else {
return false;
}
}