Version Description
- Resize original images when compressing. Set a maximum width and/or height and your original images will be scaled down in case they are bigger.
- Added support for the mobile WordPress app (thanks to David Goodwin).
Download this release
Release Info
Developer | TinyPNG |
Plugin | Compress JPEG & PNG images |
Version | 1.5.0 |
Comparing to | |
See all releases |
Code changes from version 1.4.0 to 1.5.0
- RELEASE +13 -12
- bin/docker-functions +1 -1
- bin/integration-tests +1 -1
- bin/restore-wordpress +5 -1
- bin/test-wordpress +5 -1
- readme.txt +25 -19
- src/class-tiny-compress-curl.php +15 -5
- src/class-tiny-compress-fopen.php +17 -6
- src/class-tiny-compress.php +38 -5
- src/class-tiny-metadata.php +15 -6
- src/class-tiny-plugin.php +22 -9
- src/class-tiny-settings.php +89 -13
- src/class-tiny-wp-base.php +10 -1
- src/languages/tiny-compress-images-nl_NL.mo +0 -0
- src/languages/tiny-compress-images-nl_NL.po +34 -4
- src/scripts/admin.js +24 -3
- src/styles/admin.css +12 -0
- test/fixtures/input-large.jpg +0 -0
- test/helpers/wordpress.php +6 -1
- test/integration/CompressIntegrationTest.php +47 -0
- test/integration/IntegrationTestCase.php +39 -0
- test/integration/SettingsIntegrationTest.php +37 -5
- test/mock-tinypng-webservice/common.php +45 -0
- test/mock-tinypng-webservice/output-resized.jpg +0 -0
- test/mock-tinypng-webservice/output.php +21 -1
- test/mock-tinypng-webservice/reset.php +2 -5
- test/mock-tinypng-webservice/shrink.php +9 -32
- test/unit/TinyMetadataTest.php +18 -0
- test/unit/TinyPluginTest.php +23 -10
- test/unit/TinySettingsTest.php +47 -0
- tiny-compress-images.php +2 -2
RELEASE
CHANGED
@@ -2,15 +2,16 @@ In order to release a new version of the plugin to wordpress.org, perform the fo
|
|
2 |
|
3 |
1. Update the version in tiny-compress-images.php
|
4 |
2. Change the 'Stable tag' in readme.txt to the new release number.
|
5 |
-
3.
|
6 |
-
4.
|
7 |
-
5.
|
8 |
-
6.
|
9 |
-
7.
|
10 |
-
8.
|
11 |
-
9.
|
12 |
-
10.
|
13 |
-
11.
|
14 |
-
12.
|
15 |
-
13.
|
16 |
-
14.
|
|
2 |
|
3 |
1. Update the version in tiny-compress-images.php
|
4 |
2. Change the 'Stable tag' in readme.txt to the new release number.
|
5 |
+
3. Add release notes to readme.txt.
|
6 |
+
4. If you've changed the plugin to work with newer version of wordpress add that to the readme as well.
|
7 |
+
5. Commit and push to GitHub.
|
8 |
+
6. Create a new release in GitHub and pull it in.
|
9 |
+
7. Locally, checkout the new tag: `git checkout <tagged version>`.
|
10 |
+
8. If not already done so, checkout the plugin's Subversion repository: `svn co http://plugins.svn.wordpress.org/tiny-compress-images`.
|
11 |
+
9. Update svn:ignore property of trunk when .gitignore is updated: `svn propedit svn:ignore trunk`.
|
12 |
+
10. Delete everything in trunk `rm -rf <path-to-local-svn-repo/trunk/*`.
|
13 |
+
11. Manually copy the Git release to the local Subversion repo: `git ls-files | xargs tar c | tar x -C <path-to-local-svn-repo>/trunk/`.
|
14 |
+
12. Add new files `svn st | awk '/^\?/ { print $2; }' | xargs svn add`.
|
15 |
+
13. Delete deleted files: `svn st | awk '/^!/ { print $2; }' | xargs svn rm`.
|
16 |
+
14. Commit the trunk to Subversion: `svn ci -m "<message>"`.
|
17 |
+
15. Tag the new release in Subversion and commit: `svn cp trunk tags/<version> && svn ci -m "<message>"`.
|
bin/docker-functions
CHANGED
@@ -50,7 +50,7 @@ run_mysql() {
|
|
50 |
then
|
51 |
docker start "mysql-wordpress"
|
52 |
else
|
53 |
-
docker run --name mysql-wordpress -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql
|
54 |
fi
|
55 |
fi
|
56 |
}
|
50 |
then
|
51 |
docker start "mysql-wordpress"
|
52 |
else
|
53 |
+
docker run --name mysql-wordpress -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql:5.5
|
54 |
fi
|
55 |
fi
|
56 |
}
|
bin/integration-tests
CHANGED
@@ -10,7 +10,7 @@ my $dir = dirname($0);
|
|
10 |
|
11 |
my $hostip;
|
12 |
if (`which docker-machine`) {
|
13 |
-
$hostip = `docker-machine ip
|
14 |
} else {
|
15 |
$hostip = `boot2docker ip`;
|
16 |
}
|
10 |
|
11 |
my $hostip;
|
12 |
if (`which docker-machine`) {
|
13 |
+
$hostip = `docker-machine ip $ENV{'DOCKER_MACHINE_NAME'}`;
|
14 |
} else {
|
15 |
$hostip = `boot2docker ip`;
|
16 |
}
|
bin/restore-wordpress
CHANGED
@@ -21,10 +21,14 @@ export WORDPRESS_DATABASE=wordpress_$version
|
|
21 |
export MYSQL_ROOT_PASSWORD=root
|
22 |
|
23 |
if hash docker-machine 2>/dev/null; then
|
24 |
-
export HOST_IP=$(docker-machine ip
|
25 |
else
|
26 |
export HOST_IP=$(boot2docker ip)
|
27 |
fi
|
|
|
|
|
|
|
|
|
28 |
|
29 |
export MYSQL_DUMP_FILE=tmp/mysqldump_wordpress_$version.sql.gz
|
30 |
|
21 |
export MYSQL_ROOT_PASSWORD=root
|
22 |
|
23 |
if hash docker-machine 2>/dev/null; then
|
24 |
+
export HOST_IP=$(docker-machine ip $DOCKER_MACHINE_NAME)
|
25 |
else
|
26 |
export HOST_IP=$(boot2docker ip)
|
27 |
fi
|
28 |
+
if [ -z "$HOST_IP" ]; then
|
29 |
+
echo "Could not find docker machine ip"
|
30 |
+
exit 2
|
31 |
+
fi
|
32 |
|
33 |
export MYSQL_DUMP_FILE=tmp/mysqldump_wordpress_$version.sql.gz
|
34 |
|
bin/test-wordpress
CHANGED
@@ -28,10 +28,14 @@ export WORDPRESS_DATABASE=wordpress_$version
|
|
28 |
export MYSQL_ROOT_PASSWORD=root
|
29 |
|
30 |
if hash docker-machine 2>/dev/null; then
|
31 |
-
export HOST_IP=$(docker-machine ip
|
32 |
else
|
33 |
export HOST_IP=$(boot2docker ip)
|
34 |
fi
|
|
|
|
|
|
|
|
|
35 |
|
36 |
export HOST_PORT=80$version
|
37 |
export WORDPRESS_URL=http://$HOST_IP:$HOST_PORT
|
28 |
export MYSQL_ROOT_PASSWORD=root
|
29 |
|
30 |
if hash docker-machine 2>/dev/null; then
|
31 |
+
export HOST_IP=$(docker-machine ip $DOCKER_MACHINE_NAME)
|
32 |
else
|
33 |
export HOST_IP=$(boot2docker ip)
|
34 |
fi
|
35 |
+
if [ -z "$HOST_IP" ]; then
|
36 |
+
echo "Could not find docker machine ip"
|
37 |
+
exit 2
|
38 |
+
fi
|
39 |
|
40 |
export HOST_PORT=80$version
|
41 |
export WORDPRESS_URL=http://$HOST_IP:$HOST_PORT
|
readme.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
=== Compress JPEG & PNG images ===
|
2 |
Contributors: TinyPNG
|
3 |
Donate link: https://tinypng.com/
|
4 |
-
Tags: compress, optimize, shrink, improve, images, tinypng, tinyjpg, jpeg, jpg, png, lossy, jpegmini, crunch, minify, smush, save, bandwidth, website, speed, faster, performance, panda
|
5 |
Requires at least: 3.0.6
|
6 |
Tested up to: 4.4
|
7 |
-
Stable tag: 1.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -16,16 +16,17 @@ Make your website faster by compressing your JPEG and PNG images. This plugin au
|
|
16 |
|
17 |
= Features =
|
18 |
|
19 |
-
* Automatically compress new images.
|
20 |
-
*
|
21 |
* Compress individual images already in your media library.
|
|
|
|
|
22 |
* Multisite support with a single API key.
|
23 |
* Color profiles are translated to the standard RGB color space.
|
24 |
* See your usage directly from the media settings and during bulk compression.
|
25 |
-
*
|
26 |
-
*
|
27 |
-
*
|
28 |
-
* No file size limit.
|
29 |
|
30 |
= How does it work? =
|
31 |
|
@@ -98,29 +99,34 @@ A: Yes! After installing the plugin, go to Tools > Compress JPEG & PNG images, a
|
|
98 |
|
99 |
== Changelog ==
|
100 |
|
|
|
|
|
|
|
|
|
101 |
= 1.4.0 =
|
102 |
-
*
|
103 |
-
*
|
104 |
-
*
|
105 |
|
106 |
= 1.3.2 =
|
107 |
-
*
|
108 |
|
109 |
= 1.3.1 =
|
110 |
-
* Media library
|
111 |
|
112 |
= 1.3.0 =
|
113 |
-
* Improved bulk
|
114 |
-
*
|
|
|
115 |
|
116 |
= 1.2.1 =
|
117 |
-
*
|
118 |
|
119 |
= 1.2.0 =
|
120 |
* Display connection status and number of compressions this month on the settings page. This also allows you to check if you entered a valid API key.
|
121 |
-
* Show a notice to administrators when
|
122 |
-
* The plugin
|
123 |
-
*
|
124 |
|
125 |
= 1.1.0 =
|
126 |
* The API key can now be set with the TINY_API_KEY constant in wp-config.php. This will work for normal and multisite WordPress installations.
|
1 |
=== Compress JPEG & PNG images ===
|
2 |
Contributors: TinyPNG
|
3 |
Donate link: https://tinypng.com/
|
4 |
+
Tags: compress, optimize, shrink, resize, fit, scale, improve, images, tinypng, tinyjpg, jpeg, jpg, png, lossy, jpegmini, crunch, minify, smush, save, bandwidth, website, speed, faster, performance, panda, wordpress app
|
5 |
Requires at least: 3.0.6
|
6 |
Tested up to: 4.4
|
7 |
+
Stable tag: 1.5.0
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
16 |
|
17 |
= Features =
|
18 |
|
19 |
+
* Automatically compress new images on upload.
|
20 |
+
* Resize large original images by setting a maximum width and/or height.
|
21 |
* Compress individual images already in your media library.
|
22 |
+
* Easy bulk compression of your existing media library.
|
23 |
+
* Select which thumbnail sizes of an image may be compressed.
|
24 |
* Multisite support with a single API key.
|
25 |
* Color profiles are translated to the standard RGB color space.
|
26 |
* See your usage directly from the media settings and during bulk compression.
|
27 |
+
* Convert CMYK to RGB to save more space and maximize compatibility.
|
28 |
+
* Compress and resize uploads with the WordPress mobile app.
|
29 |
+
* No file size limits.
|
|
|
30 |
|
31 |
= How does it work? =
|
32 |
|
99 |
|
100 |
== Changelog ==
|
101 |
|
102 |
+
= 1.5.0 =
|
103 |
+
* Resize original images when compressing. Set a maximum width and/or height and your original images will be scaled down in case they are bigger.
|
104 |
+
* Added support for the mobile WordPress app (thanks to David Goodwin).
|
105 |
+
|
106 |
= 1.4.0 =
|
107 |
+
* Indication of the number of images you can compress for free each month.
|
108 |
+
* Link to the settings page from the plugin listing.
|
109 |
+
* Clarification that original images will be overwritten when compressed.
|
110 |
|
111 |
= 1.3.2 =
|
112 |
+
* Detect different thumbnail sizes with the same dimensions so they will not be compressed again.
|
113 |
|
114 |
= 1.3.1 =
|
115 |
+
* Media library shows files that are in the process of compression.
|
116 |
|
117 |
= 1.3.0 =
|
118 |
+
* Improved bulk compression from media library. Bulk compress your whole media library in one step.
|
119 |
+
* Better indication of image sizes that have been compressed.
|
120 |
+
* Detection of image sizes modified after compression by other plugins.
|
121 |
|
122 |
= 1.2.1 =
|
123 |
+
* Prevent compressing the original image if it is the only selected image size.
|
124 |
|
125 |
= 1.2.0 =
|
126 |
* Display connection status and number of compressions this month on the settings page. This also allows you to check if you entered a valid API key.
|
127 |
+
* Show a notice to administrators when the limit of the fixed and free plans is reached.
|
128 |
+
* The plugin now works when php's parse_ini_file is disabled on your host.
|
129 |
+
* Avoids warnings when no image sizes have been selected.
|
130 |
|
131 |
= 1.1.0 =
|
132 |
* The API key can now be set with the TINY_API_KEY constant in wp-config.php. This will work for normal and multisite WordPress installations.
|
src/class-tiny-compress-curl.php
CHANGED
@@ -63,22 +63,32 @@ class Tiny_Compress_Curl extends Tiny_Compress {
|
|
63 |
return array(self::decode(substr($response, $header_size)), $headers, $status_code);
|
64 |
}
|
65 |
|
66 |
-
protected function output_options($url) {
|
67 |
-
|
68 |
CURLOPT_URL => $url,
|
69 |
CURLOPT_RETURNTRANSFER => true,
|
|
|
70 |
CURLOPT_CAINFO => self::get_ca_file(),
|
71 |
CURLOPT_SSL_VERIFYPEER => true
|
72 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
-
protected function output($url) {
|
76 |
$request = curl_init();
|
77 |
-
|
|
|
78 |
|
79 |
$response = curl_exec($request);
|
|
|
|
|
80 |
curl_close($request);
|
81 |
|
82 |
-
return $response;
|
83 |
}
|
84 |
}
|
63 |
return array(self::decode(substr($response, $header_size)), $headers, $status_code);
|
64 |
}
|
65 |
|
66 |
+
protected function output_options($url, $resize) {
|
67 |
+
$options = array(
|
68 |
CURLOPT_URL => $url,
|
69 |
CURLOPT_RETURNTRANSFER => true,
|
70 |
+
CURLOPT_HEADER => true,
|
71 |
CURLOPT_CAINFO => self::get_ca_file(),
|
72 |
CURLOPT_SSL_VERIFYPEER => true
|
73 |
);
|
74 |
+
if ($resize) {
|
75 |
+
$options[CURLOPT_USERPWD] = 'api:' . $this->api_key;
|
76 |
+
$options[CURLOPT_HTTPHEADER] = array('Content-Type: application/json');
|
77 |
+
$options[CURLOPT_POSTFIELDS] = json_encode(array('resize' => $resize));
|
78 |
+
}
|
79 |
+
return $options;
|
80 |
}
|
81 |
|
82 |
+
protected function output($url, $resize) {
|
83 |
$request = curl_init();
|
84 |
+
$options = $this->output_options($url, $resize);
|
85 |
+
curl_setopt_array($request, $options);
|
86 |
|
87 |
$response = curl_exec($request);
|
88 |
+
$header_size = curl_getinfo($request, CURLINFO_HEADER_SIZE);
|
89 |
+
$headers = self::parse_headers(substr($response, 0, $header_size));
|
90 |
curl_close($request);
|
91 |
|
92 |
+
return array(substr($response, $header_size), $headers);
|
93 |
}
|
94 |
}
|
src/class-tiny-compress-fopen.php
CHANGED
@@ -51,6 +51,7 @@ class Tiny_Compress_Fopen extends Tiny_Compress {
|
|
51 |
|
52 |
if (!$request) {
|
53 |
$headers = self::parse_headers($http_response_header);
|
|
|
54 |
return array(array(
|
55 |
'error' => 'FopenError',
|
56 |
'message' => 'Could not compress, enable cURL for detailed error',
|
@@ -66,8 +67,8 @@ class Tiny_Compress_Fopen extends Tiny_Compress {
|
|
66 |
return array(self::decode($response), $headers, $status_code);
|
67 |
}
|
68 |
|
69 |
-
protected function output_options() {
|
70 |
-
|
71 |
'http' => array(
|
72 |
'method' => 'GET',
|
73 |
),
|
@@ -76,19 +77,29 @@ class Tiny_Compress_Fopen extends Tiny_Compress {
|
|
76 |
'verify_peer' => true
|
77 |
)
|
78 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
|
81 |
-
protected function output($url) {
|
82 |
-
$context = stream_context_create($this->output_options());
|
83 |
$request = @fopen($url, 'rb', false, $context);
|
84 |
|
85 |
if ($request) {
|
86 |
$response = stream_get_contents($request);
|
|
|
|
|
87 |
fclose($request);
|
88 |
} else {
|
89 |
$response = '';
|
|
|
90 |
}
|
91 |
-
|
92 |
-
return $response;
|
93 |
}
|
94 |
}
|
51 |
|
52 |
if (!$request) {
|
53 |
$headers = self::parse_headers($http_response_header);
|
54 |
+
|
55 |
return array(array(
|
56 |
'error' => 'FopenError',
|
57 |
'message' => 'Could not compress, enable cURL for detailed error',
|
67 |
return array(self::decode($response), $headers, $status_code);
|
68 |
}
|
69 |
|
70 |
+
protected function output_options($resize) {
|
71 |
+
$options = array(
|
72 |
'http' => array(
|
73 |
'method' => 'GET',
|
74 |
),
|
77 |
'verify_peer' => true
|
78 |
)
|
79 |
);
|
80 |
+
if ($resize) {
|
81 |
+
$options['http']['header'] = array(
|
82 |
+
'Authorization: Basic ' . base64_encode('api:' . $this->api_key),
|
83 |
+
'Content-Type: application/json'
|
84 |
+
);
|
85 |
+
$options['http']['content'] = json_encode(array('resize' => $resize));
|
86 |
+
}
|
87 |
+
return $options;
|
88 |
}
|
89 |
|
90 |
+
protected function output($url, $resize) {
|
91 |
+
$context = stream_context_create($this->output_options($resize));
|
92 |
$request = @fopen($url, 'rb', false, $context);
|
93 |
|
94 |
if ($request) {
|
95 |
$response = stream_get_contents($request);
|
96 |
+
$meta_data = stream_get_meta_data($request);
|
97 |
+
$headers = self::parse_headers($meta_data['wrapper_data']);
|
98 |
fclose($request);
|
99 |
} else {
|
100 |
$response = '';
|
101 |
+
$headers = array();
|
102 |
}
|
103 |
+
return array($response, $headers);
|
|
|
104 |
}
|
105 |
}
|
src/class-tiny-compress.php
CHANGED
@@ -41,7 +41,7 @@ abstract class Tiny_Compress {
|
|
41 |
}
|
42 |
|
43 |
abstract protected function shrink($input);
|
44 |
-
abstract protected function output($url);
|
45 |
|
46 |
public function get_status(&$details) {
|
47 |
list($details, $headers, $status_code) = $this->shrink(null);
|
@@ -54,7 +54,7 @@ abstract class Tiny_Compress {
|
|
54 |
}
|
55 |
}
|
56 |
|
57 |
-
public function compress($input) {
|
58 |
list($details, $headers) = $this->shrink($input);
|
59 |
$this->call_after_compress_callback($details, $headers);
|
60 |
$outputUrl = isset($headers['location']) ? $headers['location'] : null;
|
@@ -63,19 +63,31 @@ abstract class Tiny_Compress {
|
|
63 |
} else if ($outputUrl === null) {
|
64 |
throw new Tiny_Exception('Could not find output url', 'OutputNotFound');
|
65 |
}
|
66 |
-
$output = $this->output($outputUrl);
|
|
|
67 |
if (strlen($output) == 0) {
|
68 |
throw new Tiny_Exception('Could not download output', 'OutputError');
|
69 |
}
|
|
|
70 |
return array($output, $details);
|
71 |
}
|
72 |
|
73 |
-
public function compress_file($file) {
|
74 |
if (!file_exists($file)) {
|
75 |
throw new Tiny_Exception('File does not exist', 'FileError');
|
76 |
}
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
78 |
file_put_contents($file, $output);
|
|
|
|
|
|
|
|
|
|
|
79 |
return $details;
|
80 |
}
|
81 |
|
@@ -109,5 +121,26 @@ abstract class Tiny_Compress {
|
|
109 |
}
|
110 |
return $result;
|
111 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
}
|
113 |
|
41 |
}
|
42 |
|
43 |
abstract protected function shrink($input);
|
44 |
+
abstract protected function output($url, $resize);
|
45 |
|
46 |
public function get_status(&$details) {
|
47 |
list($details, $headers, $status_code) = $this->shrink(null);
|
54 |
}
|
55 |
}
|
56 |
|
57 |
+
public function compress($input, $resize_options) {
|
58 |
list($details, $headers) = $this->shrink($input);
|
59 |
$this->call_after_compress_callback($details, $headers);
|
60 |
$outputUrl = isset($headers['location']) ? $headers['location'] : null;
|
63 |
} else if ($outputUrl === null) {
|
64 |
throw new Tiny_Exception('Could not find output url', 'OutputNotFound');
|
65 |
}
|
66 |
+
list($output, $headers) = $this->output($outputUrl, $resize_options);
|
67 |
+
$this->call_after_compress_callback(null, $headers);
|
68 |
if (strlen($output) == 0) {
|
69 |
throw new Tiny_Exception('Could not download output', 'OutputError');
|
70 |
}
|
71 |
+
|
72 |
return array($output, $details);
|
73 |
}
|
74 |
|
75 |
+
public function compress_file($file, $resize_options) {
|
76 |
if (!file_exists($file)) {
|
77 |
throw new Tiny_Exception('File does not exist', 'FileError');
|
78 |
}
|
79 |
+
|
80 |
+
if (!self::needs_resize($file, $resize_options)) {
|
81 |
+
$resize_options = false;
|
82 |
+
}
|
83 |
+
|
84 |
+
list($output, $details) = $this->compress(file_get_contents($file), $resize_options);
|
85 |
file_put_contents($file, $output);
|
86 |
+
|
87 |
+
if ($resize_options) {
|
88 |
+
$details['output'] = self::update_details($file, $details) + $details['output'];
|
89 |
+
}
|
90 |
+
|
91 |
return $details;
|
92 |
}
|
93 |
|
121 |
}
|
122 |
return $result;
|
123 |
}
|
124 |
+
|
125 |
+
protected static function needs_resize($file, $resize_options) {
|
126 |
+
if (!$resize_options) {
|
127 |
+
return false;
|
128 |
+
}
|
129 |
+
|
130 |
+
list($width, $height) = getimagesize($file);
|
131 |
+
return $width > $resize_options['width'] || $height > $resize_options['height'];
|
132 |
+
}
|
133 |
+
|
134 |
+
protected static function update_details($file, $details) {
|
135 |
+
$size = filesize($file);
|
136 |
+
list($width, $height) = getimagesize($file);
|
137 |
+
return array(
|
138 |
+
'size' => $size,
|
139 |
+
'width' => $width,
|
140 |
+
'height' => $height,
|
141 |
+
'ratio' => round($size / $details['input']['size'], 4),
|
142 |
+
'resized' => true
|
143 |
+
);
|
144 |
+
}
|
145 |
}
|
146 |
|
src/class-tiny-metadata.php
CHANGED
@@ -73,17 +73,22 @@ class Tiny_Metadata {
|
|
73 |
}
|
74 |
}
|
75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
public function update() {
|
77 |
update_post_meta($this->id, self::META_KEY, $this->values);
|
78 |
}
|
79 |
|
80 |
public function add_response($response, $size=self::ORIGINAL) {
|
81 |
-
$
|
82 |
-
|
83 |
-
'output' => array('size' => $response['output']['size']),
|
84 |
-
'end' => time()
|
85 |
-
);
|
86 |
-
$this->values[$size] = array_merge($this->values[$size], $data);
|
87 |
}
|
88 |
|
89 |
public function add_request($size=self::ORIGINAL) {
|
@@ -171,4 +176,8 @@ class Tiny_Metadata {
|
|
171 |
}
|
172 |
return $result;
|
173 |
}
|
|
|
|
|
|
|
|
|
174 |
}
|
73 |
}
|
74 |
}
|
75 |
|
76 |
+
public function update_wp_metadata($wp_metadata) {
|
77 |
+
$tiny_metadata = $this->get_value();
|
78 |
+
if (isset($tiny_metadata) && isset($tiny_metadata['output']) && isset($tiny_metadata['output']['width']) && isset($tiny_metadata['output']['height'])) {
|
79 |
+
$wp_metadata['width'] = $tiny_metadata['output']['width'];
|
80 |
+
$wp_metadata['height'] = $tiny_metadata['output']['height'];
|
81 |
+
}
|
82 |
+
return $wp_metadata;
|
83 |
+
}
|
84 |
+
|
85 |
public function update() {
|
86 |
update_post_meta($this->id, self::META_KEY, $this->values);
|
87 |
}
|
88 |
|
89 |
public function add_response($response, $size=self::ORIGINAL) {
|
90 |
+
$response['end'] = time();
|
91 |
+
$this->values[$size] = array_merge($this->values[$size], $response);
|
|
|
|
|
|
|
|
|
92 |
}
|
93 |
|
94 |
public function add_request($size=self::ORIGINAL) {
|
176 |
}
|
177 |
return $result;
|
178 |
}
|
179 |
+
|
180 |
+
public function is_resizable($size) {
|
181 |
+
return $size === self::ORIGINAL;
|
182 |
+
}
|
183 |
}
|
src/class-tiny-plugin.php
CHANGED
@@ -102,7 +102,7 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
102 |
$tiny_metadata = new Tiny_Metadata($attachment_id, $metadata);
|
103 |
|
104 |
if ($this->settings->get_compressor() === null || strpos($mime_type, 'image/') !== 0) {
|
105 |
-
return $
|
106 |
}
|
107 |
|
108 |
$success = 0;
|
@@ -116,9 +116,8 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
116 |
try {
|
117 |
$tiny_metadata->add_request($uncompressed_size);
|
118 |
$tiny_metadata->update();
|
119 |
-
$
|
120 |
-
$
|
121 |
-
|
122 |
$tiny_metadata->add_response($response, $uncompressed_size);
|
123 |
$success++;
|
124 |
} catch (Tiny_Exception $e) {
|
@@ -132,8 +131,8 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
132 |
}
|
133 |
|
134 |
public function compress_attachment($metadata, $attachment_id) {
|
135 |
-
$this->compress($metadata, $attachment_id);
|
136 |
-
return $metadata;
|
137 |
}
|
138 |
|
139 |
public function compress_image() {
|
@@ -160,6 +159,8 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
160 |
}
|
161 |
|
162 |
list($tiny_metadata, $result) = $this->compress($metadata, $id);
|
|
|
|
|
163 |
if ($json) {
|
164 |
$result['message'] = $tiny_metadata->get_latest_error();
|
165 |
$result['status'] = $this->settings->get_status();
|
@@ -211,6 +212,11 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
211 |
|
212 |
if (count($missing) > 0) {
|
213 |
printf(self::translate_escape('Compressed %d out of %d sizes'), $success, $total);
|
|
|
|
|
|
|
|
|
|
|
214 |
echo '<br/>';
|
215 |
if (($error = $tiny_metadata->get_latest_error())) {
|
216 |
echo '<span class="error">' . self::translate_escape('Latest error') . ': '. self::translate_escape($error) .'</span><br/>';
|
@@ -222,6 +228,11 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
222 |
printf(self::translate_escape('Compressing %d sizes...'), count($this->settings->get_active_tinify_sizes()));
|
223 |
} else {
|
224 |
printf(self::translate_escape('Compressed %d out of %d sizes'), $success, $total);
|
|
|
|
|
|
|
|
|
|
|
225 |
$savings = $tiny_metadata->get_savings();
|
226 |
if ($savings['count'] > 0) {
|
227 |
echo '<br/>';
|
@@ -238,12 +249,14 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
238 |
echo '<h2>' . self::translate('Compress JPEG & PNG Images') . '</h2>';
|
239 |
if (empty($_POST['tiny-bulk-compress']) && empty($_REQUEST['ids'])) {
|
240 |
$result = $wpdb->get_results("SELECT COUNT(*) AS `count` FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%' ORDER BY ID DESC", ARRAY_A);
|
241 |
-
$
|
|
|
242 |
|
243 |
echo '<p>' . self::translate_escape("Use this tool to compress all images in your media library") . '. ';
|
244 |
echo self::translate_escape("Only images that have not been compressed will be compressed") . '.</p>';
|
245 |
-
echo '<p>' . sprintf(self::translate_escape("We have found %d images in your media library"), $
|
246 |
-
echo self::translate_escape(
|
|
|
247 |
|
248 |
echo '<form method="POST" action="?page=tiny-bulk-compress">';
|
249 |
echo '<input type="hidden" name="_wpnonce" value="' . wp_create_nonce('tiny-bulk-compress') . '">';
|
102 |
$tiny_metadata = new Tiny_Metadata($attachment_id, $metadata);
|
103 |
|
104 |
if ($this->settings->get_compressor() === null || strpos($mime_type, 'image/') !== 0) {
|
105 |
+
return array($tiny_metadata, null);
|
106 |
}
|
107 |
|
108 |
$success = 0;
|
116 |
try {
|
117 |
$tiny_metadata->add_request($uncompressed_size);
|
118 |
$tiny_metadata->update();
|
119 |
+
$resize = $tiny_metadata->is_resizable($uncompressed_size) ? $this->settings->get_resize_options() : false;
|
120 |
+
$response = $compressor->compress_file($tiny_metadata->get_filename($uncompressed_size), $resize);
|
|
|
121 |
$tiny_metadata->add_response($response, $uncompressed_size);
|
122 |
$success++;
|
123 |
} catch (Tiny_Exception $e) {
|
131 |
}
|
132 |
|
133 |
public function compress_attachment($metadata, $attachment_id) {
|
134 |
+
list($tiny_metadata, $result) = $this->compress($metadata, $attachment_id);
|
135 |
+
return $tiny_metadata->update_wp_metadata($metadata);
|
136 |
}
|
137 |
|
138 |
public function compress_image() {
|
159 |
}
|
160 |
|
161 |
list($tiny_metadata, $result) = $this->compress($metadata, $id);
|
162 |
+
wp_update_attachment_metadata($id, $tiny_metadata->update_wp_metadata($metadata));
|
163 |
+
|
164 |
if ($json) {
|
165 |
$result['message'] = $tiny_metadata->get_latest_error();
|
166 |
$result['status'] = $this->settings->get_status();
|
212 |
|
213 |
if (count($missing) > 0) {
|
214 |
printf(self::translate_escape('Compressed %d out of %d sizes'), $success, $total);
|
215 |
+
$original = $tiny_metadata->get_value();
|
216 |
+
if (isset($original['output']['resized'])) {
|
217 |
+
echo '<br/>';
|
218 |
+
printf(self::translate_escape('Resized original to %dx%d'), $original['output']['width'], $original['output']['height']);
|
219 |
+
}
|
220 |
echo '<br/>';
|
221 |
if (($error = $tiny_metadata->get_latest_error())) {
|
222 |
echo '<span class="error">' . self::translate_escape('Latest error') . ': '. self::translate_escape($error) .'</span><br/>';
|
228 |
printf(self::translate_escape('Compressing %d sizes...'), count($this->settings->get_active_tinify_sizes()));
|
229 |
} else {
|
230 |
printf(self::translate_escape('Compressed %d out of %d sizes'), $success, $total);
|
231 |
+
$original = $tiny_metadata->get_value();
|
232 |
+
if (isset($original['output']['resized'])) {
|
233 |
+
echo '<br/>';
|
234 |
+
printf(self::translate_escape('Resized original to %dx%d'), $original['output']['width'], $original['output']['height']);
|
235 |
+
}
|
236 |
$savings = $tiny_metadata->get_savings();
|
237 |
if ($savings['count'] > 0) {
|
238 |
echo '<br/>';
|
249 |
echo '<h2>' . self::translate('Compress JPEG & PNG Images') . '</h2>';
|
250 |
if (empty($_POST['tiny-bulk-compress']) && empty($_REQUEST['ids'])) {
|
251 |
$result = $wpdb->get_results("SELECT COUNT(*) AS `count` FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%' ORDER BY ID DESC", ARRAY_A);
|
252 |
+
$image_count = $result[0]['count'];
|
253 |
+
$sizes_count = count($this->settings->get_active_tinify_sizes());
|
254 |
|
255 |
echo '<p>' . self::translate_escape("Use this tool to compress all images in your media library") . '. ';
|
256 |
echo self::translate_escape("Only images that have not been compressed will be compressed") . '.</p>';
|
257 |
+
echo '<p>' . sprintf(self::translate_escape("We have found %d images in your media library and for each image %d sizes will be compressed"), $image_count, $sizes_count) . '. ';
|
258 |
+
echo sprintf(self::translate_escape('This results in %d compressions at most'), $image_count*$sizes_count) . '.</p>';
|
259 |
+
echo '<p>' . self::translate_escape("To begin, just press the button below") . '.</p>';
|
260 |
|
261 |
echo '<form method="POST" action="?page=tiny-bulk-compress">';
|
262 |
echo '<input type="hidden" name="_wpnonce" value="' . wp_create_nonce('tiny-bulk-compress') . '">';
|
src/class-tiny-settings.php
CHANGED
@@ -32,14 +32,25 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
32 |
$this->notices = new Tiny_Notices();
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
public function admin_init() {
|
36 |
if (current_user_can('manage_options') && !$this->get_api_key()) {
|
37 |
$link = sprintf('<a href="options-media.php#%s">%s</a>', self::NAME,
|
38 |
self::translate_escape('Please fill in an API key to start compressing images'));
|
39 |
$this->notices->show('setting', $link, 'error', false);
|
40 |
}
|
41 |
-
|
42 |
-
$this->
|
43 |
} catch (Tiny_Exception $e) {
|
44 |
$this->notices->show('compressor_exception', self::translate_escape($e->getMessage()), 'error', false);
|
45 |
}
|
@@ -55,6 +66,10 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
55 |
register_setting('media', $field);
|
56 |
add_settings_field($field, self::translate('File compression'), $this->get_method('render_sizes'), 'media', $section);
|
57 |
|
|
|
|
|
|
|
|
|
58 |
$field = self::get_prefixed_name('status');
|
59 |
register_setting('media', $field);
|
60 |
add_settings_field($field, self::translate('Connection status'), $this->get_method('render_pending_status'), 'media', $section);
|
@@ -64,7 +79,7 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
64 |
}
|
65 |
|
66 |
public function image_sizes_notice() {
|
67 |
-
$this->render_image_sizes_notice($_GET["image_sizes_selected"]);
|
68 |
exit();
|
69 |
}
|
70 |
|
@@ -155,6 +170,32 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
155 |
return $this->tinify_sizes;
|
156 |
}
|
157 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
public function render_section() {
|
159 |
echo '<span id="' . self::NAME . '"></span>';
|
160 |
}
|
@@ -187,7 +228,7 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
187 |
}
|
188 |
|
189 |
echo '<div id="tiny-image-sizes-notice">';
|
190 |
-
$this->render_image_sizes_notice(count(self::get_active_tinify_sizes()));
|
191 |
echo '</div>';
|
192 |
}
|
193 |
|
@@ -204,22 +245,57 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
204 |
<?php
|
205 |
}
|
206 |
|
207 |
-
public function render_image_sizes_notice($active_image_sizes_count) {
|
208 |
-
echo '<br
|
209 |
-
|
210 |
-
|
|
|
|
|
211 |
}
|
212 |
-
|
|
|
|
|
213 |
$free_images_per_month = floor(self::MONTHLY_FREE_COMPRESSIONS / $active_image_sizes_count);
|
214 |
-
|
215 |
-
echo '<p>';
|
216 |
echo self::translate_escape('With these settings you can compress');
|
217 |
echo ' <strong>';
|
218 |
-
printf(self::translate_escape('%s images'), $free_images_per_month);
|
219 |
echo '</strong> ';
|
220 |
echo self::translate_escape('for free each month') . '.';
|
221 |
-
echo '</p>';
|
222 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
}
|
224 |
|
225 |
public function get_compression_count() {
|
32 |
$this->notices = new Tiny_Notices();
|
33 |
}
|
34 |
|
35 |
+
private function init_compressor() {
|
36 |
+
$this->compressor = Tiny_Compress::get_compressor($this->get_api_key(), $this->get_method('after_compress_callback'));
|
37 |
+
}
|
38 |
+
|
39 |
+
public function xmlrpc_init() {
|
40 |
+
try {
|
41 |
+
$this->init_compressor();
|
42 |
+
} catch (Tiny_Exception $e) {
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
public function admin_init() {
|
47 |
if (current_user_can('manage_options') && !$this->get_api_key()) {
|
48 |
$link = sprintf('<a href="options-media.php#%s">%s</a>', self::NAME,
|
49 |
self::translate_escape('Please fill in an API key to start compressing images'));
|
50 |
$this->notices->show('setting', $link, 'error', false);
|
51 |
}
|
52 |
+
try {
|
53 |
+
$this->init_compressor();
|
54 |
} catch (Tiny_Exception $e) {
|
55 |
$this->notices->show('compressor_exception', self::translate_escape($e->getMessage()), 'error', false);
|
56 |
}
|
66 |
register_setting('media', $field);
|
67 |
add_settings_field($field, self::translate('File compression'), $this->get_method('render_sizes'), 'media', $section);
|
68 |
|
69 |
+
$field = self::get_prefixed_name('resize_original');
|
70 |
+
register_setting('media', $field);
|
71 |
+
add_settings_field($field, self::translate('Resize original'), $this->get_method('render_resize'), 'media', $section);
|
72 |
+
|
73 |
$field = self::get_prefixed_name('status');
|
74 |
register_setting('media', $field);
|
75 |
add_settings_field($field, self::translate('Connection status'), $this->get_method('render_pending_status'), 'media', $section);
|
79 |
}
|
80 |
|
81 |
public function image_sizes_notice() {
|
82 |
+
$this->render_image_sizes_notice($_GET["image_sizes_selected"], isset($_GET["resize_original"]));
|
83 |
exit();
|
84 |
}
|
85 |
|
170 |
return $this->tinify_sizes;
|
171 |
}
|
172 |
|
173 |
+
public function get_resize_enabled() {
|
174 |
+
$setting = get_option(self::get_prefixed_name('resize_original'));
|
175 |
+
return isset($setting['enabled']) && $setting['enabled'] === 'on';
|
176 |
+
}
|
177 |
+
|
178 |
+
public function get_resize_options() {
|
179 |
+
$setting = get_option(self::get_prefixed_name('resize_original'));
|
180 |
+
if (!$this->get_resize_enabled()) {
|
181 |
+
return false;
|
182 |
+
}
|
183 |
+
|
184 |
+
$width = intval($setting['width']);
|
185 |
+
$height = intval($setting['height']);
|
186 |
+
$method = $width > 0 && $height > 0 ? 'fit' : 'scale';
|
187 |
+
|
188 |
+
$options['method'] = $method;
|
189 |
+
if ($width > 0) {
|
190 |
+
$options['width'] = $width;
|
191 |
+
}
|
192 |
+
if ($height > 0) {
|
193 |
+
$options['height'] = $height;
|
194 |
+
}
|
195 |
+
|
196 |
+
return sizeof($options) >= 2 ? $options : false;
|
197 |
+
}
|
198 |
+
|
199 |
public function render_section() {
|
200 |
echo '<span id="' . self::NAME . '"></span>';
|
201 |
}
|
228 |
}
|
229 |
|
230 |
echo '<div id="tiny-image-sizes-notice">';
|
231 |
+
$this->render_image_sizes_notice(count(self::get_active_tinify_sizes()), self::get_resize_enabled());
|
232 |
echo '</div>';
|
233 |
}
|
234 |
|
245 |
<?php
|
246 |
}
|
247 |
|
248 |
+
public function render_image_sizes_notice($active_image_sizes_count, $resize_original_enabled) {
|
249 |
+
echo '<br>';
|
250 |
+
echo '<p>' . self::translate_escape('Each selected size counts as a compression') . '. ';
|
251 |
+
|
252 |
+
if ($resize_original_enabled) {
|
253 |
+
$active_image_sizes_count++;
|
254 |
}
|
255 |
+
if ($active_image_sizes_count < 1) {
|
256 |
+
echo self::translate_escape('With these settings no images will be compressed') . '.';
|
257 |
+
} else {
|
258 |
$free_images_per_month = floor(self::MONTHLY_FREE_COMPRESSIONS / $active_image_sizes_count);
|
|
|
|
|
259 |
echo self::translate_escape('With these settings you can compress');
|
260 |
echo ' <strong>';
|
261 |
+
printf(self::translate_escape('at least %s images'), $free_images_per_month);
|
262 |
echo '</strong> ';
|
263 |
echo self::translate_escape('for free each month') . '.';
|
|
|
264 |
}
|
265 |
+
echo '</p>';
|
266 |
+
}
|
267 |
+
|
268 |
+
public function render_resize() {
|
269 |
+
echo '<p class="tiny-resize-unavailable" style="display: none">' . self::translate_escape("Enable the compression of the original image size to configure resizing") . '.</p>';
|
270 |
+
|
271 |
+
$id = self::get_prefixed_name("resize_original_enabled");
|
272 |
+
$field = self::get_prefixed_name("resize_original[enabled]");
|
273 |
+
$label = self::translate_escape('Resize and compress orginal images to fit within');
|
274 |
+
|
275 |
+
echo '<p class="tiny-resize-available">';
|
276 |
+
?>
|
277 |
+
<input type="checkbox" id="<?php echo $id ?>" name="<?php echo $field ?>" value="on" <?php if ($this->get_resize_enabled()) { echo ' checked="checked"'; } ?>/>
|
278 |
+
<label for="<?php echo $id; ?>"><?php echo $label; ?>:</label><br>
|
279 |
+
<?php
|
280 |
+
|
281 |
+
echo '</p>';
|
282 |
+
echo '<p class="tiny-resize-available tiny-resize-resolution">';
|
283 |
+
|
284 |
+
printf("%s: ", self::translate_escape('Max Width'));
|
285 |
+
$this->render_resize_input('width');
|
286 |
+
printf("%s: ", self::translate_escape('Max Height'));
|
287 |
+
$this->render_resize_input('height');
|
288 |
+
echo '</p>';
|
289 |
+
|
290 |
+
echo '<p class="tiny-resize-available">' . sprintf(self::translate_escape("Resizing takes %s per image larger than the specified resolution"), '<strong>' . self::translate_escape('1 additional compression') . '</strong>') . '.</p>';
|
291 |
+
}
|
292 |
+
|
293 |
+
public function render_resize_input($name) {
|
294 |
+
$id = sprintf(self::get_prefixed_name('resize_original_%s'), $name);
|
295 |
+
$field = sprintf(self::get_prefixed_name('resize_original[%s]'), $name);
|
296 |
+
$settings = get_option(self::get_prefixed_name('resize_original'));
|
297 |
+
$value = isset($settings[$name]) ? $settings[$name] : "2048";
|
298 |
+
echo '<input type="number" id="'. $id .'" name="' . $field . '" value="' . $value . '" size="5" />';
|
299 |
}
|
300 |
|
301 |
public function get_compression_count() {
|
src/class-tiny-wp-base.php
CHANGED
@@ -42,6 +42,10 @@ abstract class Tiny_WP_Base {
|
|
42 |
return floatval(self::wp_version()) >= $version;
|
43 |
}
|
44 |
|
|
|
|
|
|
|
|
|
45 |
public static function plugin_version() {
|
46 |
if (is_null(self::$plugin_version)) {
|
47 |
$plugin_data = get_plugin_data(dirname(__FILE__) . '/../tiny-compress-images.php');
|
@@ -68,7 +72,9 @@ abstract class Tiny_WP_Base {
|
|
68 |
|
69 |
public function __construct() {
|
70 |
add_action('init', $this->get_method('init'));
|
71 |
-
if (
|
|
|
|
|
72 |
add_action('admin_init', $this->get_method('admin_init'));
|
73 |
}
|
74 |
}
|
@@ -92,6 +98,9 @@ abstract class Tiny_WP_Base {
|
|
92 |
public function init() {
|
93 |
}
|
94 |
|
|
|
|
|
|
|
95 |
public function admin_init() {
|
96 |
}
|
97 |
}
|
42 |
return floatval(self::wp_version()) >= $version;
|
43 |
}
|
44 |
|
45 |
+
protected function is_xmlrpc_request() {
|
46 |
+
return defined('XMLRPC_REQUEST') && XMLRPC_REQUEST;
|
47 |
+
}
|
48 |
+
|
49 |
public static function plugin_version() {
|
50 |
if (is_null(self::$plugin_version)) {
|
51 |
$plugin_data = get_plugin_data(dirname(__FILE__) . '/../tiny-compress-images.php');
|
72 |
|
73 |
public function __construct() {
|
74 |
add_action('init', $this->get_method('init'));
|
75 |
+
if (self::is_xmlrpc_request()) {
|
76 |
+
add_action('init', $this->get_method('xmlrpc_init'));
|
77 |
+
} elseif (is_admin()) {
|
78 |
add_action('admin_init', $this->get_method('admin_init'));
|
79 |
}
|
80 |
}
|
98 |
public function init() {
|
99 |
}
|
100 |
|
101 |
+
public function xmlrpc_init() {
|
102 |
+
}
|
103 |
+
|
104 |
public function admin_init() {
|
105 |
}
|
106 |
}
|
src/languages/tiny-compress-images-nl_NL.mo
CHANGED
Binary file
|
src/languages/tiny-compress-images-nl_NL.po
CHANGED
@@ -133,11 +133,14 @@ msgstr "Als je meer afbeeldingen wilt comprimeren kun je je %s aanpassen"
|
|
133 |
msgid "Upgrade your %s if you like to compress more images"
|
134 |
msgstr "Upgrade je %s als je meer afbeeldingen wilt comprimeren"
|
135 |
|
|
|
|
|
|
|
136 |
msgid "With these settings you can compress"
|
137 |
msgstr "Met deze instellingen kun je elke maand"
|
138 |
|
139 |
-
msgid "%s images"
|
140 |
-
msgstr "%s afbeeldingen"
|
141 |
|
142 |
msgid "for free each month"
|
143 |
msgstr "gratis comprimeren"
|
@@ -184,8 +187,11 @@ msgstr "Deze tool comprimeert alle afbeeldingen in je media-bibliotheek"
|
|
184 |
msgid "Only images that have not been compressed will be compressed"
|
185 |
msgstr "Dit geldt alleen voor de afbeeldingen die nog niet zijn gecomprimeerd"
|
186 |
|
187 |
-
msgid "We have found %d images in your media library"
|
188 |
-
msgstr "We hebben %d afbeeldingen in de media-bibliotheek gevonden"
|
|
|
|
|
|
|
189 |
|
190 |
msgid "To begin, just press the button below"
|
191 |
msgstr "Druk op de knop om te starten"
|
@@ -204,3 +210,27 @@ msgstr "Je wordt genotificeerd op deze pagina bij voltooing"
|
|
204 |
|
205 |
msgid "Settings"
|
206 |
msgstr "Instellingen"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
msgid "Upgrade your %s if you like to compress more images"
|
134 |
msgstr "Upgrade je %s als je meer afbeeldingen wilt comprimeren"
|
135 |
|
136 |
+
msgid "Each selected size counts as a compression"
|
137 |
+
msgstr "Elke geselecteerde afmeting telt als een compressie"
|
138 |
+
|
139 |
msgid "With these settings you can compress"
|
140 |
msgstr "Met deze instellingen kun je elke maand"
|
141 |
|
142 |
+
msgid "at least %s images"
|
143 |
+
msgstr "minimaal %s afbeeldingen"
|
144 |
|
145 |
msgid "for free each month"
|
146 |
msgstr "gratis comprimeren"
|
187 |
msgid "Only images that have not been compressed will be compressed"
|
188 |
msgstr "Dit geldt alleen voor de afbeeldingen die nog niet zijn gecomprimeerd"
|
189 |
|
190 |
+
msgid "We have found %d images in your media library and for each image %d sizes will be compressed"
|
191 |
+
msgstr "We hebben %d afbeeldingen in de media-bibliotheek gevonden en voor elke afbeelding worden %d afmetingen gecomprimeerd"
|
192 |
+
|
193 |
+
msgid "This results in %d compressions at most"
|
194 |
+
msgstr "Dit resulteert in een maximaal verbruik van %d compressies"
|
195 |
|
196 |
msgid "To begin, just press the button below"
|
197 |
msgstr "Druk op de knop om te starten"
|
210 |
|
211 |
msgid "Settings"
|
212 |
msgstr "Instellingen"
|
213 |
+
|
214 |
+
msgid "Resize original"
|
215 |
+
msgstr "Orgineel verkleinen"
|
216 |
+
|
217 |
+
msgid "Enable the compression of the original image size to configure resizing"
|
218 |
+
msgstr "Schakel de compressie van het originele formaat in om het origineel te verkleinen"
|
219 |
+
|
220 |
+
msgid "Resize and compress orginal images to fit within"
|
221 |
+
msgstr "Verklein en comprimeer het origineel in"
|
222 |
+
|
223 |
+
msgid "Resizing takes %s per image larger than the specified resolution"
|
224 |
+
msgstr "Verkleinen gebruikt %s per afbeelding die groter is dan de opgegeven resolutie"
|
225 |
+
|
226 |
+
msgid "1 additional compression"
|
227 |
+
msgstr "1 extra compressie"
|
228 |
+
|
229 |
+
msgid "Resized original to %dx%d"
|
230 |
+
msgstr "Origineel verkleind tot %dx%d"
|
231 |
+
|
232 |
+
msgid "Max Width"
|
233 |
+
msgstr "Maximale breedte"
|
234 |
+
|
235 |
+
msgid "Max Height"
|
236 |
+
msgstr "Maximale hoogte"
|
src/scripts/admin.js
CHANGED
@@ -156,11 +156,32 @@
|
|
156 |
if (adminpage === "options-media-php") {
|
157 |
jQuery('#tiny-compress-status').load(ajaxurl + '?action=tiny_compress_status')
|
158 |
|
159 |
-
jQuery('input[name*="tinypng_sizes"]').on("click", function() {
|
160 |
// Unfortunately, we need some additional information to display the correct notice.
|
161 |
totalSelectedSizes = jQuery('input[name*="tinypng_sizes"]:checked').length
|
162 |
-
|
|
|
|
|
|
|
|
|
163 |
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
}
|
165 |
|
166 |
jQuery('.tiny-notice a.tiny-dismiss').click(dismiss_notice)
|
@@ -169,4 +190,4 @@
|
|
169 |
})
|
170 |
|
171 |
window.tinyBulkCompress = bulk_compress
|
172 |
-
}).call()
|
156 |
if (adminpage === "options-media-php") {
|
157 |
jQuery('#tiny-compress-status').load(ajaxurl + '?action=tiny_compress_status')
|
158 |
|
159 |
+
jQuery('input[name*="tinypng_sizes"], input#tinypng_resize_original_enabled').on("click", function() {
|
160 |
// Unfortunately, we need some additional information to display the correct notice.
|
161 |
totalSelectedSizes = jQuery('input[name*="tinypng_sizes"]:checked').length
|
162 |
+
var image_count_url = ajaxurl + '?action=tiny_image_sizes_notice&image_sizes_selected=' + totalSelectedSizes
|
163 |
+
if (jQuery('input#tinypng_resize_original_enabled').prop('checked') && jQuery('input#tinypng_sizes_0').prop('checked')) {
|
164 |
+
image_count_url += '&resize_original=true'
|
165 |
+
}
|
166 |
+
jQuery('#tiny-image-sizes-notice').load(image_count_url)
|
167 |
})
|
168 |
+
|
169 |
+
function update_resize_settings() {
|
170 |
+
if (jQuery('#tinypng_sizes_0').prop('checked')) {
|
171 |
+
jQuery('.tiny-resize-available').show()
|
172 |
+
jQuery('.tiny-resize-unavailable').hide()
|
173 |
+
} else {
|
174 |
+
jQuery('.tiny-resize-available').hide()
|
175 |
+
jQuery('.tiny-resize-unavailable').show()
|
176 |
+
}
|
177 |
+
|
178 |
+
var elements = jQuery('#tinypng_resize_original_width, #tinypng_resize_original_height')
|
179 |
+
for (var i = 0; i < elements.length; i++) {
|
180 |
+
elements[i].disabled = !jQuery('#tinypng_resize_original_enabled').prop('checked')
|
181 |
+
}
|
182 |
+
}
|
183 |
+
update_resize_settings()
|
184 |
+
jQuery('#tinypng_sizes_0, #tinypng_resize_original_enabled').click(update_resize_settings)
|
185 |
}
|
186 |
|
187 |
jQuery('.tiny-notice a.tiny-dismiss').click(dismiss_notice)
|
190 |
})
|
191 |
|
192 |
window.tinyBulkCompress = bulk_compress
|
193 |
+
}).call()
|
src/styles/admin.css
CHANGED
@@ -51,3 +51,15 @@
|
|
51 |
box-shadow: 0px 1px 0px #DFDFDF;
|
52 |
padding: 5px;
|
53 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
box-shadow: 0px 1px 0px #DFDFDF;
|
52 |
padding: 5px;
|
53 |
}
|
54 |
+
|
55 |
+
p.tiny-resize-resolution {
|
56 |
+
margin-left: 24px;
|
57 |
+
}
|
58 |
+
|
59 |
+
p.tiny-resize-resolution input {
|
60 |
+
margin-right: 6px;
|
61 |
+
}
|
62 |
+
|
63 |
+
input[type=number][name*="tinypng_resize_original"] {
|
64 |
+
width: 65px;
|
65 |
+
}
|
test/fixtures/input-large.jpg
ADDED
Binary file
|
test/helpers/wordpress.php
CHANGED
@@ -176,7 +176,12 @@ class WordPressStubs {
|
|
176 |
}
|
177 |
|
178 |
public function getTestMetadata($path='14/01', $name='test') {
|
179 |
-
$metadata = array(
|
|
|
|
|
|
|
|
|
|
|
180 |
|
181 |
$regex = '#^' . preg_quote($name) .'-([^.]+)[.](png|jpe?g)$#';
|
182 |
$dir = $this->vfs->getChild(self::UPLOAD_DIR . "/$path");
|
176 |
}
|
177 |
|
178 |
public function getTestMetadata($path='14/01', $name='test') {
|
179 |
+
$metadata = array(
|
180 |
+
'file' => "$path/$name.png",
|
181 |
+
'width' => 4000,
|
182 |
+
'height' => 3000,
|
183 |
+
'sizes' => array()
|
184 |
+
);
|
185 |
|
186 |
$regex = '#^' . preg_quote($name) .'-([^.]+)[.](png|jpe?g)$#';
|
187 |
$dir = $this->vfs->getChild(self::UPLOAD_DIR . "/$path");
|
test/integration/CompressIntegrationTest.php
CHANGED
@@ -80,4 +80,51 @@ class CompressIntegrationTest extends IntegrationTestCase {
|
|
80 |
self::$driver->wait(2)->until(WebDriverExpectedCondition::textToBePresentInElement(
|
81 |
WebDriverBy::cssSelector('td.tiny-compress-images'), 'JSON: Syntax error [4]'));
|
82 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
}
|
80 |
self::$driver->wait(2)->until(WebDriverExpectedCondition::textToBePresentInElement(
|
81 |
WebDriverBy::cssSelector('td.tiny-compress-images'), 'JSON: Syntax error [4]'));
|
82 |
}
|
83 |
+
|
84 |
+
public function testResizeFit() {
|
85 |
+
$this->set_api_key('JPG123');
|
86 |
+
$this->enable_resize(300, 200);
|
87 |
+
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-large.jpg');
|
88 |
+
$this->assertContains('Resized original to 300x200',
|
89 |
+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
|
90 |
+
$this->view_edit_image();
|
91 |
+
$this->assertContains('Dimensions: 300 × 200',
|
92 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.misc-pub-dimensions'))->getText());
|
93 |
+
}
|
94 |
+
|
95 |
+
public function testResizeScale() {
|
96 |
+
$this->set_api_key('JPG123');
|
97 |
+
$this->enable_resize(0, 200);
|
98 |
+
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-large.jpg');
|
99 |
+
$this->assertContains('Resized original to 300x200',
|
100 |
+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
|
101 |
+
$this->view_edit_image();
|
102 |
+
$this->assertContains('Dimensions: 300 × 200',
|
103 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.misc-pub-dimensions'))->getText());
|
104 |
+
}
|
105 |
+
|
106 |
+
public function testResizeNotNeeded()
|
107 |
+
{
|
108 |
+
$this->set_api_key('JPG123');
|
109 |
+
$this->enable_resize(30000, 20000);
|
110 |
+
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-large.jpg');
|
111 |
+
$this->assertNotContains('Resized original',
|
112 |
+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
|
113 |
+
$this->view_edit_image();
|
114 |
+
$this->assertContains('Dimensions: 1080 × 330',
|
115 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.misc-pub-dimensions'))->getText());
|
116 |
+
}
|
117 |
+
|
118 |
+
public function testResizeDisabled()
|
119 |
+
{
|
120 |
+
$this->set_api_key('JPG123');
|
121 |
+
$this->enable_resize(300, 200);
|
122 |
+
$this->disable_resize();
|
123 |
+
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-large.jpg');
|
124 |
+
$this->assertNotContains('Resized original',
|
125 |
+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
|
126 |
+
$this->view_edit_image();
|
127 |
+
$this->assertContains('Dimensions: 1080 × 330',
|
128 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.misc-pub-dimensions'))->getText());
|
129 |
+
}
|
130 |
}
|
test/integration/IntegrationTestCase.php
CHANGED
@@ -62,4 +62,43 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase {
|
|
62 |
}
|
63 |
self::$driver->findElement(WebDriverBy::tagName('form'))->submit();
|
64 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
62 |
}
|
63 |
self::$driver->findElement(WebDriverBy::tagName('form'))->submit();
|
64 |
}
|
65 |
+
|
66 |
+
protected function enable_resize($width, $height) {
|
67 |
+
$url = wordpress('/wp-admin/options-media.php');
|
68 |
+
if (self::$driver->getCurrentUrl() != $url) {
|
69 |
+
self::$driver->get($url);
|
70 |
+
}
|
71 |
+
$element = self::$driver->findElement(WebDriverBy::id('tinypng_resize_original_enabled'));
|
72 |
+
if (!$element->getAttribute('checked')) {
|
73 |
+
$element->click();
|
74 |
+
}
|
75 |
+
self::$driver->findElement(WebDriverBy::id('tinypng_resize_original_width'))->clear()->sendKeys($width);
|
76 |
+
self::$driver->findElement(WebDriverBy::id('tinypng_resize_original_height'))->clear()->sendKeys($height);
|
77 |
+
self::$driver->findElement(WebDriverBy::tagName('form'))->submit();
|
78 |
+
}
|
79 |
+
|
80 |
+
protected function disable_resize() {
|
81 |
+
$url = wordpress('/wp-admin/options-media.php');
|
82 |
+
if (self::$driver->getCurrentUrl() != $url) {
|
83 |
+
self::$driver->get($url);
|
84 |
+
}
|
85 |
+
$element = self::$driver->findElement(WebDriverBy::id('tinypng_resize_original_enabled'));
|
86 |
+
if ($element->getAttribute('checked')) {
|
87 |
+
$element->click();
|
88 |
+
}
|
89 |
+
self::$driver->findElement(WebDriverBy::tagName('form'))->submit();
|
90 |
+
}
|
91 |
+
|
92 |
+
protected function view_edit_image($image_title = 'input-large') {
|
93 |
+
$url = wordpress('/wp-admin/upload.php');
|
94 |
+
if (self::$driver->getCurrentUrl() != $url) {
|
95 |
+
self::$driver->get($url);
|
96 |
+
}
|
97 |
+
if (wordpress_version() >= 43) {
|
98 |
+
$selector = "//span[text()='" . $image_title . "']";
|
99 |
+
} else {
|
100 |
+
$selector = "//a[contains(text(),'" . $image_title . "')]";
|
101 |
+
}
|
102 |
+
self::$driver->findElement(WebDriverBy::xpath($selector))->click();
|
103 |
+
}
|
104 |
}
|
test/integration/SettingsIntegrationTest.php
CHANGED
@@ -89,7 +89,7 @@ class SettingsIntegrationTest extends IntegrationTestCase {
|
|
89 |
public function testShouldShowTotalImagesInfo() {
|
90 |
$elements = self::$driver->findElement(WebDriverBy::id('tiny-image-sizes-notice'))->findElements(WebDriverBy::tagName('p'));
|
91 |
$statuses = array_map('innerText', $elements);
|
92 |
-
$this->assertContains('With these settings you can compress 100 images for free each month.', $statuses);
|
93 |
}
|
94 |
|
95 |
public function testShouldUpdateTotalImagesInfo() {
|
@@ -97,11 +97,11 @@ class SettingsIntegrationTest extends IntegrationTestCase {
|
|
97 |
WebDriverBy::xpath('//input[@type="checkbox" and @name="tinypng_sizes[0]" and @checked="checked"]'));
|
98 |
$element->click();
|
99 |
self::$driver->wait(2)->until(WebDriverExpectedCondition::textToBePresentInElement(
|
100 |
-
WebDriverBy::cssSelector('#tiny-image-sizes-notice'), 'With these settings you can compress 125 images for free each month.'));
|
101 |
// Not really necessary anymore to assert this.
|
102 |
$elements = self::$driver->findElement(WebDriverBy::id('tiny-image-sizes-notice'))->findElements(WebDriverBy::tagName('p'));
|
103 |
$statuses = array_map('innerText', $elements);
|
104 |
-
$this->assertContains('With these settings you can compress 125 images for free each month.', $statuses);
|
105 |
}
|
106 |
|
107 |
public function testShouldShowCorrectNoImageSizesInfo() {
|
@@ -111,11 +111,43 @@ class SettingsIntegrationTest extends IntegrationTestCase {
|
|
111 |
$element->click();
|
112 |
}
|
113 |
self::$driver->wait(2)->until(WebDriverExpectedCondition::textToBePresentInElement(
|
114 |
-
WebDriverBy::cssSelector('#tiny-image-sizes-notice'), 'With these settings no images will be compressed.'));
|
115 |
// Not really necessary anymore to assert this.
|
116 |
$elements = self::$driver->findElement(WebDriverBy::id('tiny-image-sizes-notice'))->findElements(WebDriverBy::tagName('p'));
|
117 |
$statuses = array_map('innerText', $elements);
|
118 |
-
$this->assertContains('With these settings no images will be compressed.', $statuses);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
}
|
120 |
|
121 |
public function testStatusPresenceOK() {
|
89 |
public function testShouldShowTotalImagesInfo() {
|
90 |
$elements = self::$driver->findElement(WebDriverBy::id('tiny-image-sizes-notice'))->findElements(WebDriverBy::tagName('p'));
|
91 |
$statuses = array_map('innerText', $elements);
|
92 |
+
$this->assertContains('Each selected size counts as a compression. With these settings you can compress at least 100 images for free each month.', $statuses);
|
93 |
}
|
94 |
|
95 |
public function testShouldUpdateTotalImagesInfo() {
|
97 |
WebDriverBy::xpath('//input[@type="checkbox" and @name="tinypng_sizes[0]" and @checked="checked"]'));
|
98 |
$element->click();
|
99 |
self::$driver->wait(2)->until(WebDriverExpectedCondition::textToBePresentInElement(
|
100 |
+
WebDriverBy::cssSelector('#tiny-image-sizes-notice'), 'Each selected size counts as a compression. With these settings you can compress at least 125 images for free each month.'));
|
101 |
// Not really necessary anymore to assert this.
|
102 |
$elements = self::$driver->findElement(WebDriverBy::id('tiny-image-sizes-notice'))->findElements(WebDriverBy::tagName('p'));
|
103 |
$statuses = array_map('innerText', $elements);
|
104 |
+
$this->assertContains('Each selected size counts as a compression. With these settings you can compress at least 125 images for free each month.', $statuses);
|
105 |
}
|
106 |
|
107 |
public function testShouldShowCorrectNoImageSizesInfo() {
|
111 |
$element->click();
|
112 |
}
|
113 |
self::$driver->wait(2)->until(WebDriverExpectedCondition::textToBePresentInElement(
|
114 |
+
WebDriverBy::cssSelector('#tiny-image-sizes-notice'), 'Each selected size counts as a compression. With these settings no images will be compressed.'));
|
115 |
// Not really necessary anymore to assert this.
|
116 |
$elements = self::$driver->findElement(WebDriverBy::id('tiny-image-sizes-notice'))->findElements(WebDriverBy::tagName('p'));
|
117 |
$statuses = array_map('innerText', $elements);
|
118 |
+
$this->assertContains('Each selected size counts as a compression. With these settings no images will be compressed.', $statuses);
|
119 |
+
}
|
120 |
+
|
121 |
+
public function testShouldShowResizingWhenOriginalEnabled() {
|
122 |
+
$element = self::$driver->findElement(WebDriverBy::id('tinypng_sizes_0'));
|
123 |
+
if (!$element->getAttribute('checked')) {
|
124 |
+
$element->click();
|
125 |
+
}
|
126 |
+
$labels = self::$driver->findElements(WebDriverBy::tagName('label'));
|
127 |
+
$texts = array_map('innerText', $labels);
|
128 |
+
$this->assertContains('Resize and compress orginal images to fit within:', $texts);
|
129 |
+
$paragraphs = self::$driver->findElements(WebDriverBy::tagName('p'));
|
130 |
+
$texts = array_map('innerText', $paragraphs);
|
131 |
+
$this->assertNotContains('Enable the compression of the original image size to configure resizing.', $texts);
|
132 |
+
}
|
133 |
+
|
134 |
+
public function testShouldNotShowResizingWhenOriginalDisabled() {
|
135 |
+
$element = self::$driver->findElement(WebDriverBy::id('tinypng_sizes_0'));
|
136 |
+
if ($element->getAttribute('checked')) {
|
137 |
+
$element->click();
|
138 |
+
}
|
139 |
+
$labels = self::$driver->findElements(WebDriverBy::tagName('label'));
|
140 |
+
$texts = array_map('innerText', $labels);
|
141 |
+
$this->assertNotContains('Resize and compress orginal images to fit within:', $texts);
|
142 |
+
$paragraphs = self::$driver->findElements(WebDriverBy::tagName('p'));
|
143 |
+
$texts = array_map('innerText', $paragraphs);
|
144 |
+
$this->assertContains('Enable the compression of the original image size to configure resizing.', $texts);
|
145 |
+
}
|
146 |
+
|
147 |
+
public function testShouldPersistResizingSettings() {
|
148 |
+
$this->enable_resize(123, 456);
|
149 |
+
$this->assertEquals('123', self::$driver->findElement(WebDriverBy::id('tinypng_resize_original_width'))->getAttribute('value'));
|
150 |
+
$this->assertEquals('456', self::$driver->findElement(WebDriverBy::id('tinypng_resize_original_height'))->getAttribute('value'));
|
151 |
}
|
152 |
|
153 |
public function testStatusPresenceOK() {
|
test/mock-tinypng-webservice/common.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
define('SESSION_FILE', '/tmp/session.dat');
|
4 |
+
|
5 |
+
if (file_exists(SESSION_FILE)) {
|
6 |
+
$session = unserialize(file_get_contents(SESSION_FILE));
|
7 |
+
} else {
|
8 |
+
$session = array('Compression-Count' => 0);
|
9 |
+
}
|
10 |
+
|
11 |
+
function save_session() {
|
12 |
+
global $session;
|
13 |
+
if ($session) {
|
14 |
+
file_put_contents(SESSION_FILE, serialize($session));
|
15 |
+
} elseif (file_exists(SESSION_FILE)) {
|
16 |
+
unlink(SESSION_FILE);
|
17 |
+
}
|
18 |
+
}
|
19 |
+
register_shutdown_function('save_session');
|
20 |
+
|
21 |
+
function get_api_key() {
|
22 |
+
$request_headers = apache_request_headers();
|
23 |
+
if (!isset($request_headers['Authorization'])) {
|
24 |
+
return null;
|
25 |
+
}
|
26 |
+
$basic_auth = base64_decode(str_replace('Basic ', '', $request_headers['Authorization']));
|
27 |
+
return next(explode(':', $basic_auth));
|
28 |
+
}
|
29 |
+
|
30 |
+
function get_json_body() {
|
31 |
+
return json_decode(file_get_contents("php://input"));
|
32 |
+
}
|
33 |
+
|
34 |
+
function mock_invalid_response() {
|
35 |
+
global $session;
|
36 |
+
|
37 |
+
header('HTTP/1.1 401 Unauthorized');
|
38 |
+
header("Content-Type: application/json; charset=utf-8");
|
39 |
+
|
40 |
+
$response = array(
|
41 |
+
"error" => "Unauthorized",
|
42 |
+
"message" => "Credentials are invalid"
|
43 |
+
);
|
44 |
+
return json_encode($response);
|
45 |
+
}
|
test/mock-tinypng-webservice/output-resized.jpg
ADDED
Binary file
|
test/mock-tinypng-webservice/output.php
CHANGED
@@ -1,13 +1,33 @@
|
|
1 |
<?php
|
2 |
ob_start();
|
3 |
|
|
|
|
|
4 |
if (preg_match('#output/.+[.](png|jpg)$#', $_SERVER['REQUEST_URI'], $match)) {
|
5 |
$file = str_replace('/', '-', $match[0]);
|
|
|
6 |
$mime = $match[1] == 'jpg' ? 'image/jpeg' : "image/$ext";
|
7 |
} else {
|
8 |
$file = null;
|
9 |
}
|
10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
if ($file && file_exists($file)) {
|
12 |
header("Content-Type: $mime");
|
13 |
header('Content-Disposition: attachment');
|
@@ -16,4 +36,4 @@ if ($file && file_exists($file)) {
|
|
16 |
header("HTTP/1.1 404 Not Found");
|
17 |
}
|
18 |
|
19 |
-
ob_end_flush();
|
1 |
<?php
|
2 |
ob_start();
|
3 |
|
4 |
+
require_once('common.php');
|
5 |
+
|
6 |
if (preg_match('#output/.+[.](png|jpg)$#', $_SERVER['REQUEST_URI'], $match)) {
|
7 |
$file = str_replace('/', '-', $match[0]);
|
8 |
+
$ext = $match[1];
|
9 |
$mime = $match[1] == 'jpg' ? 'image/jpeg' : "image/$ext";
|
10 |
} else {
|
11 |
$file = null;
|
12 |
}
|
13 |
|
14 |
+
$api_key = get_api_key();
|
15 |
+
if (!is_null($api_key)) {
|
16 |
+
$data = get_json_body();
|
17 |
+
if (is_null($data) || $api_key != 'JPG123') {
|
18 |
+
mock_invalid_response();
|
19 |
+
ob_end_flush();
|
20 |
+
exit();
|
21 |
+
}
|
22 |
+
|
23 |
+
$resize = $data->resize;
|
24 |
+
if ($resize->method) {
|
25 |
+
$file = "output-resized.$ext";
|
26 |
+
header("Image-Width: {$resize->width}");
|
27 |
+
header("Image-Height: {$resize->height}");
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
if ($file && file_exists($file)) {
|
32 |
header("Content-Type: $mime");
|
33 |
header('Content-Disposition: attachment');
|
36 |
header("HTTP/1.1 404 Not Found");
|
37 |
}
|
38 |
|
39 |
+
ob_end_flush();
|
test/mock-tinypng-webservice/reset.php
CHANGED
@@ -1,7 +1,4 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
if (file_exists(SESSION_FILE)) {
|
6 |
-
unlink(SESSION_FILE);
|
7 |
-
}
|
1 |
<?php
|
2 |
|
3 |
+
require('common.php');
|
4 |
+
$session = null;
|
|
|
|
|
|
test/mock-tinypng-webservice/shrink.php
CHANGED
@@ -1,13 +1,7 @@
|
|
1 |
<?php
|
2 |
ob_start();
|
3 |
|
4 |
-
|
5 |
-
|
6 |
-
if (file_exists(SESSION_FILE)) {
|
7 |
-
$session = unserialize(file_get_contents(SESSION_FILE));
|
8 |
-
} else {
|
9 |
-
$session = array('Compression-Count' => 0);
|
10 |
-
}
|
11 |
|
12 |
function mock_png_response() {
|
13 |
global $session;
|
@@ -15,10 +9,11 @@ function mock_png_response() {
|
|
15 |
$session['Compression-Count'] += 1;
|
16 |
header('HTTP/1.1 201 Created');
|
17 |
header("Location: http://webservice/output/example.png");
|
|
|
18 |
header("Compression-Count: {$session['Compression-Count']}");
|
19 |
$response = array(
|
20 |
"input" => array("size" => 161885, "type" => "image/png"),
|
21 |
-
"output" => array("size" => 151021, "type" => "image
|
22 |
);
|
23 |
return json_encode($response);
|
24 |
}
|
@@ -29,6 +24,7 @@ function mock_jpg_response() {
|
|
29 |
$session['Compression-Count'] += 1;
|
30 |
header('HTTP/1.1 201 Created');
|
31 |
header("Location: http://webservice/output/example.jpg");
|
|
|
32 |
header("Compression-Count: {$session['Compression-Count']}");
|
33 |
|
34 |
$response = array(
|
@@ -44,6 +40,7 @@ function mock_large_response() {
|
|
44 |
$session['Compression-Count'] += 1;
|
45 |
header('HTTP/1.1 201 Created');
|
46 |
header("Location: http://webservice/output/large.png");
|
|
|
47 |
header("Compression-Count: {$session['Compression-Count']}");
|
48 |
|
49 |
$response = array(
|
@@ -53,19 +50,6 @@ function mock_large_response() {
|
|
53 |
return json_encode($response);
|
54 |
}
|
55 |
|
56 |
-
function mock_invalid_response() {
|
57 |
-
global $session;
|
58 |
-
|
59 |
-
header('HTTP/1.1 401 Unauthorized');
|
60 |
-
header("Content-Type: application/json; charset=utf-8");
|
61 |
-
|
62 |
-
$response = array(
|
63 |
-
"error" => "Unauthorized",
|
64 |
-
"message" => "Credentials are invalid"
|
65 |
-
);
|
66 |
-
return json_encode($response);
|
67 |
-
}
|
68 |
-
|
69 |
function mock_empty_response() {
|
70 |
global $session;
|
71 |
|
@@ -100,17 +84,12 @@ function mock_invalid_json_response() {
|
|
100 |
$session['Compression-Count'] += 1;
|
101 |
header('HTTP/1.1 201 Created');
|
102 |
header("Location: http://webservice/output/example.png");
|
|
|
103 |
header("Compression-Count: {$session['Compression-Count']}");
|
104 |
return '{invalid: json}';
|
105 |
}
|
106 |
|
107 |
-
$
|
108 |
-
$basic_auth = base64_decode(str_replace('Basic ', '', $request_headers['Authorization']));
|
109 |
-
$api_key_elements = explode(':', $basic_auth);
|
110 |
-
$api_key = $api_key_elements[1];
|
111 |
-
|
112 |
-
header("Content-Type: application/json; charset=utf-8");
|
113 |
-
|
114 |
if ($api_key == 'PNG123') {
|
115 |
if (intval($_SERVER['CONTENT_LENGTH']) == 0) {
|
116 |
echo mock_empty_response();
|
@@ -127,7 +106,7 @@ if ($api_key == 'PNG123') {
|
|
127 |
if (intval($_SERVER['CONTENT_LENGTH']) == 0) {
|
128 |
echo mock_empty_response();
|
129 |
} else {
|
130 |
-
echo
|
131 |
}
|
132 |
} else if ($api_key == 'LIMIT123') {
|
133 |
echo mock_limit_reached_response();
|
@@ -135,6 +114,4 @@ if ($api_key == 'PNG123') {
|
|
135 |
echo mock_invalid_response();
|
136 |
}
|
137 |
|
138 |
-
|
139 |
-
|
140 |
-
ob_end_flush();
|
1 |
<?php
|
2 |
ob_start();
|
3 |
|
4 |
+
require_once('common.php');
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
function mock_png_response() {
|
7 |
global $session;
|
9 |
$session['Compression-Count'] += 1;
|
10 |
header('HTTP/1.1 201 Created');
|
11 |
header("Location: http://webservice/output/example.png");
|
12 |
+
header("Content-Type: application/json; charset=utf-8");
|
13 |
header("Compression-Count: {$session['Compression-Count']}");
|
14 |
$response = array(
|
15 |
"input" => array("size" => 161885, "type" => "image/png"),
|
16 |
+
"output" => array("size" => 151021, "type" => "image/png", "ratio" => 0.933)
|
17 |
);
|
18 |
return json_encode($response);
|
19 |
}
|
24 |
$session['Compression-Count'] += 1;
|
25 |
header('HTTP/1.1 201 Created');
|
26 |
header("Location: http://webservice/output/example.jpg");
|
27 |
+
header("Content-Type: application/json; charset=utf-8");
|
28 |
header("Compression-Count: {$session['Compression-Count']}");
|
29 |
|
30 |
$response = array(
|
40 |
$session['Compression-Count'] += 1;
|
41 |
header('HTTP/1.1 201 Created');
|
42 |
header("Location: http://webservice/output/large.png");
|
43 |
+
header("Content-Type: application/json; charset=utf-8");
|
44 |
header("Compression-Count: {$session['Compression-Count']}");
|
45 |
|
46 |
$response = array(
|
50 |
return json_encode($response);
|
51 |
}
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
function mock_empty_response() {
|
54 |
global $session;
|
55 |
|
84 |
$session['Compression-Count'] += 1;
|
85 |
header('HTTP/1.1 201 Created');
|
86 |
header("Location: http://webservice/output/example.png");
|
87 |
+
header("Content-Type: application/json; charset=utf-8");
|
88 |
header("Compression-Count: {$session['Compression-Count']}");
|
89 |
return '{invalid: json}';
|
90 |
}
|
91 |
|
92 |
+
$api_key = get_api_key();
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
if ($api_key == 'PNG123') {
|
94 |
if (intval($_SERVER['CONTENT_LENGTH']) == 0) {
|
95 |
echo mock_empty_response();
|
106 |
if (intval($_SERVER['CONTENT_LENGTH']) == 0) {
|
107 |
echo mock_empty_response();
|
108 |
} else {
|
109 |
+
echo mock_invalid_json_response();
|
110 |
}
|
111 |
} else if ($api_key == 'LIMIT123') {
|
112 |
echo mock_limit_reached_response();
|
114 |
echo mock_invalid_response();
|
115 |
}
|
116 |
|
117 |
+
ob_end_flush();
|
|
|
|
test/unit/TinyMetadataTest.php
CHANGED
@@ -38,4 +38,22 @@ class Tiny_Metadata_Test extends TinyTestCase {
|
|
38 |
$uncompressed_sizes = array(Tiny_Metadata::ORIGINAL, "custom-size");
|
39 |
$this->assertEquals($uncompressed_sizes, $this->subject->get_uncompressed_sizes($tinify_sizes));
|
40 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
}
|
38 |
$uncompressed_sizes = array(Tiny_Metadata::ORIGINAL, "custom-size");
|
39 |
$this->assertEquals($uncompressed_sizes, $this->subject->get_uncompressed_sizes($tinify_sizes));
|
40 |
}
|
41 |
+
|
42 |
+
public function testUpdateWpMetadataShouldNotUpdateWithNoResizedOriginal() {
|
43 |
+
$wp_metadata = array(
|
44 |
+
'width' => 2000,
|
45 |
+
'height' => 1000
|
46 |
+
);
|
47 |
+
$this->assertEquals(array('width' => 2000, 'height' => 1000), $this->subject->update_wp_metadata($wp_metadata));
|
48 |
+
}
|
49 |
+
|
50 |
+
public function testUpdateWpMetadataShouldUpdateWithResizedOriginal() {
|
51 |
+
$wp_metadata = array(
|
52 |
+
'width' => 2000,
|
53 |
+
'height' => 1000
|
54 |
+
);
|
55 |
+
$this->subject->add_request();
|
56 |
+
$this->subject->add_response(array('output' => array('width' => 200, 'height' => 100)));
|
57 |
+
$this->assertEquals(array('width' => 200, 'height' => 100), $this->subject->update_wp_metadata($wp_metadata));
|
58 |
+
}
|
59 |
}
|
test/unit/TinyPluginTest.php
CHANGED
@@ -34,19 +34,32 @@ class Tiny_Plugin_Test extends TinyTestCase {
|
|
34 |
$input = filesize($file);
|
35 |
switch ($key) {
|
36 |
case "thumbnail":
|
37 |
-
$output = 81;
|
|
|
|
|
|
|
38 |
case "medium":
|
39 |
-
$output = 768;
|
|
|
|
|
|
|
40 |
case "large":
|
41 |
-
$output = 6789;
|
|
|
|
|
|
|
42 |
case "post-thumbnail":
|
43 |
-
$output = 1000;
|
|
|
|
|
|
|
44 |
default:
|
45 |
$output = 10000;
|
|
|
|
|
46 |
}
|
47 |
$this->vfs->getChild(vfsStream::path($file))->truncate($output);
|
48 |
-
return array('input' => array('size' => $input), 'output' => array('size' => $output));
|
49 |
-
|
50 |
}
|
51 |
|
52 |
public function testInitShouldAddFilters() {
|
@@ -120,9 +133,9 @@ class Tiny_Plugin_Test extends TinyTestCase {
|
|
120 |
unset($metadata[$key]['start']);
|
121 |
}
|
122 |
$this->assertEquals(array(
|
123 |
-
0 => array('input' => array('size' => 12345), 'output' => array('size' => 10000)),
|
124 |
-
'large' => array('input' => array('size' => 10000), 'output' => array('size' => 6789)),
|
125 |
-
'post-thumbnail' => array('input' => array('size' => 1234), 'output' => array('size' => 1000)),
|
126 |
), $metadata);
|
127 |
}
|
128 |
|
@@ -186,4 +199,4 @@ class Tiny_Plugin_Test extends TinyTestCase {
|
|
186 |
$this->subject->compress_attachment($testmeta, 1);
|
187 |
$this->assertEquals(2, count($this->wp->getCalls('update_post_meta')));
|
188 |
}
|
189 |
-
}
|
34 |
$input = filesize($file);
|
35 |
switch ($key) {
|
36 |
case "thumbnail":
|
37 |
+
$output = 81;
|
38 |
+
$width = '150';
|
39 |
+
$height = '150';
|
40 |
+
break;
|
41 |
case "medium":
|
42 |
+
$output = 768;
|
43 |
+
$width = '300';
|
44 |
+
$height = '300';
|
45 |
+
break;
|
46 |
case "large":
|
47 |
+
$output = 6789;
|
48 |
+
$width = '1024';
|
49 |
+
$height = '1024';
|
50 |
+
break;
|
51 |
case "post-thumbnail":
|
52 |
+
$output = 1000;
|
53 |
+
$width = '800';
|
54 |
+
$height = '500';
|
55 |
+
break;
|
56 |
default:
|
57 |
$output = 10000;
|
58 |
+
$width = '4000';
|
59 |
+
$height = '3000';
|
60 |
}
|
61 |
$this->vfs->getChild(vfsStream::path($file))->truncate($output);
|
62 |
+
return array('input' => array('size' => $input), 'output' => array('size' => $output, 'width' => $width, 'height' => $height));
|
|
|
63 |
}
|
64 |
|
65 |
public function testInitShouldAddFilters() {
|
133 |
unset($metadata[$key]['start']);
|
134 |
}
|
135 |
$this->assertEquals(array(
|
136 |
+
0 => array('input' => array('size' => 12345), 'output' => array('size' => 10000, 'width' => 4000, 'height' => 3000)),
|
137 |
+
'large' => array('input' => array('size' => 10000), 'output' => array('size' => 6789, 'width' => 1024, 'height' => 1024)),
|
138 |
+
'post-thumbnail' => array('input' => array('size' => 1234), 'output' => array('size' => 1000, 'width' => 800, 'height' => 500)),
|
139 |
), $metadata);
|
140 |
}
|
141 |
|
199 |
$this->subject->compress_attachment($testmeta, 1);
|
200 |
$this->assertEquals(2, count($this->wp->getCalls('update_post_meta')));
|
201 |
}
|
202 |
+
}
|
test/unit/TinySettingsTest.php
CHANGED
@@ -14,6 +14,7 @@ class Tiny_Settings_Test extends TinyTestCase {
|
|
14 |
$this->assertEquals(array(
|
15 |
array('media', 'tinypng_api_key'),
|
16 |
array('media', 'tinypng_sizes'),
|
|
|
17 |
array('media', 'tinypng_status')
|
18 |
), $this->wp->getCalls('register_setting'));
|
19 |
}
|
@@ -28,6 +29,7 @@ class Tiny_Settings_Test extends TinyTestCase {
|
|
28 |
$this->assertEquals(array(
|
29 |
array('tinypng_api_key', 'TinyPNG API key', array($this->subject, 'render_api_key'), 'media', 'tinypng_settings', array('label_for' => 'tinypng_api_key')),
|
30 |
array('tinypng_sizes', 'File compression', array($this->subject, 'render_sizes'), 'media', 'tinypng_settings'),
|
|
|
31 |
array('tinypng_status', 'Connection status', array($this->subject, 'render_pending_status'), 'media', 'tinypng_settings')
|
32 |
), $this->wp->getCalls('add_settings_field'));
|
33 |
}
|
@@ -99,4 +101,49 @@ class Tiny_Settings_Test extends TinyTestCase {
|
|
99 |
array('width' => 0, 'height' => 888, 'tinify' => true),
|
100 |
$sizes["additional_size_no_width"]);
|
101 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
}
|
14 |
$this->assertEquals(array(
|
15 |
array('media', 'tinypng_api_key'),
|
16 |
array('media', 'tinypng_sizes'),
|
17 |
+
array('media', 'tinypng_resize_original'),
|
18 |
array('media', 'tinypng_status')
|
19 |
), $this->wp->getCalls('register_setting'));
|
20 |
}
|
29 |
$this->assertEquals(array(
|
30 |
array('tinypng_api_key', 'TinyPNG API key', array($this->subject, 'render_api_key'), 'media', 'tinypng_settings', array('label_for' => 'tinypng_api_key')),
|
31 |
array('tinypng_sizes', 'File compression', array($this->subject, 'render_sizes'), 'media', 'tinypng_settings'),
|
32 |
+
array('tinypng_resize_original', 'Resize original', array($this->subject, 'render_resize'), 'media', 'tinypng_settings'),
|
33 |
array('tinypng_status', 'Connection status', array($this->subject, 'render_pending_status'), 'media', 'tinypng_settings')
|
34 |
), $this->wp->getCalls('add_settings_field'));
|
35 |
}
|
101 |
array('width' => 0, 'height' => 888, 'tinify' => true),
|
102 |
$sizes["additional_size_no_width"]);
|
103 |
}
|
104 |
+
|
105 |
+
public function testShouldReturnResizeEnabled() {
|
106 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on'));
|
107 |
+
$this->assertEquals(true, $this->subject->get_resize_enabled());
|
108 |
+
}
|
109 |
+
|
110 |
+
public function testShouldReturnResizeNotEnabledWithoutConfiguration() {
|
111 |
+
$this->wp->addOption("tinypng_resize_original", array());
|
112 |
+
$this->assertEquals(false, $this->subject->get_resize_enabled());
|
113 |
+
}
|
114 |
+
|
115 |
+
public function testShouldReturnResizeOptionsWithWidthAndHeight() {
|
116 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '800', 'height' => '600'));
|
117 |
+
$this->assertEquals(array('method' => 'fit', 'width' => 800, 'height' => 600), $this->subject->get_resize_options());
|
118 |
+
}
|
119 |
+
|
120 |
+
public function testShouldReturnResizeOptionsWithoutWidth() {
|
121 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '', 'height' => '600'));
|
122 |
+
$this->assertEquals(array('method' => 'scale', 'height' => 600), $this->subject->get_resize_options());
|
123 |
+
}
|
124 |
+
|
125 |
+
public function testShouldReturnResizeOptionsWithoutHeight() {
|
126 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '800', 'height' => '',));
|
127 |
+
$this->assertEquals(array('method' => 'scale', 'width' => 800), $this->subject->get_resize_options());
|
128 |
+
}
|
129 |
+
|
130 |
+
public function testShouldReturnResizeOptionsWithInvaledWidth() {
|
131 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '-1', 'height' => '600'));
|
132 |
+
$this->assertEquals(array('method' => 'scale', 'height' => 600), $this->subject->get_resize_options());
|
133 |
+
}
|
134 |
+
|
135 |
+
public function testShouldReturnResizeOptionsWithInvaledHeight() {
|
136 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '800', 'height' => '-1'));
|
137 |
+
$this->assertEquals(array('method' => 'scale', 'width' => 800), $this->subject->get_resize_options());
|
138 |
+
}
|
139 |
+
|
140 |
+
public function testShouldNotReturnResizeOptionsWithoutWithAndHeight() {
|
141 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '', 'height' => ''));
|
142 |
+
$this->assertEquals(false, $this->subject->get_resize_options());
|
143 |
+
}
|
144 |
+
|
145 |
+
public function testShouldNotReturnResizeOptionsWhenNotEnabled() {
|
146 |
+
$this->wp->addOption("tinypng_resize_original", array('width' => '800', 'height' => '600'));
|
147 |
+
$this->assertEquals(false, $this->subject->get_resize_options());
|
148 |
+
}
|
149 |
}
|
tiny-compress-images.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
/**
|
3 |
* Plugin Name: Compress JPEG & PNG images
|
4 |
* Description: Speed up your website. Optimize your JPEG and PNG images automatically with TinyPNG.
|
5 |
-
* Version: 1.
|
6 |
* Author: TinyPNG
|
7 |
* Author URI: https://tinypng.com
|
8 |
* License: GPLv2 or later
|
@@ -24,4 +24,4 @@ $tiny_plugin = new Tiny_Plugin();
|
|
24 |
|
25 |
if (!defined('TINY_DEBUG')) {
|
26 |
define('TINY_DEBUG', null);
|
27 |
-
}
|
2 |
/**
|
3 |
* Plugin Name: Compress JPEG & PNG images
|
4 |
* Description: Speed up your website. Optimize your JPEG and PNG images automatically with TinyPNG.
|
5 |
+
* Version: 1.5.0
|
6 |
* Author: TinyPNG
|
7 |
* Author URI: https://tinypng.com
|
8 |
* License: GPLv2 or later
|
24 |
|
25 |
if (!defined('TINY_DEBUG')) {
|
26 |
define('TINY_DEBUG', null);
|
27 |
+
}
|