mirror of
https://github.com/mosbth/cimage.git
synced 2025-01-16 18:48:14 +01:00
prepare to test
This commit is contained in:
parent
c637fa23ef
commit
b1d0cb1506
@ -91,7 +91,6 @@ class CFastTrackCache
|
||||
$queryAsString = http_build_query($query);
|
||||
|
||||
$this->filename = md5($queryAsString);
|
||||
$this->container["query-string"] = $queryAsString;
|
||||
|
||||
return $this->filename;
|
||||
}
|
||||
@ -216,7 +215,6 @@ class CFastTrackCache
|
||||
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])
|
||||
&& strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) == $item["last-modified"]) {
|
||||
header("HTTP/1.0 304 Not Modified");
|
||||
debug("fast track 304");
|
||||
exit;
|
||||
}
|
||||
|
||||
@ -224,7 +222,6 @@ class CFastTrackCache
|
||||
header($value);
|
||||
}
|
||||
|
||||
debug("fast track 200");
|
||||
readfile($item["source"]);
|
||||
exit;
|
||||
}
|
||||
|
@ -2621,7 +2621,6 @@ class CImage
|
||||
}
|
||||
|
||||
header("HTTP/1.0 304 Not Modified");
|
||||
debug("standard 304");
|
||||
|
||||
} else {
|
||||
|
||||
@ -2652,7 +2651,6 @@ class CImage
|
||||
|
||||
$this->fastTrackCache->setSource($file);
|
||||
$this->fastTrackCache->writeToCache();
|
||||
debug("standard 200");
|
||||
readfile($file);
|
||||
}
|
||||
|
||||
|
26
README.md
26
README.md
@ -8,7 +8,7 @@ Image conversion on the fly using PHP
|
||||
About
|
||||
-------------------------------------
|
||||
|
||||
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim07.png&w=200&c=140,140,520,340&sharpen"/>
|
||||
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim07.png&w=200&c=140,140,520,340&sharpen"/>
|
||||
|
||||
`CImage` is a PHP class enabling resizing of images through scaling, cropping and filtering effects -- using PHP GD. The script `img.php` uses `CImage` to enable server-side image processing utilizing caching and optimization of the processed images.
|
||||
|
||||
@ -99,7 +99,7 @@ Lets take some use cases to let you know when and how `img.php` might be useful.
|
||||
|
||||
### Make a thumbnail
|
||||
|
||||
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim04.png&w=80&h=80&cf">
|
||||
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim04.png&w=80&h=80&cf">
|
||||
|
||||
Lets say you have a larger image and you want to make a smaller thumbnail of it with a size of 80x80 pixels. You simply take the image and add constraints on `width`, `height` and you use the resize strategy `crop-to-fit` to crops out the parts of the image that does not fit.
|
||||
|
||||
@ -113,7 +113,7 @@ To produce such a thumbnail, create a link like this:
|
||||
|
||||
Perhaps you got an image from a friend. The image was taken with the iPhone and thus rotated.
|
||||
|
||||
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=issue36/me-270.jpg&w=250">
|
||||
<img src="https://cimage.se/cimage/imgd.php?src=example/issue36/me-270.jpg&w=250">
|
||||
|
||||
The original image is looking like this one, scaled down to a width of 250 pixels.
|
||||
|
||||
@ -126,7 +126,7 @@ Lets call this *the URL-Photoshopper*. This is how the magic looks like.
|
||||
> `img.php?src=issue36/me-270.jpg&w=100&h=100&cf&aro`
|
||||
> `&rb=-25&a=8,30,30,38&f=grayscale&convolve=sharpen-alt`
|
||||
|
||||
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=issue36/me-270.jpg&w=100&h=100&cf&aro&rb=-25&a=8,30,30,38&f=grayscale&convolve=sharpen-alt">
|
||||
<img src="https://cimage.se/cimage/imgd.php?src=example/issue36/me-270.jpg&w=100&h=100&cf&aro&rb=-25&a=8,30,30,38&f=grayscale&convolve=sharpen-alt">
|
||||
|
||||
For myself, I use `img.php` to put up all images on my website, it gives me the power of affecting the resulting images - without opening up a photo-editing application.
|
||||
|
||||
@ -145,7 +145,7 @@ Try it out by pointing your browser to the test file `webroot/test/test.php`. It
|
||||
|
||||
###Process your first image
|
||||
|
||||
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim04.png&w=w2&a=40,0,50,0" alt=''>
|
||||
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim04.png&w=w2&a=40,0,50,0" alt=''>
|
||||
|
||||
Try it yourself by opening up an image in your browser. Start with
|
||||
|
||||
@ -199,7 +199,7 @@ Open an image through `img.php` by using its `src` attribute.
|
||||
|
||||
It looks like this.
|
||||
|
||||
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=w1&save-as=jpg">
|
||||
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=w1&save-as=jpg">
|
||||
|
||||
All images are stored in a directory structure and you access them as:
|
||||
|
||||
@ -213,7 +213,7 @@ Create a thumbnail of the image by applying constraints on width and height, or
|
||||
|
||||
| `&width=150` | `&height=150` | `&w=150&h=150` |
|
||||
|---------------------|---------------------|---------------------|
|
||||
| <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=150 alt=''> | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&h=150 alt=''> | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=150&h=150 alt=''> |
|
||||
| <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=150 alt=''> | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&h=150 alt=''> | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=150&h=150 alt=''> |
|
||||
|
||||
By setting `width`, `height` or both, the image gets resized to be *not larger* than the defined dimensions *and* keeping its original aspect ratio.
|
||||
|
||||
@ -228,10 +228,10 @@ Creating a thumbnail with a certain dimension of width and height, usually invol
|
||||
|
||||
| What | The image |
|
||||
|---------------------|---------------------|
|
||||
| **Original.** The original image resized with a max width and max height.<br>`?w=300&h=150` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150 alt=''> |
|
||||
| **Stretch.** Stretch the image so that the resulting image has the defined width and height.<br>`?w=300&h=150&stretch` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150&stretch alt=''> |
|
||||
| **Crop to fit.** Keep the aspect ratio and crop out the parts of the image that does not fit.<br>`?w=300&h=150&crop-to-fit` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150&crop-to-fit alt=''> |
|
||||
| **Fill to fit.** Keep the aspect ratio and fill then blank space with a background color.<br>`?w=300&h=150&fill-to-fit=006600` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150&fill-to-fit=006600 alt=''> |
|
||||
| **Original.** The original image resized with a max width and max height.<br>`?w=300&h=150` | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=300&h=150 alt=''> |
|
||||
| **Stretch.** Stretch the image so that the resulting image has the defined width and height.<br>`?w=300&h=150&stretch` | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=300&h=150&stretch alt=''> |
|
||||
| **Crop to fit.** Keep the aspect ratio and crop out the parts of the image that does not fit.<br>`?w=300&h=150&crop-to-fit` | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=300&h=150&crop-to-fit alt=''> |
|
||||
| **Fill to fit.** Keep the aspect ratio and fill then blank space with a background color.<br>`?w=300&h=150&fill-to-fit=006600` | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=300&h=150&fill-to-fit=006600 alt=''> |
|
||||
|
||||
Learn to crop your images, creative cropping can make wonderful images from appearingly useless originals.
|
||||
|
||||
@ -248,7 +248,7 @@ Fill to fit is useful when you have some image that must fit in a certain dimens
|
||||
> `img.php?src=kodim13.png&w=600&aspect-ratio=4`
|
||||
> `&crop-to-fit&sharpen&save-as=jpg&q=30`
|
||||
|
||||
<img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=600&aspect-ratio=4&crop-to-fit&sharpen&save-as=jpg&q=30 alt=''>
|
||||
<img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=600&aspect-ratio=4&crop-to-fit&sharpen&save-as=jpg&q=30 alt=''>
|
||||
|
||||
Here is a list of all parameters that you can use together with `img.php`, grouped by its basic intent of usage.
|
||||
|
||||
@ -431,7 +431,7 @@ For example, the following image is created like this:
|
||||
|
||||
> `&w=300&save-as=jpg`
|
||||
|
||||
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim24.png&w=300&save-as=jpg" alt=''>
|
||||
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim24.png&w=300&save-as=jpg" alt=''>
|
||||
|
||||
Its JSON-representation is retrieved like this:
|
||||
|
||||
|
11
REVISION.md
11
REVISION.md
@ -5,6 +5,17 @@ Revision history
|
||||
[![Build Status](https://scrutinizer-ci.com/g/mosbth/cimage/badges/build.png?b=master)](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master)
|
||||
|
||||
|
||||
v0.7.13 (2016-08-08)
|
||||
-------------------------------------
|
||||
|
||||
* Moved functions from img.php to `functions.php`.
|
||||
* Added function `trace()` to measure speed and memory consumption, only for development.
|
||||
* Added fast cache #149.
|
||||
* Added `imgf.php` as shortcut to check for fast cache, before loading `img.php` as usual.
|
||||
* Created `defines.php` and moved definition av version there.
|
||||
* Fixed images in README, #148.
|
||||
|
||||
|
||||
v0.7.12 (2016-06-01)
|
||||
-------------------------------------
|
||||
|
||||
|
@ -3,9 +3,10 @@
|
||||
* Autoloader for CImage and related class files.
|
||||
*
|
||||
*/
|
||||
//include __DIR__ . "/../CHttpGet.php";
|
||||
//include __DIR__ . "/../CRemoteImage.php";
|
||||
//include __DIR__ . "/../CImage.php";
|
||||
require __DIR__ . "/defines.php";
|
||||
require __DIR__ . "/functions.php";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Autoloader for classes.
|
||||
|
@ -34,12 +34,15 @@ fi
|
||||
$ECHO "Creating '$TARGET_D', '$TARGET_P' and '$TARGET_S' by combining the following files:"
|
||||
$ECHO "\n"
|
||||
$ECHO "\n webroot/img_header.php"
|
||||
$ECHO "\n defines.php"
|
||||
$ECHO "\n functions.php"
|
||||
$ECHO "\n CHttpGet.php"
|
||||
$ECHO "\n CRemoteImage.php"
|
||||
$ECHO "\n CWhitelist.php"
|
||||
$ECHO "\n CAsciiArt.php"
|
||||
$ECHO "\n CImage.php"
|
||||
$ECHO "\n CCache.php"
|
||||
$ECHO "\n CFastTrackCache.php"
|
||||
$ECHO "\n webroot/img.php"
|
||||
$ECHO "\n"
|
||||
$ECHO "\n'$TARGET_D' is for development mode."
|
||||
@ -60,6 +63,12 @@ cat webroot/img_header.php | sed "s|//'mode' => 'production',|'mode'
|
||||
|
||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
|
||||
tail -n +2 defines.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
|
||||
tail -n +2 functions.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
|
||||
tail -n +2 CHttpGet.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
|
||||
@ -78,6 +87,9 @@ $ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
tail -n +2 CCache.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
|
||||
tail -n +2 CFastTrackCache.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
|
||||
tail -n +2 webroot/img.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
|
||||
|
@ -25,13 +25,18 @@
|
||||
"ext-exif": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"files": [
|
||||
"defines.php",
|
||||
"functions.php"
|
||||
],
|
||||
"classmap": [
|
||||
"CImage.php",
|
||||
"CHttpGet.php",
|
||||
"CRemoteImage.php",
|
||||
"CWhitelist.php",
|
||||
"CAsciiArt.php",
|
||||
"CCache.php"
|
||||
"CFastTrackCache.php"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
6
defines.php
Normal file
6
defines.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
// Version of cimage and img.php
|
||||
define("CIMAGE_VERSION", "v0.7.13 (2016-08-08)");
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/" . CIMAGE_VERSION);
|
164
functions.php
Normal file
164
functions.php
Normal file
@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/**
|
||||
* General functions to use in img.php.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Trace and log execution to logfile, useful for debugging and development.
|
||||
*
|
||||
* @param string $msg message to log to file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function trace($msg)
|
||||
{
|
||||
$file = "/tmp/cimage";
|
||||
if (!is_writable($file)) {
|
||||
die("Using trace without a writable logfile. Create the file '$file' and make it writable for the web server.");
|
||||
}
|
||||
|
||||
$msg .= ":" . count(get_included_files());
|
||||
$msg .= ":" . round(memory_get_peak_usage()/1024/1024, 3) . "MB";
|
||||
$msg .= ":" . (string) round((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]), 6) . "ms";
|
||||
file_put_contents($file, "$msg\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display error message.
|
||||
*
|
||||
* @param string $msg to display.
|
||||
* @param int $type of HTTP error to display.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function errorPage($msg, $type = 500)
|
||||
{
|
||||
global $mode;
|
||||
|
||||
switch ($type) {
|
||||
case 403:
|
||||
$header = "403 Forbidden";
|
||||
break;
|
||||
case 404:
|
||||
$header = "404 Not Found";
|
||||
break;
|
||||
default:
|
||||
$header = "500 Internal Server Error";
|
||||
}
|
||||
|
||||
if ($mode == "strict") {
|
||||
$header = "404 Not Found";
|
||||
}
|
||||
|
||||
header("HTTP/1.0 $header");
|
||||
|
||||
if ($mode == "development") {
|
||||
die("[img.php] $msg");
|
||||
}
|
||||
|
||||
error_log("[img.php] $msg");
|
||||
die("HTTP/1.0 $header");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Custom exception handler.
|
||||
*/
|
||||
set_exception_handler(function ($exception) {
|
||||
errorPage(
|
||||
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||
. $exception->getMessage()
|
||||
. "</p><pre>"
|
||||
. $exception->getTraceAsString()
|
||||
. "</pre>",
|
||||
500
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string or return default value if not set.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $default value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value from $_GET or default value.
|
||||
*/
|
||||
function get($key, $default = null)
|
||||
{
|
||||
if (is_array($key)) {
|
||||
foreach ($key as $val) {
|
||||
if (isset($_GET[$val])) {
|
||||
return $_GET[$val];
|
||||
}
|
||||
}
|
||||
} elseif (isset($_GET[$key])) {
|
||||
return $_GET[$key];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string and set to $defined if defined or else $undefined.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $defined value to return when $key is set in $_GET.
|
||||
* @param mixed $undefined value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value as $defined or $undefined.
|
||||
*/
|
||||
function getDefined($key, $defined, $undefined)
|
||||
{
|
||||
return get($key) === null ? $undefined : $defined;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value from config array or default if key is not set in config array.
|
||||
*
|
||||
* @param string $key the key in the config array.
|
||||
* @param mixed $default value to be default if $key is not set in config.
|
||||
*
|
||||
* @return mixed value as $config[$key] or $default.
|
||||
*/
|
||||
function getConfig($key, $default)
|
||||
{
|
||||
global $config;
|
||||
return isset($config[$key])
|
||||
? $config[$key]
|
||||
: $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log when verbose mode, when used without argument it returns the result.
|
||||
*
|
||||
* @param string $msg to log.
|
||||
*
|
||||
* @return void or array.
|
||||
*/
|
||||
function verbose($msg = null)
|
||||
{
|
||||
global $verbose, $verboseFile;
|
||||
static $log = array();
|
||||
|
||||
if (!($verbose || $verboseFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($msg)) {
|
||||
return $log;
|
||||
}
|
||||
|
||||
$log[] = $msg;
|
||||
}
|
190
webroot/img.php
190
webroot/img.php
@ -8,165 +8,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
$version = "v0.7.12 (2016-06-01)";
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/$version");
|
||||
|
||||
|
||||
// Include debug functions
|
||||
function debug($msg)
|
||||
{
|
||||
$file = "/tmp/cimage";
|
||||
if (!is_writable($file)) {
|
||||
return;
|
||||
}
|
||||
$msg .= ":" . count(get_included_files());
|
||||
$msg .= ":" . round(memory_get_peak_usage()/1024/1024, 3) . "MB";
|
||||
$msg .= ":" . (string) round((microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']), 6) . "ms";
|
||||
file_put_contents($file, "$msg\n", FILE_APPEND);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display error message.
|
||||
*
|
||||
* @param string $msg to display.
|
||||
* @param int $type of HTTP error to display.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function errorPage($msg, $type = 500)
|
||||
{
|
||||
global $mode;
|
||||
|
||||
switch ($type) {
|
||||
case 403:
|
||||
$header = "403 Forbidden";
|
||||
break;
|
||||
case 404:
|
||||
$header = "404 Not Found";
|
||||
break;
|
||||
default:
|
||||
$header = "500 Internal Server Error";
|
||||
}
|
||||
|
||||
if ($mode == "strict") {
|
||||
$header = "404 Not Found";
|
||||
}
|
||||
|
||||
header("HTTP/1.0 $header");
|
||||
|
||||
if ($mode == "development") {
|
||||
die("[img.php] $msg");
|
||||
}
|
||||
|
||||
error_log("[img.php] $msg");
|
||||
die("HTTP/1.0 $header");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Custom exception handler.
|
||||
*/
|
||||
set_exception_handler(function ($exception) {
|
||||
errorPage(
|
||||
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||
. $exception->getMessage()
|
||||
. "</p><pre>"
|
||||
. $exception->getTraceAsString()
|
||||
. "</pre>",
|
||||
500
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string or return default value if not set.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $default value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value from $_GET or default value.
|
||||
*/
|
||||
function get($key, $default = null)
|
||||
{
|
||||
if (is_array($key)) {
|
||||
foreach ($key as $val) {
|
||||
if (isset($_GET[$val])) {
|
||||
return $_GET[$val];
|
||||
}
|
||||
}
|
||||
} elseif (isset($_GET[$key])) {
|
||||
return $_GET[$key];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string and set to $defined if defined or else $undefined.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $defined value to return when $key is set in $_GET.
|
||||
* @param mixed $undefined value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value as $defined or $undefined.
|
||||
*/
|
||||
function getDefined($key, $defined, $undefined)
|
||||
{
|
||||
return get($key) === null ? $undefined : $defined;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value from config array or default if key is not set in config array.
|
||||
*
|
||||
* @param string $key the key in the config array.
|
||||
* @param mixed $default value to be default if $key is not set in config.
|
||||
*
|
||||
* @return mixed value as $config[$key] or $default.
|
||||
*/
|
||||
function getConfig($key, $default)
|
||||
{
|
||||
global $config;
|
||||
return isset($config[$key])
|
||||
? $config[$key]
|
||||
: $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log when verbose mode, when used without argument it returns the result.
|
||||
*
|
||||
* @param string $msg to log.
|
||||
*
|
||||
* @return void or array.
|
||||
*/
|
||||
function verbose($msg = null)
|
||||
{
|
||||
global $verbose, $verboseFile;
|
||||
static $log = array();
|
||||
|
||||
if (!($verbose || $verboseFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($msg)) {
|
||||
return $log;
|
||||
}
|
||||
|
||||
$log[] = $msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get configuration options from file, if the file exists, else use $config
|
||||
* if its defined or create an empty $config.
|
||||
@ -181,13 +22,26 @@ if (is_file($configFile)) {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Setup the autoloader, but not when using a bundle.
|
||||
*/
|
||||
if (!defined("CIMAGE_BUNDLE")) {
|
||||
if (!isset($config["autoloader"])) {
|
||||
die("CImage: Missing autoloader.");
|
||||
}
|
||||
|
||||
require $config["autoloader"];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* verbose, v - do a verbose dump of what happens
|
||||
* vf - do verbose dump to file
|
||||
*/
|
||||
$verbose = getDefined(array('verbose', 'v'), true, false);
|
||||
$verboseFile = getDefined('vf', true, false);
|
||||
verbose("img.php version = $version");
|
||||
verbose("img.php version = " . CIMAGE_VERSION);
|
||||
|
||||
|
||||
|
||||
@ -345,20 +199,6 @@ verbose("referer host = $refererHost");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the source files.
|
||||
*/
|
||||
$autoloader = getConfig('autoloader', false);
|
||||
$cimageClass = getConfig('cimage_class', false);
|
||||
|
||||
if ($autoloader) {
|
||||
require $autoloader;
|
||||
} elseif ($cimageClass) {
|
||||
require $cimageClass;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the class for the image.
|
||||
*/
|
||||
@ -1105,7 +945,7 @@ if ($srgb || $srgbDefault) {
|
||||
* Display status
|
||||
*/
|
||||
if ($status) {
|
||||
$text = "img.php version = $version\n";
|
||||
$text = "img.php version = " . CIMAGE_VERSION . "\n";
|
||||
$text .= "PHP version = " . PHP_VERSION . "\n";
|
||||
$text .= "Running on: " . $_SERVER['SERVER_SOFTWARE'] . "\n";
|
||||
$text .= "Allow remote images = $allowRemote\n";
|
||||
|
@ -29,14 +29,12 @@ return array(
|
||||
|
||||
|
||||
/**
|
||||
* Where are the sources for the class files.
|
||||
* Where to find the autoloader.
|
||||
*
|
||||
* Default values:
|
||||
* autoloader: null // used from v0.6.2
|
||||
* cimage_class: null // used until v0.6.1
|
||||
* autoloader: null
|
||||
*/
|
||||
'autoloader' => __DIR__ . '/../autoload.php',
|
||||
//'cimage_class' => __DIR__ . '/../CImage.php',
|
||||
|
||||
|
||||
|
||||
@ -63,7 +61,7 @@ return array(
|
||||
* Default values:
|
||||
* fast_track_allow: false
|
||||
*/
|
||||
'fast_track_allow' => true,
|
||||
//'fast_track_allow' => true,
|
||||
|
||||
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
* @link https://github.com/mosbth/cimage
|
||||
*
|
||||
*/
|
||||
define("CIMAGE_BUNDLE", true);
|
||||
|
||||
|
||||
/**
|
||||
|
690
webroot/imgd.php
690
webroot/imgd.php
@ -10,6 +10,7 @@
|
||||
* @link https://github.com/mosbth/cimage
|
||||
*
|
||||
*/
|
||||
define("CIMAGE_BUNDLE", true);
|
||||
|
||||
|
||||
/**
|
||||
@ -36,6 +37,180 @@ $config = array(
|
||||
|
||||
|
||||
|
||||
// Version of cimage and img.php
|
||||
define("CIMAGE_VERSION", "v0.7.13 (2016-08-08)");
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/" . CIMAGE_VERSION);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* General functions to use in img.php.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Trace and log execution to logfile, useful for debugging and development.
|
||||
*
|
||||
* @param string $msg message to log to file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function trace($msg)
|
||||
{
|
||||
$file = "/tmp/cimage";
|
||||
if (!is_writable($file)) {
|
||||
die("Using trace without a writable logfile. Create the file '$file' and make it writable for the web server.");
|
||||
}
|
||||
|
||||
$msg .= ":" . count(get_included_files());
|
||||
$msg .= ":" . round(memory_get_peak_usage()/1024/1024, 3) . "MB";
|
||||
$msg .= ":" . (string) round((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]), 6) . "ms";
|
||||
file_put_contents($file, "$msg\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display error message.
|
||||
*
|
||||
* @param string $msg to display.
|
||||
* @param int $type of HTTP error to display.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function errorPage($msg, $type = 500)
|
||||
{
|
||||
global $mode;
|
||||
|
||||
switch ($type) {
|
||||
case 403:
|
||||
$header = "403 Forbidden";
|
||||
break;
|
||||
case 404:
|
||||
$header = "404 Not Found";
|
||||
break;
|
||||
default:
|
||||
$header = "500 Internal Server Error";
|
||||
}
|
||||
|
||||
if ($mode == "strict") {
|
||||
$header = "404 Not Found";
|
||||
}
|
||||
|
||||
header("HTTP/1.0 $header");
|
||||
|
||||
if ($mode == "development") {
|
||||
die("[img.php] $msg");
|
||||
}
|
||||
|
||||
error_log("[img.php] $msg");
|
||||
die("HTTP/1.0 $header");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Custom exception handler.
|
||||
*/
|
||||
set_exception_handler(function ($exception) {
|
||||
errorPage(
|
||||
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||
. $exception->getMessage()
|
||||
. "</p><pre>"
|
||||
. $exception->getTraceAsString()
|
||||
. "</pre>",
|
||||
500
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string or return default value if not set.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $default value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value from $_GET or default value.
|
||||
*/
|
||||
function get($key, $default = null)
|
||||
{
|
||||
if (is_array($key)) {
|
||||
foreach ($key as $val) {
|
||||
if (isset($_GET[$val])) {
|
||||
return $_GET[$val];
|
||||
}
|
||||
}
|
||||
} elseif (isset($_GET[$key])) {
|
||||
return $_GET[$key];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string and set to $defined if defined or else $undefined.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $defined value to return when $key is set in $_GET.
|
||||
* @param mixed $undefined value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value as $defined or $undefined.
|
||||
*/
|
||||
function getDefined($key, $defined, $undefined)
|
||||
{
|
||||
return get($key) === null ? $undefined : $defined;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value from config array or default if key is not set in config array.
|
||||
*
|
||||
* @param string $key the key in the config array.
|
||||
* @param mixed $default value to be default if $key is not set in config.
|
||||
*
|
||||
* @return mixed value as $config[$key] or $default.
|
||||
*/
|
||||
function getConfig($key, $default)
|
||||
{
|
||||
global $config;
|
||||
return isset($config[$key])
|
||||
? $config[$key]
|
||||
: $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log when verbose mode, when used without argument it returns the result.
|
||||
*
|
||||
* @param string $msg to log.
|
||||
*
|
||||
* @return void or array.
|
||||
*/
|
||||
function verbose($msg = null)
|
||||
{
|
||||
global $verbose, $verboseFile;
|
||||
static $log = array();
|
||||
|
||||
if (!($verbose || $verboseFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($msg)) {
|
||||
return $log;
|
||||
}
|
||||
|
||||
$log[] = $msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a image from a remote server using HTTP GET and If-Modified-Since.
|
||||
*
|
||||
@ -1303,6 +1478,12 @@ class CImage
|
||||
private $useCache = true;
|
||||
|
||||
|
||||
/**
|
||||
* Disable the fasttrackCacke to start with, inject an object to enable it.
|
||||
*/
|
||||
private $fastTrackCache = null;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set whitelist for valid hostnames from where remote source can be
|
||||
@ -1370,6 +1551,25 @@ class CImage
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Inject object and use it, must be available as member.
|
||||
*
|
||||
* @param string $property to set as object.
|
||||
* @param object $object to set to property.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function injectDependency($property, $object)
|
||||
{
|
||||
if (!property_exists($this, $property)) {
|
||||
$this->raiseError("Injecting unknown property.");
|
||||
}
|
||||
$this->$property = $object;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set verbose mode.
|
||||
*
|
||||
@ -2630,9 +2830,6 @@ class CImage
|
||||
&& ($this->width < $this->newWidth || $this->height < $this->newHeight)) {
|
||||
$this->log("Resizing - smaller image, do not upscale.");
|
||||
|
||||
//$cropX = round(($this->cropWidth/2) - ($this->width/2));
|
||||
//$cropY = round(($this->cropHeight/2) - ($this->height/2));
|
||||
|
||||
$posX = 0;
|
||||
$posY = 0;
|
||||
$cropX = 0;
|
||||
@ -2663,7 +2860,6 @@ class CImage
|
||||
$this->log(" cropY: $cropY");
|
||||
|
||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||
//imagecopy($imageResized, $this->image, $posX, $posY, 0, 0, $this->width, $this->height);
|
||||
imagecopy($imageResized, $this->image, $posX, $posY, $cropX, $cropY, $this->width, $this->height);
|
||||
} else {
|
||||
$cropX = round(($this->cropWidth/2) - ($this->newWidth/2));
|
||||
@ -2746,7 +2942,6 @@ class CImage
|
||||
$cropX = round(($this->width - $this->newWidth) / 2);
|
||||
}
|
||||
|
||||
//$this->log("posX=$posX, posY=$posY, cropX=$cropX, cropY=$cropY.");
|
||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||
imagecopy($imageResized, $this->image, $posX, $posY, $cropX, $cropY, $this->width, $this->height);
|
||||
$this->image = $imageResized;
|
||||
@ -3449,7 +3644,7 @@ class CImage
|
||||
|
||||
|
||||
/**
|
||||
* Add HTTP header for putputting together with image.
|
||||
* Add HTTP header for output together with image.
|
||||
*
|
||||
* @param string $type the header type such as "Cache-Control"
|
||||
* @param string $value the value to use
|
||||
@ -3500,14 +3695,20 @@ class CImage
|
||||
// Get image modification time
|
||||
clearstatcache();
|
||||
$lastModified = filemtime($file);
|
||||
$gmdate = gmdate("D, d M Y H:i:s", $lastModified);
|
||||
$lastModifiedFormat = "D, d M Y H:i:s";
|
||||
$gmdate = gmdate($lastModifiedFormat, $lastModified);
|
||||
|
||||
if (!$this->verbose) {
|
||||
header('Last-Modified: ' . $gmdate . " GMT");
|
||||
$header = "Last-Modified: $gmdate GMT";
|
||||
header($header);
|
||||
$this->fastTrackCache->addHeader($header);
|
||||
$this->fastTrackCache->setLastModified($lastModified);
|
||||
}
|
||||
|
||||
foreach($this->HTTPHeader as $key => $val) {
|
||||
header("$key: $val");
|
||||
foreach ($this->HTTPHeader as $key => $val) {
|
||||
$header = "$key: $val";
|
||||
header($header);
|
||||
$this->fastTrackCache->addHeader($header);
|
||||
}
|
||||
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified) {
|
||||
@ -3539,8 +3740,16 @@ class CImage
|
||||
}
|
||||
}
|
||||
|
||||
header("Content-type: $mime");
|
||||
header("Content-length: $size");
|
||||
$header = "Content-type: $mime";
|
||||
header($header);
|
||||
$this->fastTrackCache->addHeaderOnOutput($header);
|
||||
|
||||
$header = "Content-length: $size";
|
||||
header($header);
|
||||
$this->fastTrackCache->addHeaderOnOutput($header);
|
||||
|
||||
$this->fastTrackCache->setSource($file);
|
||||
$this->fastTrackCache->writeToCache();
|
||||
readfile($file);
|
||||
}
|
||||
|
||||
@ -3834,6 +4043,236 @@ class CCache
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enable a fast track cache with a json representation of the image delivery.
|
||||
*
|
||||
*/
|
||||
class CFastTrackCache
|
||||
{
|
||||
/**
|
||||
* Cache is disabled to start with.
|
||||
*/
|
||||
private $enabled = false;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Path to the cache directory.
|
||||
*/
|
||||
private $path;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Filename of current cache item.
|
||||
*/
|
||||
private $filename;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Container with items to store as cached item.
|
||||
*/
|
||||
private $container;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enable or disable cache.
|
||||
*
|
||||
* @param boolean $enable set to true to enable, false to disable
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function enable($enabled)
|
||||
{
|
||||
$this->enabled = $enabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the path to the cache dir which must exist.
|
||||
*
|
||||
* @param string $path to the cache dir.
|
||||
*
|
||||
* @throws Exception when $path is not a directory.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCacheDir($path)
|
||||
{
|
||||
if (!is_dir($path)) {
|
||||
throw new Exception("Cachedir is not a directory.");
|
||||
}
|
||||
|
||||
$this->path = rtrim($path, "/");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the filename to store in cache, use the querystring to create that
|
||||
* filename.
|
||||
*
|
||||
* @param array $clear items to clear in $_GET when creating the filename.
|
||||
*
|
||||
* @return string as filename created.
|
||||
*/
|
||||
public function setFilename($clear)
|
||||
{
|
||||
$query = $_GET;
|
||||
|
||||
// Remove parts from querystring that should not be part of filename
|
||||
foreach ($clear as $value) {
|
||||
unset($query[$value]);
|
||||
}
|
||||
|
||||
arsort($query);
|
||||
$queryAsString = http_build_query($query);
|
||||
|
||||
$this->filename = md5($queryAsString);
|
||||
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add header items.
|
||||
*
|
||||
* @param string $header add this as header.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addHeader($header)
|
||||
{
|
||||
$this->container["header"][] = $header;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add header items on output, these are not output when 304.
|
||||
*
|
||||
* @param string $header add this as header.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addHeaderOnOutput($header)
|
||||
{
|
||||
$this->container["header-output"][] = $header;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set path to source image to.
|
||||
*
|
||||
* @param string $source path to source image file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSource($source)
|
||||
{
|
||||
$this->container["source"] = $source;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set last modified of source image, use to check for 304.
|
||||
*
|
||||
* @param string $lastModified
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setLastModified($lastModified)
|
||||
{
|
||||
$this->container["last-modified"] = $lastModified;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get filename of cached item.
|
||||
*
|
||||
* @return string as filename.
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->path . "/" . $this->filename;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Write current item to cache.
|
||||
*
|
||||
* @return boolean if cache file was written.
|
||||
*/
|
||||
public function writeToCache()
|
||||
{
|
||||
if (!$this->enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_dir($this->path) && is_writable($this->path)) {
|
||||
$filename = $this->getFilename();
|
||||
return file_put_contents($filename, json_encode($this->container)) !== false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Output current item from cache, if available.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
$filename = $this->getFilename();
|
||||
if (!is_readable($filename)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$item = json_decode(file_get_contents($filename), true);
|
||||
|
||||
if (!is_readable($item["source"])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($item["header"] as $value) {
|
||||
header($value);
|
||||
}
|
||||
|
||||
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])
|
||||
&& strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) == $item["last-modified"]) {
|
||||
header("HTTP/1.0 304 Not Modified");
|
||||
exit;
|
||||
}
|
||||
|
||||
foreach ($item["header-output"] as $value) {
|
||||
header($value);
|
||||
}
|
||||
|
||||
readfile($item["source"]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resize and crop images on the fly, store generated images in a cache.
|
||||
*
|
||||
@ -3843,151 +4282,6 @@ class CCache
|
||||
*
|
||||
*/
|
||||
|
||||
$version = "v0.7.11 (2016-04-18)";
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/$version");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display error message.
|
||||
*
|
||||
* @param string $msg to display.
|
||||
* @param int $type of HTTP error to display.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function errorPage($msg, $type = 500)
|
||||
{
|
||||
global $mode;
|
||||
|
||||
switch ($type) {
|
||||
case 403:
|
||||
$header = "403 Forbidden";
|
||||
break;
|
||||
case 404:
|
||||
$header = "404 Not Found";
|
||||
break;
|
||||
default:
|
||||
$header = "500 Internal Server Error";
|
||||
}
|
||||
|
||||
if ($mode == "strict") {
|
||||
$header = "404 Not Found";
|
||||
}
|
||||
|
||||
header("HTTP/1.0 $header");
|
||||
|
||||
if ($mode == "development") {
|
||||
die("[img.php] $msg");
|
||||
}
|
||||
|
||||
error_log("[img.php] $msg");
|
||||
die("HTTP/1.0 $header");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Custom exception handler.
|
||||
*/
|
||||
set_exception_handler(function ($exception) {
|
||||
errorPage(
|
||||
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||
. $exception->getMessage()
|
||||
. "</p><pre>"
|
||||
. $exception->getTraceAsString()
|
||||
. "</pre>",
|
||||
500
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string or return default value if not set.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $default value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value from $_GET or default value.
|
||||
*/
|
||||
function get($key, $default = null)
|
||||
{
|
||||
if (is_array($key)) {
|
||||
foreach ($key as $val) {
|
||||
if (isset($_GET[$val])) {
|
||||
return $_GET[$val];
|
||||
}
|
||||
}
|
||||
} elseif (isset($_GET[$key])) {
|
||||
return $_GET[$key];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string and set to $defined if defined or else $undefined.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $defined value to return when $key is set in $_GET.
|
||||
* @param mixed $undefined value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value as $defined or $undefined.
|
||||
*/
|
||||
function getDefined($key, $defined, $undefined)
|
||||
{
|
||||
return get($key) === null ? $undefined : $defined;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value from config array or default if key is not set in config array.
|
||||
*
|
||||
* @param string $key the key in the config array.
|
||||
* @param mixed $default value to be default if $key is not set in config.
|
||||
*
|
||||
* @return mixed value as $config[$key] or $default.
|
||||
*/
|
||||
function getConfig($key, $default)
|
||||
{
|
||||
global $config;
|
||||
return isset($config[$key])
|
||||
? $config[$key]
|
||||
: $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log when verbose mode, when used without argument it returns the result.
|
||||
*
|
||||
* @param string $msg to log.
|
||||
*
|
||||
* @return void or array.
|
||||
*/
|
||||
function verbose($msg = null)
|
||||
{
|
||||
global $verbose, $verboseFile;
|
||||
static $log = array();
|
||||
|
||||
if (!($verbose || $verboseFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($msg)) {
|
||||
return $log;
|
||||
}
|
||||
|
||||
$log[] = $msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get configuration options from file, if the file exists, else use $config
|
||||
* if its defined or create an empty $config.
|
||||
@ -4002,13 +4296,26 @@ if (is_file($configFile)) {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Setup the autoloader, but not when using a bundle.
|
||||
*/
|
||||
if (!defined("CIMAGE_BUNDLE")) {
|
||||
if (!isset($config["autoloader"])) {
|
||||
die("CImage: Missing autoloader.");
|
||||
}
|
||||
|
||||
require $config["autoloader"];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* verbose, v - do a verbose dump of what happens
|
||||
* vf - do verbose dump to file
|
||||
*/
|
||||
$verbose = getDefined(array('verbose', 'v'), true, false);
|
||||
$verboseFile = getDefined('vf', true, false);
|
||||
verbose("img.php version = $version");
|
||||
verbose("img.php version = " . CIMAGE_VERSION);
|
||||
|
||||
|
||||
|
||||
@ -4166,24 +4473,11 @@ verbose("referer host = $refererHost");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the source files.
|
||||
*/
|
||||
$autoloader = getConfig('autoloader', false);
|
||||
$cimageClass = getConfig('cimage_class', false);
|
||||
|
||||
if ($autoloader) {
|
||||
require $autoloader;
|
||||
} elseif ($cimageClass) {
|
||||
require $cimageClass;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the class for the image.
|
||||
*/
|
||||
$img = new CImage();
|
||||
$CImage = getConfig('CImage', 'CImage');
|
||||
$img = new $CImage();
|
||||
$img->setVerbose($verbose || $verboseFile);
|
||||
|
||||
|
||||
@ -4191,12 +4485,46 @@ $img->setVerbose($verbose || $verboseFile);
|
||||
/**
|
||||
* Get the cachepath from config.
|
||||
*/
|
||||
$CCache = getConfig('CCache', 'CCache');
|
||||
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
||||
$cache = new CCache();
|
||||
$cache = new $CCache();
|
||||
$cache->setDir($cachePath);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* no-cache, nc - skip the cached version and process and create a new version in cache.
|
||||
*/
|
||||
$useCache = getDefined(array('no-cache', 'nc'), false, true);
|
||||
|
||||
verbose("use cache = $useCache");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prepare fast track cache for swriting cache items.
|
||||
*/
|
||||
$fastTrackCache = "fasttrack";
|
||||
$allowFastTrackCache = getConfig('fast_track_allow', false);
|
||||
|
||||
$CFastTrackCache = getConfig('CFastTrackCache', 'CFastTrackCache');
|
||||
$ftc = new $CFastTrackCache();
|
||||
$ftc->setCacheDir($cache->getPathToSubdir($fastTrackCache))
|
||||
->enable($allowFastTrackCache)
|
||||
->setFilename(array('no-cache', 'nc'));
|
||||
$img->injectDependency("fastTrackCache", $ftc);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load and output images from fast track cache, if items are available
|
||||
* in cache.
|
||||
*/
|
||||
if ($useCache && $allowFastTrackCache) {
|
||||
$ftc->output();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allow or disallow remote download of images from other servers.
|
||||
@ -4542,15 +4870,6 @@ verbose("use original = $useOriginal");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* no-cache, nc - skip the cached version and process and create a new version in cache.
|
||||
*/
|
||||
$useCache = getDefined(array('no-cache', 'nc'), false, true);
|
||||
|
||||
verbose("use cache = $useCache");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* quality, q - set level of quality for jpeg images
|
||||
*/
|
||||
@ -4900,7 +5219,7 @@ if ($srgb || $srgbDefault) {
|
||||
* Display status
|
||||
*/
|
||||
if ($status) {
|
||||
$text = "img.php version = $version\n";
|
||||
$text = "img.php version = " . CIMAGE_VERSION . "\n";
|
||||
$text .= "PHP version = " . PHP_VERSION . "\n";
|
||||
$text .= "Running on: " . $_SERVER['SERVER_SOFTWARE'] . "\n";
|
||||
$text .= "Allow remote images = $allowRemote\n";
|
||||
@ -4917,6 +5236,9 @@ if ($status) {
|
||||
$res = $cache->getStatusOfSubdir("srgb");
|
||||
$text .= "Cache srgb $res\n";
|
||||
|
||||
$res = $cache->getStatusOfSubdir($fasttrackCache);
|
||||
$text .= "Cache fasttrack $res\n";
|
||||
|
||||
$text .= "Alias path writable = " . is_writable($aliasPath) . "\n";
|
||||
|
||||
$no = extension_loaded('exif') ? null : 'NOT';
|
||||
|
@ -3,37 +3,42 @@
|
||||
* Fast track cache, read entries from the cache before processing image
|
||||
* the ordinary way.
|
||||
*/
|
||||
// Include debug functions
|
||||
function debug1($msg)
|
||||
{
|
||||
$file = "/tmp/cimage";
|
||||
if (!is_writable($file)) {
|
||||
return;
|
||||
}
|
||||
$msg .= ":" . count(get_included_files());
|
||||
$msg .= ":" . round(memory_get_peak_usage()/1024/1024, 3) . "MB";
|
||||
$msg .= ":" . (string) round((microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']), 6) . "ms";
|
||||
file_put_contents($file, "$msg\n", FILE_APPEND);
|
||||
|
||||
// Load the config file or use defaults
|
||||
$configFile = __DIR__
|
||||
. "/"
|
||||
. basename(__FILE__, ".php")
|
||||
. "_config.php";
|
||||
|
||||
if (is_file($configFile) && is_readable($configFile)) {
|
||||
$config = require $configFile;
|
||||
} elseif (!isset($config)) {
|
||||
$config = array(
|
||||
"cache_path" => __DIR__ . "/../cache/",
|
||||
);
|
||||
}
|
||||
|
||||
//$useCache = getDefined(array('no-cache', 'nc'), false, true);
|
||||
|
||||
|
||||
$cachePath = __DIR__ . "/../cache/fasttrack";
|
||||
// Prepare to check if fast cache should be used
|
||||
$cachePath = $config["cache_path"] . "/fasttrack";
|
||||
$query = $_GET;
|
||||
|
||||
// Do not use cache when no-cache is active
|
||||
$useCache = !(array_key_exists("no-cache", $query) || array_key_exists("nc", $query));
|
||||
|
||||
// Remove parts from querystring that should not be part of filename
|
||||
$clear = array("nc", "no-cache");
|
||||
foreach ($clear as $value) {
|
||||
unset($query[$value]);
|
||||
}
|
||||
|
||||
// Create the cache filename
|
||||
arsort($query);
|
||||
$queryAsString = http_build_query($query);
|
||||
|
||||
$filename = md5($queryAsString);
|
||||
$filename = "$cachePath/$filename";
|
||||
if (is_readable($filename)) {
|
||||
|
||||
// Check cached item, if any
|
||||
if ($useCache && is_readable($filename)) {
|
||||
$item = json_decode(file_get_contents($filename), true);
|
||||
|
||||
if (is_readable($item["source"])) {
|
||||
@ -44,7 +49,6 @@ if (is_readable($filename)) {
|
||||
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])
|
||||
&& strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) == $item["last-modified"]) {
|
||||
header("HTTP/1.0 304 Not Modified");
|
||||
debug1("really fast track 304");
|
||||
exit;
|
||||
}
|
||||
|
||||
@ -52,12 +56,10 @@ if (is_readable($filename)) {
|
||||
header($value);
|
||||
}
|
||||
|
||||
debug1("really fast track 200");
|
||||
readfile($item["source"]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// No fast track cache, proceed as usual
|
||||
include __DIR__ . "/img.php";
|
||||
|
690
webroot/imgp.php
690
webroot/imgp.php
@ -10,6 +10,7 @@
|
||||
* @link https://github.com/mosbth/cimage
|
||||
*
|
||||
*/
|
||||
define("CIMAGE_BUNDLE", true);
|
||||
|
||||
|
||||
/**
|
||||
@ -36,6 +37,180 @@ $config = array(
|
||||
|
||||
|
||||
|
||||
// Version of cimage and img.php
|
||||
define("CIMAGE_VERSION", "v0.7.13 (2016-08-08)");
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/" . CIMAGE_VERSION);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* General functions to use in img.php.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Trace and log execution to logfile, useful for debugging and development.
|
||||
*
|
||||
* @param string $msg message to log to file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function trace($msg)
|
||||
{
|
||||
$file = "/tmp/cimage";
|
||||
if (!is_writable($file)) {
|
||||
die("Using trace without a writable logfile. Create the file '$file' and make it writable for the web server.");
|
||||
}
|
||||
|
||||
$msg .= ":" . count(get_included_files());
|
||||
$msg .= ":" . round(memory_get_peak_usage()/1024/1024, 3) . "MB";
|
||||
$msg .= ":" . (string) round((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]), 6) . "ms";
|
||||
file_put_contents($file, "$msg\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display error message.
|
||||
*
|
||||
* @param string $msg to display.
|
||||
* @param int $type of HTTP error to display.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function errorPage($msg, $type = 500)
|
||||
{
|
||||
global $mode;
|
||||
|
||||
switch ($type) {
|
||||
case 403:
|
||||
$header = "403 Forbidden";
|
||||
break;
|
||||
case 404:
|
||||
$header = "404 Not Found";
|
||||
break;
|
||||
default:
|
||||
$header = "500 Internal Server Error";
|
||||
}
|
||||
|
||||
if ($mode == "strict") {
|
||||
$header = "404 Not Found";
|
||||
}
|
||||
|
||||
header("HTTP/1.0 $header");
|
||||
|
||||
if ($mode == "development") {
|
||||
die("[img.php] $msg");
|
||||
}
|
||||
|
||||
error_log("[img.php] $msg");
|
||||
die("HTTP/1.0 $header");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Custom exception handler.
|
||||
*/
|
||||
set_exception_handler(function ($exception) {
|
||||
errorPage(
|
||||
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||
. $exception->getMessage()
|
||||
. "</p><pre>"
|
||||
. $exception->getTraceAsString()
|
||||
. "</pre>",
|
||||
500
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string or return default value if not set.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $default value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value from $_GET or default value.
|
||||
*/
|
||||
function get($key, $default = null)
|
||||
{
|
||||
if (is_array($key)) {
|
||||
foreach ($key as $val) {
|
||||
if (isset($_GET[$val])) {
|
||||
return $_GET[$val];
|
||||
}
|
||||
}
|
||||
} elseif (isset($_GET[$key])) {
|
||||
return $_GET[$key];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string and set to $defined if defined or else $undefined.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $defined value to return when $key is set in $_GET.
|
||||
* @param mixed $undefined value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value as $defined or $undefined.
|
||||
*/
|
||||
function getDefined($key, $defined, $undefined)
|
||||
{
|
||||
return get($key) === null ? $undefined : $defined;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value from config array or default if key is not set in config array.
|
||||
*
|
||||
* @param string $key the key in the config array.
|
||||
* @param mixed $default value to be default if $key is not set in config.
|
||||
*
|
||||
* @return mixed value as $config[$key] or $default.
|
||||
*/
|
||||
function getConfig($key, $default)
|
||||
{
|
||||
global $config;
|
||||
return isset($config[$key])
|
||||
? $config[$key]
|
||||
: $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log when verbose mode, when used without argument it returns the result.
|
||||
*
|
||||
* @param string $msg to log.
|
||||
*
|
||||
* @return void or array.
|
||||
*/
|
||||
function verbose($msg = null)
|
||||
{
|
||||
global $verbose, $verboseFile;
|
||||
static $log = array();
|
||||
|
||||
if (!($verbose || $verboseFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($msg)) {
|
||||
return $log;
|
||||
}
|
||||
|
||||
$log[] = $msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a image from a remote server using HTTP GET and If-Modified-Since.
|
||||
*
|
||||
@ -1303,6 +1478,12 @@ class CImage
|
||||
private $useCache = true;
|
||||
|
||||
|
||||
/**
|
||||
* Disable the fasttrackCacke to start with, inject an object to enable it.
|
||||
*/
|
||||
private $fastTrackCache = null;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set whitelist for valid hostnames from where remote source can be
|
||||
@ -1370,6 +1551,25 @@ class CImage
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Inject object and use it, must be available as member.
|
||||
*
|
||||
* @param string $property to set as object.
|
||||
* @param object $object to set to property.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function injectDependency($property, $object)
|
||||
{
|
||||
if (!property_exists($this, $property)) {
|
||||
$this->raiseError("Injecting unknown property.");
|
||||
}
|
||||
$this->$property = $object;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set verbose mode.
|
||||
*
|
||||
@ -2630,9 +2830,6 @@ class CImage
|
||||
&& ($this->width < $this->newWidth || $this->height < $this->newHeight)) {
|
||||
$this->log("Resizing - smaller image, do not upscale.");
|
||||
|
||||
//$cropX = round(($this->cropWidth/2) - ($this->width/2));
|
||||
//$cropY = round(($this->cropHeight/2) - ($this->height/2));
|
||||
|
||||
$posX = 0;
|
||||
$posY = 0;
|
||||
$cropX = 0;
|
||||
@ -2663,7 +2860,6 @@ class CImage
|
||||
$this->log(" cropY: $cropY");
|
||||
|
||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||
//imagecopy($imageResized, $this->image, $posX, $posY, 0, 0, $this->width, $this->height);
|
||||
imagecopy($imageResized, $this->image, $posX, $posY, $cropX, $cropY, $this->width, $this->height);
|
||||
} else {
|
||||
$cropX = round(($this->cropWidth/2) - ($this->newWidth/2));
|
||||
@ -2746,7 +2942,6 @@ class CImage
|
||||
$cropX = round(($this->width - $this->newWidth) / 2);
|
||||
}
|
||||
|
||||
//$this->log("posX=$posX, posY=$posY, cropX=$cropX, cropY=$cropY.");
|
||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||
imagecopy($imageResized, $this->image, $posX, $posY, $cropX, $cropY, $this->width, $this->height);
|
||||
$this->image = $imageResized;
|
||||
@ -3449,7 +3644,7 @@ class CImage
|
||||
|
||||
|
||||
/**
|
||||
* Add HTTP header for putputting together with image.
|
||||
* Add HTTP header for output together with image.
|
||||
*
|
||||
* @param string $type the header type such as "Cache-Control"
|
||||
* @param string $value the value to use
|
||||
@ -3500,14 +3695,20 @@ class CImage
|
||||
// Get image modification time
|
||||
clearstatcache();
|
||||
$lastModified = filemtime($file);
|
||||
$gmdate = gmdate("D, d M Y H:i:s", $lastModified);
|
||||
$lastModifiedFormat = "D, d M Y H:i:s";
|
||||
$gmdate = gmdate($lastModifiedFormat, $lastModified);
|
||||
|
||||
if (!$this->verbose) {
|
||||
header('Last-Modified: ' . $gmdate . " GMT");
|
||||
$header = "Last-Modified: $gmdate GMT";
|
||||
header($header);
|
||||
$this->fastTrackCache->addHeader($header);
|
||||
$this->fastTrackCache->setLastModified($lastModified);
|
||||
}
|
||||
|
||||
foreach($this->HTTPHeader as $key => $val) {
|
||||
header("$key: $val");
|
||||
foreach ($this->HTTPHeader as $key => $val) {
|
||||
$header = "$key: $val";
|
||||
header($header);
|
||||
$this->fastTrackCache->addHeader($header);
|
||||
}
|
||||
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified) {
|
||||
@ -3539,8 +3740,16 @@ class CImage
|
||||
}
|
||||
}
|
||||
|
||||
header("Content-type: $mime");
|
||||
header("Content-length: $size");
|
||||
$header = "Content-type: $mime";
|
||||
header($header);
|
||||
$this->fastTrackCache->addHeaderOnOutput($header);
|
||||
|
||||
$header = "Content-length: $size";
|
||||
header($header);
|
||||
$this->fastTrackCache->addHeaderOnOutput($header);
|
||||
|
||||
$this->fastTrackCache->setSource($file);
|
||||
$this->fastTrackCache->writeToCache();
|
||||
readfile($file);
|
||||
}
|
||||
|
||||
@ -3834,6 +4043,236 @@ class CCache
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enable a fast track cache with a json representation of the image delivery.
|
||||
*
|
||||
*/
|
||||
class CFastTrackCache
|
||||
{
|
||||
/**
|
||||
* Cache is disabled to start with.
|
||||
*/
|
||||
private $enabled = false;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Path to the cache directory.
|
||||
*/
|
||||
private $path;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Filename of current cache item.
|
||||
*/
|
||||
private $filename;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Container with items to store as cached item.
|
||||
*/
|
||||
private $container;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enable or disable cache.
|
||||
*
|
||||
* @param boolean $enable set to true to enable, false to disable
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function enable($enabled)
|
||||
{
|
||||
$this->enabled = $enabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the path to the cache dir which must exist.
|
||||
*
|
||||
* @param string $path to the cache dir.
|
||||
*
|
||||
* @throws Exception when $path is not a directory.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCacheDir($path)
|
||||
{
|
||||
if (!is_dir($path)) {
|
||||
throw new Exception("Cachedir is not a directory.");
|
||||
}
|
||||
|
||||
$this->path = rtrim($path, "/");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the filename to store in cache, use the querystring to create that
|
||||
* filename.
|
||||
*
|
||||
* @param array $clear items to clear in $_GET when creating the filename.
|
||||
*
|
||||
* @return string as filename created.
|
||||
*/
|
||||
public function setFilename($clear)
|
||||
{
|
||||
$query = $_GET;
|
||||
|
||||
// Remove parts from querystring that should not be part of filename
|
||||
foreach ($clear as $value) {
|
||||
unset($query[$value]);
|
||||
}
|
||||
|
||||
arsort($query);
|
||||
$queryAsString = http_build_query($query);
|
||||
|
||||
$this->filename = md5($queryAsString);
|
||||
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add header items.
|
||||
*
|
||||
* @param string $header add this as header.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addHeader($header)
|
||||
{
|
||||
$this->container["header"][] = $header;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add header items on output, these are not output when 304.
|
||||
*
|
||||
* @param string $header add this as header.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addHeaderOnOutput($header)
|
||||
{
|
||||
$this->container["header-output"][] = $header;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set path to source image to.
|
||||
*
|
||||
* @param string $source path to source image file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSource($source)
|
||||
{
|
||||
$this->container["source"] = $source;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set last modified of source image, use to check for 304.
|
||||
*
|
||||
* @param string $lastModified
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setLastModified($lastModified)
|
||||
{
|
||||
$this->container["last-modified"] = $lastModified;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get filename of cached item.
|
||||
*
|
||||
* @return string as filename.
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->path . "/" . $this->filename;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Write current item to cache.
|
||||
*
|
||||
* @return boolean if cache file was written.
|
||||
*/
|
||||
public function writeToCache()
|
||||
{
|
||||
if (!$this->enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_dir($this->path) && is_writable($this->path)) {
|
||||
$filename = $this->getFilename();
|
||||
return file_put_contents($filename, json_encode($this->container)) !== false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Output current item from cache, if available.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
$filename = $this->getFilename();
|
||||
if (!is_readable($filename)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$item = json_decode(file_get_contents($filename), true);
|
||||
|
||||
if (!is_readable($item["source"])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($item["header"] as $value) {
|
||||
header($value);
|
||||
}
|
||||
|
||||
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])
|
||||
&& strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) == $item["last-modified"]) {
|
||||
header("HTTP/1.0 304 Not Modified");
|
||||
exit;
|
||||
}
|
||||
|
||||
foreach ($item["header-output"] as $value) {
|
||||
header($value);
|
||||
}
|
||||
|
||||
readfile($item["source"]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resize and crop images on the fly, store generated images in a cache.
|
||||
*
|
||||
@ -3843,151 +4282,6 @@ class CCache
|
||||
*
|
||||
*/
|
||||
|
||||
$version = "v0.7.11 (2016-04-18)";
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/$version");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display error message.
|
||||
*
|
||||
* @param string $msg to display.
|
||||
* @param int $type of HTTP error to display.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function errorPage($msg, $type = 500)
|
||||
{
|
||||
global $mode;
|
||||
|
||||
switch ($type) {
|
||||
case 403:
|
||||
$header = "403 Forbidden";
|
||||
break;
|
||||
case 404:
|
||||
$header = "404 Not Found";
|
||||
break;
|
||||
default:
|
||||
$header = "500 Internal Server Error";
|
||||
}
|
||||
|
||||
if ($mode == "strict") {
|
||||
$header = "404 Not Found";
|
||||
}
|
||||
|
||||
header("HTTP/1.0 $header");
|
||||
|
||||
if ($mode == "development") {
|
||||
die("[img.php] $msg");
|
||||
}
|
||||
|
||||
error_log("[img.php] $msg");
|
||||
die("HTTP/1.0 $header");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Custom exception handler.
|
||||
*/
|
||||
set_exception_handler(function ($exception) {
|
||||
errorPage(
|
||||
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||
. $exception->getMessage()
|
||||
. "</p><pre>"
|
||||
. $exception->getTraceAsString()
|
||||
. "</pre>",
|
||||
500
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string or return default value if not set.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $default value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value from $_GET or default value.
|
||||
*/
|
||||
function get($key, $default = null)
|
||||
{
|
||||
if (is_array($key)) {
|
||||
foreach ($key as $val) {
|
||||
if (isset($_GET[$val])) {
|
||||
return $_GET[$val];
|
||||
}
|
||||
}
|
||||
} elseif (isset($_GET[$key])) {
|
||||
return $_GET[$key];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string and set to $defined if defined or else $undefined.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $defined value to return when $key is set in $_GET.
|
||||
* @param mixed $undefined value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value as $defined or $undefined.
|
||||
*/
|
||||
function getDefined($key, $defined, $undefined)
|
||||
{
|
||||
return get($key) === null ? $undefined : $defined;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value from config array or default if key is not set in config array.
|
||||
*
|
||||
* @param string $key the key in the config array.
|
||||
* @param mixed $default value to be default if $key is not set in config.
|
||||
*
|
||||
* @return mixed value as $config[$key] or $default.
|
||||
*/
|
||||
function getConfig($key, $default)
|
||||
{
|
||||
global $config;
|
||||
return isset($config[$key])
|
||||
? $config[$key]
|
||||
: $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log when verbose mode, when used without argument it returns the result.
|
||||
*
|
||||
* @param string $msg to log.
|
||||
*
|
||||
* @return void or array.
|
||||
*/
|
||||
function verbose($msg = null)
|
||||
{
|
||||
global $verbose, $verboseFile;
|
||||
static $log = array();
|
||||
|
||||
if (!($verbose || $verboseFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($msg)) {
|
||||
return $log;
|
||||
}
|
||||
|
||||
$log[] = $msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get configuration options from file, if the file exists, else use $config
|
||||
* if its defined or create an empty $config.
|
||||
@ -4002,13 +4296,26 @@ if (is_file($configFile)) {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Setup the autoloader, but not when using a bundle.
|
||||
*/
|
||||
if (!defined("CIMAGE_BUNDLE")) {
|
||||
if (!isset($config["autoloader"])) {
|
||||
die("CImage: Missing autoloader.");
|
||||
}
|
||||
|
||||
require $config["autoloader"];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* verbose, v - do a verbose dump of what happens
|
||||
* vf - do verbose dump to file
|
||||
*/
|
||||
$verbose = getDefined(array('verbose', 'v'), true, false);
|
||||
$verboseFile = getDefined('vf', true, false);
|
||||
verbose("img.php version = $version");
|
||||
verbose("img.php version = " . CIMAGE_VERSION);
|
||||
|
||||
|
||||
|
||||
@ -4166,24 +4473,11 @@ verbose("referer host = $refererHost");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the source files.
|
||||
*/
|
||||
$autoloader = getConfig('autoloader', false);
|
||||
$cimageClass = getConfig('cimage_class', false);
|
||||
|
||||
if ($autoloader) {
|
||||
require $autoloader;
|
||||
} elseif ($cimageClass) {
|
||||
require $cimageClass;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the class for the image.
|
||||
*/
|
||||
$img = new CImage();
|
||||
$CImage = getConfig('CImage', 'CImage');
|
||||
$img = new $CImage();
|
||||
$img->setVerbose($verbose || $verboseFile);
|
||||
|
||||
|
||||
@ -4191,12 +4485,46 @@ $img->setVerbose($verbose || $verboseFile);
|
||||
/**
|
||||
* Get the cachepath from config.
|
||||
*/
|
||||
$CCache = getConfig('CCache', 'CCache');
|
||||
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
||||
$cache = new CCache();
|
||||
$cache = new $CCache();
|
||||
$cache->setDir($cachePath);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* no-cache, nc - skip the cached version and process and create a new version in cache.
|
||||
*/
|
||||
$useCache = getDefined(array('no-cache', 'nc'), false, true);
|
||||
|
||||
verbose("use cache = $useCache");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prepare fast track cache for swriting cache items.
|
||||
*/
|
||||
$fastTrackCache = "fasttrack";
|
||||
$allowFastTrackCache = getConfig('fast_track_allow', false);
|
||||
|
||||
$CFastTrackCache = getConfig('CFastTrackCache', 'CFastTrackCache');
|
||||
$ftc = new $CFastTrackCache();
|
||||
$ftc->setCacheDir($cache->getPathToSubdir($fastTrackCache))
|
||||
->enable($allowFastTrackCache)
|
||||
->setFilename(array('no-cache', 'nc'));
|
||||
$img->injectDependency("fastTrackCache", $ftc);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load and output images from fast track cache, if items are available
|
||||
* in cache.
|
||||
*/
|
||||
if ($useCache && $allowFastTrackCache) {
|
||||
$ftc->output();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allow or disallow remote download of images from other servers.
|
||||
@ -4542,15 +4870,6 @@ verbose("use original = $useOriginal");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* no-cache, nc - skip the cached version and process and create a new version in cache.
|
||||
*/
|
||||
$useCache = getDefined(array('no-cache', 'nc'), false, true);
|
||||
|
||||
verbose("use cache = $useCache");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* quality, q - set level of quality for jpeg images
|
||||
*/
|
||||
@ -4900,7 +5219,7 @@ if ($srgb || $srgbDefault) {
|
||||
* Display status
|
||||
*/
|
||||
if ($status) {
|
||||
$text = "img.php version = $version\n";
|
||||
$text = "img.php version = " . CIMAGE_VERSION . "\n";
|
||||
$text .= "PHP version = " . PHP_VERSION . "\n";
|
||||
$text .= "Running on: " . $_SERVER['SERVER_SOFTWARE'] . "\n";
|
||||
$text .= "Allow remote images = $allowRemote\n";
|
||||
@ -4917,6 +5236,9 @@ if ($status) {
|
||||
$res = $cache->getStatusOfSubdir("srgb");
|
||||
$text .= "Cache srgb $res\n";
|
||||
|
||||
$res = $cache->getStatusOfSubdir($fasttrackCache);
|
||||
$text .= "Cache fasttrack $res\n";
|
||||
|
||||
$text .= "Alias path writable = " . is_writable($aliasPath) . "\n";
|
||||
|
||||
$no = extension_loaded('exif') ? null : 'NOT';
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user