Version Description
- Improved compression status in the Media Library with new details window.
- Show total compression savings on the Media Settings page with link to bulk compression page when no images have been compressed yet.
- Moved Compress All Images from the Tools to the Media menu.
Download this release
Release Info
Developer | TinyPNG |
Plugin | Compress JPEG & PNG images |
Version | 1.6.0 |
Comparing to | |
See all releases |
Code changes from version 1.3.1 to 1.6.0
- README.md +23 -8
- RELEASE +14 -11
- bin/docker-functions +2 -2
- bin/integration-tests +8 -2
- bin/restore-wordpress +11 -1
- bin/test-wordpress +12 -2
- composer.json +8 -1
- composer.lock +230 -139
- config/Dockerfile-phantomjs +2 -14
- config/Dockerfile-wordpress-37 +3 -3
- config/Dockerfile-wordpress-38 +3 -3
- config/Dockerfile-wordpress-39 +3 -3
- config/Dockerfile-wordpress-40 +3 -3
- config/Dockerfile-wordpress-41 +3 -3
- config/Dockerfile-wordpress-42 +3 -3
- config/Dockerfile-wordpress-43 +15 -0
- readme.txt +49 -21
- src/class-tiny-compress-curl.php +22 -11
- src/class-tiny-compress-fopen.php +34 -14
- src/class-tiny-compress.php +45 -9
- src/class-tiny-metadata.php +98 -18
- src/class-tiny-plugin.php +62 -44
- src/class-tiny-settings.php +180 -32
- src/class-tiny-wp-base.php +15 -2
- src/config/tiny-config.php +1 -0
- src/languages/tiny-compress-images-nl_NL.mo +0 -0
- src/languages/tiny-compress-images-nl_NL.po +135 -27
- src/languages/tiny-compress-images-ru_RU.mo +0 -0
- src/languages/tiny-compress-images-ru_RU.po +6 -12
- src/languages/tiny-compress-images-zh_TW.mo +0 -0
- src/languages/tiny-compress-images-zh_TW.po +205 -0
- src/scripts/admin.js +30 -1
- src/styles/admin.css +88 -3
- src/views/compress-details-processing.php +9 -0
- src/views/compress-details.php +119 -0
- test/fixtures/input-large.jpg +0 -0
- test/fixtures/json/wp_meta_default_sizes.json +27 -0
- test/fixtures/json/wp_meta_sizes_with_same_files.json +21 -0
- test/helpers/setup.php +11 -5
- test/helpers/wordpress.php +45 -2
- test/integration/BulkCompressIntegrationTest.php +2 -2
- test/integration/CompressIntegrationTest.php +70 -4
- test/integration/IntegrationTestCase.php +39 -0
- test/integration/PluginIntegrationTest.php +21 -0
- test/integration/SettingsIntegrationTest.php +85 -1
- 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 +22 -29
- test/unit/TinyMetadataTest.php +279 -0
- test/unit/TinyPluginTest.php +24 -11
- test/unit/TinySettingsTest.php +51 -2
- test/unit/TinyTestCase.php +9 -0
- tiny-compress-images.php +16 -16
- trunk/tmp/.gitkeep +0 -0
README.md
CHANGED
@@ -1,25 +1,29 @@
|
|
1 |
[<img src="https://travis-ci.org/tinify/wordpress-plugin.svg?branch=master" alt="Build Status">](https://travis-ci.org/tinify/wordpress-plugin)
|
2 |
|
3 |
-
#
|
|
|
4 |
Make your website faster by compressing your JPEG and PNG images.
|
5 |
|
6 |
-
This plugin automatically optimizes your images by integrating with the
|
|
|
|
|
7 |
|
8 |
-
Learn more about TinyPNG at https://tinypng.com
|
9 |
|
10 |
## Contact us
|
|
|
11 |
Got questions or feedback? Let us know! Contact us at support@tinypng.com.
|
12 |
|
13 |
## Information for plugin contributors
|
14 |
|
15 |
### Prerequisites
|
16 |
-
* A working
|
17 |
* Composer (https://getcomposer.org/download/).
|
18 |
* Selenium Server (http://www.seleniumhq.org/download/).
|
19 |
-
*
|
20 |
* Java runtime.
|
21 |
|
22 |
-
### Running the plugin in
|
23 |
1. Run `bin/run-wordpress <version>`. E.g. `bin/run-wordpress 41`.
|
24 |
2. Use `docker ps` to check which port to use to connect to WordPress.
|
25 |
|
@@ -28,11 +32,22 @@ Got questions or feedback? Let us know! Contact us at support@tinypng.com.
|
|
28 |
|
29 |
### Running the integration tests
|
30 |
1. Start Selenium server: `java -jar selenium-server-standalone-2.44.0.jar`.
|
31 |
-
2. Run `bin/integration-tests $version [$to_version]
|
|
|
|
|
|
|
|
|
32 |
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
## License
|
|
|
36 |
Copyright (C) 2015 Voormedia B.V.
|
37 |
|
38 |
This program is free software; you can redistribute it and/or modify
|
1 |
[<img src="https://travis-ci.org/tinify/wordpress-plugin.svg?branch=master" alt="Build Status">](https://travis-ci.org/tinify/wordpress-plugin)
|
2 |
|
3 |
+
# Compress JPEG & PNG images for WordPress
|
4 |
+
|
5 |
Make your website faster by compressing your JPEG and PNG images.
|
6 |
|
7 |
+
This plugin automatically optimizes your images by integrating with the
|
8 |
+
popular image compression services TinyJPG and TinyPNG. You can download the
|
9 |
+
plugin from https://wordpress.org/plugins/tiny-compress-images/.
|
10 |
|
11 |
+
Learn more about TinyJPG and TinyPNG at https://tinypng.com/.
|
12 |
|
13 |
## Contact us
|
14 |
+
|
15 |
Got questions or feedback? Let us know! Contact us at support@tinypng.com.
|
16 |
|
17 |
## Information for plugin contributors
|
18 |
|
19 |
### Prerequisites
|
20 |
+
* A working Docker installation (https://docs.docker.com/installation/).
|
21 |
* Composer (https://getcomposer.org/download/).
|
22 |
* Selenium Server (http://www.seleniumhq.org/download/).
|
23 |
+
* MySQL client and admin tools.
|
24 |
* Java runtime.
|
25 |
|
26 |
+
### Running the plugin in WordPress
|
27 |
1. Run `bin/run-wordpress <version>`. E.g. `bin/run-wordpress 41`.
|
28 |
2. Use `docker ps` to check which port to use to connect to WordPress.
|
29 |
|
32 |
|
33 |
### Running the integration tests
|
34 |
1. Start Selenium server: `java -jar selenium-server-standalone-2.44.0.jar`.
|
35 |
+
2. Run `bin/integration-tests $version [$to_version]` (When $to_version is
|
36 |
+
added, all versions between $version and $to_version are tested). E.g.
|
37 |
+
`bin/integration-tests 41` or `bin/integration-tests 40 42`.
|
38 |
+
|
39 |
+
### Create language files
|
40 |
|
41 |
+
WordPress requires both .po and .mo files for each language. The .mo files
|
42 |
+
can be generated with [gettext](https://www.gnu.org/software/gettext/) that
|
43 |
+
needs to be installed first.
|
44 |
+
|
45 |
+
1. Install gettext for example run `brew install gettext`.
|
46 |
+
2. Add a link msgfmt `ln -s /usr/local/Cellar/gettext/0.19.6/bin/msgfmt ~/.bin`.
|
47 |
+
3. Generate the .mo files `bin/format-language-files`.
|
48 |
|
49 |
## License
|
50 |
+
|
51 |
Copyright (C) 2015 Voormedia B.V.
|
52 |
|
53 |
This program is free software; you can redistribute it and/or modify
|
RELEASE
CHANGED
@@ -2,14 +2,17 @@ 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. Delete
|
14 |
-
12.
|
15 |
-
13.
|
|
|
|
|
|
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.txt 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. Run `svn update` when the Subversion repository already existed.
|
12 |
+
10. Update svn:ignore property of trunk when .gitignore is updated: `svn propedit svn:ignore trunk`.
|
13 |
+
11. Delete everything in trunk `rm -rf <path-to-local-svn-repo/trunk/*`.
|
14 |
+
12. 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/`.
|
15 |
+
13. Add new files `svn st | awk '/^\?/ { print $2; }' | xargs svn add`.
|
16 |
+
14. Delete deleted files: `svn st | awk '/^!/ { print $2; }' | xargs svn rm`.
|
17 |
+
15. Commit the trunk to Subversion: `svn ci -m "<message>"`.
|
18 |
+
16. Tag the new release in Subversion and commit: `svn cp trunk tags/<version> && svn ci -m "<message>"`.
|
bin/docker-functions
CHANGED
@@ -21,7 +21,7 @@ run_phantomjs() {
|
|
21 |
echo "Starting PhantomJS container..."
|
22 |
docker run --name phantomjs \
|
23 |
--link "wordpress$version":wordpress \
|
24 |
-
|
25 |
}
|
26 |
|
27 |
run_wordpress() {
|
@@ -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 |
}
|
21 |
echo "Starting PhantomJS container..."
|
22 |
docker run --name phantomjs \
|
23 |
--link "wordpress$version":wordpress \
|
24 |
+
--detach=false phantomjs
|
25 |
}
|
26 |
|
27 |
run_wordpress() {
|
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
@@ -7,7 +7,13 @@ use IO::Socket;
|
|
7 |
use Time::HiRes qw(usleep);
|
8 |
|
9 |
my $dir = dirname($0);
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
sub check_port {
|
13 |
my ($ip, $port, $times, $sleep) = @_;
|
@@ -28,7 +34,7 @@ my $from = $ARGV[0] || 42;
|
|
28 |
my $to = $ARGV[1] || $from;
|
29 |
|
30 |
for (my $version = $from; $version <= $to; $version++) {
|
31 |
-
printf("====================
|
32 |
print(" - Running\n");
|
33 |
my $ret = system("$dir/run-wordpress $version > /dev/null 2>&1");
|
34 |
if ($ret) {
|
7 |
use Time::HiRes qw(usleep);
|
8 |
|
9 |
my $dir = dirname($0);
|
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 |
+
}
|
17 |
|
18 |
sub check_port {
|
19 |
my ($ip, $port, $times, $sleep) = @_;
|
34 |
my $to = $ARGV[1] || $from;
|
35 |
|
36 |
for (my $version = $from; $version <= $to; $version++) {
|
37 |
+
printf("==================== WordPress %d ====================\n", $version);
|
38 |
print(" - Running\n");
|
39 |
my $ret = system("$dir/run-wordpress $version > /dev/null 2>&1");
|
40 |
if ($ret) {
|
bin/restore-wordpress
CHANGED
@@ -19,7 +19,17 @@ source $DIR/docker-functions
|
|
19 |
export WORDPRESS_VERSION=$version
|
20 |
export WORDPRESS_DATABASE=wordpress_$version
|
21 |
export MYSQL_ROOT_PASSWORD=root
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
export MYSQL_DUMP_FILE=tmp/mysqldump_wordpress_$version.sql.gz
|
24 |
|
25 |
gunzip -c < $MYSQL_DUMP_FILE | mysql -h $HOST_IP -u root "-p$MYSQL_ROOT_PASSWORD" $WORDPRESS_DATABASE
|
19 |
export WORDPRESS_VERSION=$version
|
20 |
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 $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 |
|
35 |
gunzip -c < $MYSQL_DUMP_FILE | mysql -h $HOST_IP -u root "-p$MYSQL_ROOT_PASSWORD" $WORDPRESS_DATABASE
|
bin/test-wordpress
CHANGED
@@ -26,7 +26,17 @@ fi
|
|
26 |
export WORDPRESS_VERSION=$version
|
27 |
export WORDPRESS_DATABASE=wordpress_$version
|
28 |
export MYSQL_ROOT_PASSWORD=root
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
export HOST_PORT=80$version
|
31 |
-
export WORDPRESS_URL=http://$
|
32 |
vendor/bin/phpunit "$PHPUNIT_ARG"
|
26 |
export WORDPRESS_VERSION=$version
|
27 |
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 $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
|
42 |
vendor/bin/phpunit "$PHPUNIT_ARG"
|
composer.json
CHANGED
@@ -1,8 +1,15 @@
|
|
1 |
{
|
|
|
|
|
|
|
|
|
|
|
2 |
"require": {
|
3 |
-
"
|
|
|
4 |
},
|
5 |
"require-dev": {
|
|
|
6 |
"phpunit/phpunit": "~4.6",
|
7 |
"mikey179/vfsStream": "~1.5",
|
8 |
"mockery/mockery": "~0.9"
|
1 |
{
|
2 |
+
"name": "tinify/wordpress-plugin",
|
3 |
+
"description": "Speed up your website. Optimize your JPEG and PNG images automatically with TinyPNG.",
|
4 |
+
"license": "GPL-2.0+",
|
5 |
+
"type": "wordpress-plugin",
|
6 |
+
"keywords": ["plugin"],
|
7 |
"require": {
|
8 |
+
"php": ">=5.3.0",
|
9 |
+
"composer/installers": "~1.0"
|
10 |
},
|
11 |
"require-dev": {
|
12 |
+
"facebook/webdriver": "0.5.*",
|
13 |
"phpunit/phpunit": "~4.6",
|
14 |
"mikey179/vfsStream": "~1.5",
|
15 |
"mockery/mockery": "~0.9"
|
composer.lock
CHANGED
@@ -4,63 +4,120 @@
|
|
4 |
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
5 |
"This file is @generated automatically"
|
6 |
],
|
7 |
-
"hash": "
|
8 |
"packages": [
|
9 |
{
|
10 |
-
"name": "
|
11 |
-
"version": "
|
12 |
"source": {
|
13 |
"type": "git",
|
14 |
-
"url": "https://github.com/
|
15 |
-
"reference": "
|
16 |
},
|
17 |
"dist": {
|
18 |
"type": "zip",
|
19 |
-
"url": "https://api.github.com/repos/
|
20 |
-
"reference": "
|
21 |
"shasum": ""
|
22 |
},
|
23 |
"require": {
|
24 |
-
"
|
|
|
|
|
|
|
|
|
25 |
},
|
26 |
"require-dev": {
|
27 |
-
"
|
28 |
-
"phpunit/phpunit": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
},
|
30 |
-
"type": "library",
|
31 |
"autoload": {
|
32 |
-
"
|
33 |
-
"
|
34 |
-
|
35 |
},
|
36 |
"notification-url": "https://packagist.org/downloads/",
|
37 |
"license": [
|
38 |
-
"
|
39 |
],
|
40 |
-
"
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
"keywords": [
|
43 |
-
"
|
44 |
-
"
|
45 |
-
"
|
46 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
],
|
48 |
-
"time": "
|
49 |
}
|
50 |
],
|
51 |
"packages-dev": [
|
52 |
{
|
53 |
"name": "doctrine/instantiator",
|
54 |
-
"version": "1.0.
|
55 |
"source": {
|
56 |
"type": "git",
|
57 |
"url": "https://github.com/doctrine/instantiator.git",
|
58 |
-
"reference": "
|
59 |
},
|
60 |
"dist": {
|
61 |
"type": "zip",
|
62 |
-
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/
|
63 |
-
"reference": "
|
64 |
"shasum": ""
|
65 |
},
|
66 |
"require": {
|
@@ -71,7 +128,7 @@
|
|
71 |
"ext-pdo": "*",
|
72 |
"ext-phar": "*",
|
73 |
"phpunit/phpunit": "~4.0",
|
74 |
-
"squizlabs/php_codesniffer": "2.0
|
75 |
},
|
76 |
"type": "library",
|
77 |
"extra": {
|
@@ -80,8 +137,8 @@
|
|
80 |
}
|
81 |
},
|
82 |
"autoload": {
|
83 |
-
"psr-
|
84 |
-
"Doctrine\\Instantiator\\": "src"
|
85 |
}
|
86 |
},
|
87 |
"notification-url": "https://packagist.org/downloads/",
|
@@ -101,7 +158,48 @@
|
|
101 |
"constructor",
|
102 |
"instantiate"
|
103 |
],
|
104 |
-
"time": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
},
|
106 |
{
|
107 |
"name": "hamcrest/hamcrest-php",
|
@@ -150,16 +248,16 @@
|
|
150 |
},
|
151 |
{
|
152 |
"name": "mikey179/vfsStream",
|
153 |
-
"version": "v1.
|
154 |
"source": {
|
155 |
"type": "git",
|
156 |
"url": "https://github.com/mikey179/vfsStream.git",
|
157 |
-
"reference": "
|
158 |
},
|
159 |
"dist": {
|
160 |
"type": "zip",
|
161 |
-
"url": "https://api.github.com/repos/mikey179/vfsStream/zipball/
|
162 |
-
"reference": "
|
163 |
"shasum": ""
|
164 |
},
|
165 |
"require": {
|
@@ -171,7 +269,7 @@
|
|
171 |
"type": "library",
|
172 |
"extra": {
|
173 |
"branch-alias": {
|
174 |
-
"dev-master": "1.
|
175 |
}
|
176 |
},
|
177 |
"autoload": {
|
@@ -192,7 +290,7 @@
|
|
192 |
],
|
193 |
"description": "Virtual file system to mock the real file system in unit tests.",
|
194 |
"homepage": "http://vfs.bovigo.org/",
|
195 |
-
"time": "2015-
|
196 |
},
|
197 |
{
|
198 |
"name": "mockery/mockery",
|
@@ -310,16 +408,16 @@
|
|
310 |
},
|
311 |
{
|
312 |
"name": "phpspec/prophecy",
|
313 |
-
"version": "v1.
|
314 |
"source": {
|
315 |
"type": "git",
|
316 |
"url": "https://github.com/phpspec/prophecy.git",
|
317 |
-
"reference": "
|
318 |
},
|
319 |
"dist": {
|
320 |
"type": "zip",
|
321 |
-
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/
|
322 |
-
"reference": "
|
323 |
"shasum": ""
|
324 |
},
|
325 |
"require": {
|
@@ -366,20 +464,20 @@
|
|
366 |
"spy",
|
367 |
"stub"
|
368 |
],
|
369 |
-
"time": "2015-
|
370 |
},
|
371 |
{
|
372 |
"name": "phpunit/php-code-coverage",
|
373 |
-
"version": "2.
|
374 |
"source": {
|
375 |
"type": "git",
|
376 |
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
377 |
-
"reference": "
|
378 |
},
|
379 |
"dist": {
|
380 |
"type": "zip",
|
381 |
-
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/
|
382 |
-
"reference": "
|
383 |
"shasum": ""
|
384 |
},
|
385 |
"require": {
|
@@ -387,7 +485,7 @@
|
|
387 |
"phpunit/php-file-iterator": "~1.3",
|
388 |
"phpunit/php-text-template": "~1.2",
|
389 |
"phpunit/php-token-stream": "~1.3",
|
390 |
-
"sebastian/environment": "
|
391 |
"sebastian/version": "~1.0"
|
392 |
},
|
393 |
"require-dev": {
|
@@ -402,7 +500,7 @@
|
|
402 |
"type": "library",
|
403 |
"extra": {
|
404 |
"branch-alias": {
|
405 |
-
"dev-master": "2.
|
406 |
}
|
407 |
},
|
408 |
"autoload": {
|
@@ -428,20 +526,20 @@
|
|
428 |
"testing",
|
429 |
"xunit"
|
430 |
],
|
431 |
-
"time": "2015-
|
432 |
},
|
433 |
{
|
434 |
"name": "phpunit/php-file-iterator",
|
435 |
-
"version": "1.4.
|
436 |
"source": {
|
437 |
"type": "git",
|
438 |
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
439 |
-
"reference": "
|
440 |
},
|
441 |
"dist": {
|
442 |
"type": "zip",
|
443 |
-
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/
|
444 |
-
"reference": "
|
445 |
"shasum": ""
|
446 |
},
|
447 |
"require": {
|
@@ -475,20 +573,20 @@
|
|
475 |
"filesystem",
|
476 |
"iterator"
|
477 |
],
|
478 |
-
"time": "2015-
|
479 |
},
|
480 |
{
|
481 |
"name": "phpunit/php-text-template",
|
482 |
-
"version": "1.2.
|
483 |
"source": {
|
484 |
"type": "git",
|
485 |
"url": "https://github.com/sebastianbergmann/php-text-template.git",
|
486 |
-
"reference": "
|
487 |
},
|
488 |
"dist": {
|
489 |
"type": "zip",
|
490 |
-
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/
|
491 |
-
"reference": "
|
492 |
"shasum": ""
|
493 |
},
|
494 |
"require": {
|
@@ -497,20 +595,17 @@
|
|
497 |
"type": "library",
|
498 |
"autoload": {
|
499 |
"classmap": [
|
500 |
-
"
|
501 |
]
|
502 |
},
|
503 |
"notification-url": "https://packagist.org/downloads/",
|
504 |
-
"include-path": [
|
505 |
-
""
|
506 |
-
],
|
507 |
"license": [
|
508 |
"BSD-3-Clause"
|
509 |
],
|
510 |
"authors": [
|
511 |
{
|
512 |
"name": "Sebastian Bergmann",
|
513 |
-
"email": "
|
514 |
"role": "lead"
|
515 |
}
|
516 |
],
|
@@ -519,20 +614,20 @@
|
|
519 |
"keywords": [
|
520 |
"template"
|
521 |
],
|
522 |
-
"time": "
|
523 |
},
|
524 |
{
|
525 |
"name": "phpunit/php-timer",
|
526 |
-
"version": "1.0.
|
527 |
"source": {
|
528 |
"type": "git",
|
529 |
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
530 |
-
"reference": "
|
531 |
},
|
532 |
"dist": {
|
533 |
"type": "zip",
|
534 |
-
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/
|
535 |
-
"reference": "
|
536 |
"shasum": ""
|
537 |
},
|
538 |
"require": {
|
@@ -541,13 +636,10 @@
|
|
541 |
"type": "library",
|
542 |
"autoload": {
|
543 |
"classmap": [
|
544 |
-
"
|
545 |
]
|
546 |
},
|
547 |
"notification-url": "https://packagist.org/downloads/",
|
548 |
-
"include-path": [
|
549 |
-
""
|
550 |
-
],
|
551 |
"license": [
|
552 |
"BSD-3-Clause"
|
553 |
],
|
@@ -563,20 +655,20 @@
|
|
563 |
"keywords": [
|
564 |
"timer"
|
565 |
],
|
566 |
-
"time": "
|
567 |
},
|
568 |
{
|
569 |
"name": "phpunit/php-token-stream",
|
570 |
-
"version": "1.4.
|
571 |
"source": {
|
572 |
"type": "git",
|
573 |
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
574 |
-
"reference": "
|
575 |
},
|
576 |
"dist": {
|
577 |
"type": "zip",
|
578 |
-
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/
|
579 |
-
"reference": "
|
580 |
"shasum": ""
|
581 |
},
|
582 |
"require": {
|
@@ -612,20 +704,20 @@
|
|
612 |
"keywords": [
|
613 |
"tokenizer"
|
614 |
],
|
615 |
-
"time": "2015-
|
616 |
},
|
617 |
{
|
618 |
"name": "phpunit/phpunit",
|
619 |
-
"version": "4.
|
620 |
"source": {
|
621 |
"type": "git",
|
622 |
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
623 |
-
"reference": "
|
624 |
},
|
625 |
"dist": {
|
626 |
"type": "zip",
|
627 |
-
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/
|
628 |
-
"reference": "
|
629 |
"shasum": ""
|
630 |
},
|
631 |
"require": {
|
@@ -635,15 +727,15 @@
|
|
635 |
"ext-reflection": "*",
|
636 |
"ext-spl": "*",
|
637 |
"php": ">=5.3.3",
|
638 |
-
"phpspec/prophecy": "
|
639 |
-
"phpunit/php-code-coverage": "~2.
|
640 |
"phpunit/php-file-iterator": "~1.4",
|
641 |
"phpunit/php-text-template": "~1.2",
|
642 |
-
"phpunit/php-timer": "
|
643 |
"phpunit/phpunit-mock-objects": "~2.3",
|
644 |
"sebastian/comparator": "~1.1",
|
645 |
"sebastian/diff": "~1.2",
|
646 |
-
"sebastian/environment": "~1.
|
647 |
"sebastian/exporter": "~1.2",
|
648 |
"sebastian/global-state": "~1.0",
|
649 |
"sebastian/version": "~1.0",
|
@@ -658,7 +750,7 @@
|
|
658 |
"type": "library",
|
659 |
"extra": {
|
660 |
"branch-alias": {
|
661 |
-
"dev-master": "4.
|
662 |
}
|
663 |
},
|
664 |
"autoload": {
|
@@ -684,26 +776,27 @@
|
|
684 |
"testing",
|
685 |
"xunit"
|
686 |
],
|
687 |
-
"time": "2015-
|
688 |
},
|
689 |
{
|
690 |
"name": "phpunit/phpunit-mock-objects",
|
691 |
-
"version": "2.3.
|
692 |
"source": {
|
693 |
"type": "git",
|
694 |
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
|
695 |
-
"reference": "
|
696 |
},
|
697 |
"dist": {
|
698 |
"type": "zip",
|
699 |
-
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/
|
700 |
-
"reference": "
|
701 |
"shasum": ""
|
702 |
},
|
703 |
"require": {
|
704 |
-
"doctrine/instantiator": "
|
705 |
"php": ">=5.3.3",
|
706 |
-
"phpunit/php-text-template": "~1.2"
|
|
|
707 |
},
|
708 |
"require-dev": {
|
709 |
"phpunit/phpunit": "~4.4"
|
@@ -739,20 +832,20 @@
|
|
739 |
"mock",
|
740 |
"xunit"
|
741 |
],
|
742 |
-
"time": "2015-
|
743 |
},
|
744 |
{
|
745 |
"name": "sebastian/comparator",
|
746 |
-
"version": "1.
|
747 |
"source": {
|
748 |
"type": "git",
|
749 |
"url": "https://github.com/sebastianbergmann/comparator.git",
|
750 |
-
"reference": "
|
751 |
},
|
752 |
"dist": {
|
753 |
"type": "zip",
|
754 |
-
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/
|
755 |
-
"reference": "
|
756 |
"shasum": ""
|
757 |
},
|
758 |
"require": {
|
@@ -766,7 +859,7 @@
|
|
766 |
"type": "library",
|
767 |
"extra": {
|
768 |
"branch-alias": {
|
769 |
-
"dev-master": "1.
|
770 |
}
|
771 |
},
|
772 |
"autoload": {
|
@@ -803,7 +896,7 @@
|
|
803 |
"compare",
|
804 |
"equality"
|
805 |
],
|
806 |
-
"time": "2015-
|
807 |
},
|
808 |
{
|
809 |
"name": "sebastian/diff",
|
@@ -859,16 +952,16 @@
|
|
859 |
},
|
860 |
{
|
861 |
"name": "sebastian/environment",
|
862 |
-
"version": "1.
|
863 |
"source": {
|
864 |
"type": "git",
|
865 |
"url": "https://github.com/sebastianbergmann/environment.git",
|
866 |
-
"reference": "
|
867 |
},
|
868 |
"dist": {
|
869 |
"type": "zip",
|
870 |
-
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/
|
871 |
-
"reference": "
|
872 |
"shasum": ""
|
873 |
},
|
874 |
"require": {
|
@@ -905,20 +998,20 @@
|
|
905 |
"environment",
|
906 |
"hhvm"
|
907 |
],
|
908 |
-
"time": "2015-
|
909 |
},
|
910 |
{
|
911 |
"name": "sebastian/exporter",
|
912 |
-
"version": "1.2.
|
913 |
"source": {
|
914 |
"type": "git",
|
915 |
"url": "https://github.com/sebastianbergmann/exporter.git",
|
916 |
-
"reference": "
|
917 |
},
|
918 |
"dist": {
|
919 |
"type": "zip",
|
920 |
-
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/
|
921 |
-
"reference": "
|
922 |
"shasum": ""
|
923 |
},
|
924 |
"require": {
|
@@ -971,20 +1064,20 @@
|
|
971 |
"export",
|
972 |
"exporter"
|
973 |
],
|
974 |
-
"time": "2015-
|
975 |
},
|
976 |
{
|
977 |
"name": "sebastian/global-state",
|
978 |
-
"version": "1.
|
979 |
"source": {
|
980 |
"type": "git",
|
981 |
"url": "https://github.com/sebastianbergmann/global-state.git",
|
982 |
-
"reference": "
|
983 |
},
|
984 |
"dist": {
|
985 |
"type": "zip",
|
986 |
-
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/
|
987 |
-
"reference": "
|
988 |
"shasum": ""
|
989 |
},
|
990 |
"require": {
|
@@ -1022,20 +1115,20 @@
|
|
1022 |
"keywords": [
|
1023 |
"global state"
|
1024 |
],
|
1025 |
-
"time": "
|
1026 |
},
|
1027 |
{
|
1028 |
"name": "sebastian/recursion-context",
|
1029 |
-
"version": "1.0.
|
1030 |
"source": {
|
1031 |
"type": "git",
|
1032 |
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
1033 |
-
"reference": "
|
1034 |
},
|
1035 |
"dist": {
|
1036 |
"type": "zip",
|
1037 |
-
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/
|
1038 |
-
"reference": "
|
1039 |
"shasum": ""
|
1040 |
},
|
1041 |
"require": {
|
@@ -1075,20 +1168,20 @@
|
|
1075 |
],
|
1076 |
"description": "Provides functionality to recursively process PHP variables",
|
1077 |
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
1078 |
-
"time": "2015-
|
1079 |
},
|
1080 |
{
|
1081 |
"name": "sebastian/version",
|
1082 |
-
"version": "1.0.
|
1083 |
"source": {
|
1084 |
"type": "git",
|
1085 |
"url": "https://github.com/sebastianbergmann/version.git",
|
1086 |
-
"reference": "
|
1087 |
},
|
1088 |
"dist": {
|
1089 |
"type": "zip",
|
1090 |
-
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/
|
1091 |
-
"reference": "
|
1092 |
"shasum": ""
|
1093 |
},
|
1094 |
"type": "library",
|
@@ -1110,37 +1203,33 @@
|
|
1110 |
],
|
1111 |
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
|
1112 |
"homepage": "https://github.com/sebastianbergmann/version",
|
1113 |
-
"time": "2015-
|
1114 |
},
|
1115 |
{
|
1116 |
"name": "symfony/yaml",
|
1117 |
-
"version": "v2.6
|
1118 |
-
"target-dir": "Symfony/Component/Yaml",
|
1119 |
"source": {
|
1120 |
"type": "git",
|
1121 |
-
"url": "https://github.com/symfony/
|
1122 |
-
"reference": "
|
1123 |
},
|
1124 |
"dist": {
|
1125 |
"type": "zip",
|
1126 |
-
"url": "https://api.github.com/repos/symfony/
|
1127 |
-
"reference": "
|
1128 |
"shasum": ""
|
1129 |
},
|
1130 |
"require": {
|
1131 |
-
"php": ">=5.3.
|
1132 |
-
},
|
1133 |
-
"require-dev": {
|
1134 |
-
"symfony/phpunit-bridge": "~2.7"
|
1135 |
},
|
1136 |
"type": "library",
|
1137 |
"extra": {
|
1138 |
"branch-alias": {
|
1139 |
-
"dev-master": "2.
|
1140 |
}
|
1141 |
},
|
1142 |
"autoload": {
|
1143 |
-
"psr-
|
1144 |
"Symfony\\Component\\Yaml\\": ""
|
1145 |
}
|
1146 |
},
|
@@ -1160,7 +1249,7 @@
|
|
1160 |
],
|
1161 |
"description": "Symfony Yaml Component",
|
1162 |
"homepage": "https://symfony.com",
|
1163 |
-
"time": "2015-
|
1164 |
}
|
1165 |
],
|
1166 |
"aliases": [],
|
@@ -1168,6 +1257,8 @@
|
|
1168 |
"stability-flags": [],
|
1169 |
"prefer-stable": false,
|
1170 |
"prefer-lowest": false,
|
1171 |
-
"platform":
|
|
|
|
|
1172 |
"platform-dev": []
|
1173 |
}
|
4 |
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
5 |
"This file is @generated automatically"
|
6 |
],
|
7 |
+
"hash": "ae7fd61a1dd5aff668e00bbc8cc907ae",
|
8 |
"packages": [
|
9 |
{
|
10 |
+
"name": "composer/installers",
|
11 |
+
"version": "v1.0.22",
|
12 |
"source": {
|
13 |
"type": "git",
|
14 |
+
"url": "https://github.com/composer/installers.git",
|
15 |
+
"reference": "bd9b14f094c89c8b5804a4e41edeb7853bb85046"
|
16 |
},
|
17 |
"dist": {
|
18 |
"type": "zip",
|
19 |
+
"url": "https://api.github.com/repos/composer/installers/zipball/bd9b14f094c89c8b5804a4e41edeb7853bb85046",
|
20 |
+
"reference": "bd9b14f094c89c8b5804a4e41edeb7853bb85046",
|
21 |
"shasum": ""
|
22 |
},
|
23 |
"require": {
|
24 |
+
"composer-plugin-api": "1.0.0"
|
25 |
+
},
|
26 |
+
"replace": {
|
27 |
+
"roundcube/plugin-installer": "*",
|
28 |
+
"shama/baton": "*"
|
29 |
},
|
30 |
"require-dev": {
|
31 |
+
"composer/composer": "1.0.*@dev",
|
32 |
+
"phpunit/phpunit": "4.1.*"
|
33 |
+
},
|
34 |
+
"type": "composer-plugin",
|
35 |
+
"extra": {
|
36 |
+
"class": "Composer\\Installers\\Plugin",
|
37 |
+
"branch-alias": {
|
38 |
+
"dev-master": "1.0-dev"
|
39 |
+
}
|
40 |
},
|
|
|
41 |
"autoload": {
|
42 |
+
"psr-0": {
|
43 |
+
"Composer\\Installers\\": "src/"
|
44 |
+
}
|
45 |
},
|
46 |
"notification-url": "https://packagist.org/downloads/",
|
47 |
"license": [
|
48 |
+
"MIT"
|
49 |
],
|
50 |
+
"authors": [
|
51 |
+
{
|
52 |
+
"name": "Kyle Robinson Young",
|
53 |
+
"email": "kyle@dontkry.com",
|
54 |
+
"homepage": "https://github.com/shama"
|
55 |
+
}
|
56 |
+
],
|
57 |
+
"description": "A multi-framework Composer library installer",
|
58 |
+
"homepage": "http://composer.github.com/installers/",
|
59 |
"keywords": [
|
60 |
+
"Craft",
|
61 |
+
"Dolibarr",
|
62 |
+
"Hurad",
|
63 |
+
"MODX Evo",
|
64 |
+
"OXID",
|
65 |
+
"SMF",
|
66 |
+
"Thelia",
|
67 |
+
"WolfCMS",
|
68 |
+
"agl",
|
69 |
+
"aimeos",
|
70 |
+
"annotatecms",
|
71 |
+
"bitrix",
|
72 |
+
"cakephp",
|
73 |
+
"chef",
|
74 |
+
"codeigniter",
|
75 |
+
"concrete5",
|
76 |
+
"croogo",
|
77 |
+
"dokuwiki",
|
78 |
+
"drupal",
|
79 |
+
"elgg",
|
80 |
+
"fuelphp",
|
81 |
+
"grav",
|
82 |
+
"installer",
|
83 |
+
"joomla",
|
84 |
+
"kohana",
|
85 |
+
"laravel",
|
86 |
+
"lithium",
|
87 |
+
"magento",
|
88 |
+
"mako",
|
89 |
+
"mediawiki",
|
90 |
+
"modulework",
|
91 |
+
"moodle",
|
92 |
+
"phpbb",
|
93 |
+
"piwik",
|
94 |
+
"ppi",
|
95 |
+
"puppet",
|
96 |
+
"roundcube",
|
97 |
+
"shopware",
|
98 |
+
"silverstripe",
|
99 |
+
"symfony",
|
100 |
+
"typo3",
|
101 |
+
"wordpress",
|
102 |
+
"zend",
|
103 |
+
"zikula"
|
104 |
],
|
105 |
+
"time": "2015-10-29 23:28:48"
|
106 |
}
|
107 |
],
|
108 |
"packages-dev": [
|
109 |
{
|
110 |
"name": "doctrine/instantiator",
|
111 |
+
"version": "1.0.5",
|
112 |
"source": {
|
113 |
"type": "git",
|
114 |
"url": "https://github.com/doctrine/instantiator.git",
|
115 |
+
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
|
116 |
},
|
117 |
"dist": {
|
118 |
"type": "zip",
|
119 |
+
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
|
120 |
+
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
|
121 |
"shasum": ""
|
122 |
},
|
123 |
"require": {
|
128 |
"ext-pdo": "*",
|
129 |
"ext-phar": "*",
|
130 |
"phpunit/phpunit": "~4.0",
|
131 |
+
"squizlabs/php_codesniffer": "~2.0"
|
132 |
},
|
133 |
"type": "library",
|
134 |
"extra": {
|
137 |
}
|
138 |
},
|
139 |
"autoload": {
|
140 |
+
"psr-4": {
|
141 |
+
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
|
142 |
}
|
143 |
},
|
144 |
"notification-url": "https://packagist.org/downloads/",
|
158 |
"constructor",
|
159 |
"instantiate"
|
160 |
],
|
161 |
+
"time": "2015-06-14 21:17:01"
|
162 |
+
},
|
163 |
+
{
|
164 |
+
"name": "facebook/webdriver",
|
165 |
+
"version": "v0.5.1",
|
166 |
+
"source": {
|
167 |
+
"type": "git",
|
168 |
+
"url": "https://github.com/facebook/php-webdriver.git",
|
169 |
+
"reference": "bbcb697efb394d17bd9ec3d467e7da847cde4509"
|
170 |
+
},
|
171 |
+
"dist": {
|
172 |
+
"type": "zip",
|
173 |
+
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/bbcb697efb394d17bd9ec3d467e7da847cde4509",
|
174 |
+
"reference": "bbcb697efb394d17bd9ec3d467e7da847cde4509",
|
175 |
+
"shasum": ""
|
176 |
+
},
|
177 |
+
"require": {
|
178 |
+
"php": ">=5.3.19"
|
179 |
+
},
|
180 |
+
"require-dev": {
|
181 |
+
"phpdocumentor/phpdocumentor": "2.*",
|
182 |
+
"phpunit/phpunit": "3.7.*"
|
183 |
+
},
|
184 |
+
"type": "library",
|
185 |
+
"autoload": {
|
186 |
+
"classmap": [
|
187 |
+
"lib/"
|
188 |
+
]
|
189 |
+
},
|
190 |
+
"notification-url": "https://packagist.org/downloads/",
|
191 |
+
"license": [
|
192 |
+
"Apache-2.0"
|
193 |
+
],
|
194 |
+
"description": "A php client for WebDriver",
|
195 |
+
"homepage": "https://github.com/facebook/php-webdriver",
|
196 |
+
"keywords": [
|
197 |
+
"facebook",
|
198 |
+
"php",
|
199 |
+
"selenium",
|
200 |
+
"webdriver"
|
201 |
+
],
|
202 |
+
"time": "2014-11-05 20:53:09"
|
203 |
},
|
204 |
{
|
205 |
"name": "hamcrest/hamcrest-php",
|
248 |
},
|
249 |
{
|
250 |
"name": "mikey179/vfsStream",
|
251 |
+
"version": "v1.6.0",
|
252 |
"source": {
|
253 |
"type": "git",
|
254 |
"url": "https://github.com/mikey179/vfsStream.git",
|
255 |
+
"reference": "73bcb605b741a7d5044b47592338c633788b0eb7"
|
256 |
},
|
257 |
"dist": {
|
258 |
"type": "zip",
|
259 |
+
"url": "https://api.github.com/repos/mikey179/vfsStream/zipball/73bcb605b741a7d5044b47592338c633788b0eb7",
|
260 |
+
"reference": "73bcb605b741a7d5044b47592338c633788b0eb7",
|
261 |
"shasum": ""
|
262 |
},
|
263 |
"require": {
|
269 |
"type": "library",
|
270 |
"extra": {
|
271 |
"branch-alias": {
|
272 |
+
"dev-master": "1.6.x-dev"
|
273 |
}
|
274 |
},
|
275 |
"autoload": {
|
290 |
],
|
291 |
"description": "Virtual file system to mock the real file system in unit tests.",
|
292 |
"homepage": "http://vfs.bovigo.org/",
|
293 |
+
"time": "2015-10-06 16:59:57"
|
294 |
},
|
295 |
{
|
296 |
"name": "mockery/mockery",
|
408 |
},
|
409 |
{
|
410 |
"name": "phpspec/prophecy",
|
411 |
+
"version": "v1.5.0",
|
412 |
"source": {
|
413 |
"type": "git",
|
414 |
"url": "https://github.com/phpspec/prophecy.git",
|
415 |
+
"reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7"
|
416 |
},
|
417 |
"dist": {
|
418 |
"type": "zip",
|
419 |
+
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7",
|
420 |
+
"reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7",
|
421 |
"shasum": ""
|
422 |
},
|
423 |
"require": {
|
464 |
"spy",
|
465 |
"stub"
|
466 |
],
|
467 |
+
"time": "2015-08-13 10:07:40"
|
468 |
},
|
469 |
{
|
470 |
"name": "phpunit/php-code-coverage",
|
471 |
+
"version": "2.2.4",
|
472 |
"source": {
|
473 |
"type": "git",
|
474 |
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
475 |
+
"reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
|
476 |
},
|
477 |
"dist": {
|
478 |
"type": "zip",
|
479 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
|
480 |
+
"reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
|
481 |
"shasum": ""
|
482 |
},
|
483 |
"require": {
|
485 |
"phpunit/php-file-iterator": "~1.3",
|
486 |
"phpunit/php-text-template": "~1.2",
|
487 |
"phpunit/php-token-stream": "~1.3",
|
488 |
+
"sebastian/environment": "^1.3.2",
|
489 |
"sebastian/version": "~1.0"
|
490 |
},
|
491 |
"require-dev": {
|
500 |
"type": "library",
|
501 |
"extra": {
|
502 |
"branch-alias": {
|
503 |
+
"dev-master": "2.2.x-dev"
|
504 |
}
|
505 |
},
|
506 |
"autoload": {
|
526 |
"testing",
|
527 |
"xunit"
|
528 |
],
|
529 |
+
"time": "2015-10-06 15:47:00"
|
530 |
},
|
531 |
{
|
532 |
"name": "phpunit/php-file-iterator",
|
533 |
+
"version": "1.4.1",
|
534 |
"source": {
|
535 |
"type": "git",
|
536 |
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
537 |
+
"reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
|
538 |
},
|
539 |
"dist": {
|
540 |
"type": "zip",
|
541 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
|
542 |
+
"reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
|
543 |
"shasum": ""
|
544 |
},
|
545 |
"require": {
|
573 |
"filesystem",
|
574 |
"iterator"
|
575 |
],
|
576 |
+
"time": "2015-06-21 13:08:43"
|
577 |
},
|
578 |
{
|
579 |
"name": "phpunit/php-text-template",
|
580 |
+
"version": "1.2.1",
|
581 |
"source": {
|
582 |
"type": "git",
|
583 |
"url": "https://github.com/sebastianbergmann/php-text-template.git",
|
584 |
+
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
|
585 |
},
|
586 |
"dist": {
|
587 |
"type": "zip",
|
588 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
|
589 |
+
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
|
590 |
"shasum": ""
|
591 |
},
|
592 |
"require": {
|
595 |
"type": "library",
|
596 |
"autoload": {
|
597 |
"classmap": [
|
598 |
+
"src/"
|
599 |
]
|
600 |
},
|
601 |
"notification-url": "https://packagist.org/downloads/",
|
|
|
|
|
|
|
602 |
"license": [
|
603 |
"BSD-3-Clause"
|
604 |
],
|
605 |
"authors": [
|
606 |
{
|
607 |
"name": "Sebastian Bergmann",
|
608 |
+
"email": "sebastian@phpunit.de",
|
609 |
"role": "lead"
|
610 |
}
|
611 |
],
|
614 |
"keywords": [
|
615 |
"template"
|
616 |
],
|
617 |
+
"time": "2015-06-21 13:50:34"
|
618 |
},
|
619 |
{
|
620 |
"name": "phpunit/php-timer",
|
621 |
+
"version": "1.0.7",
|
622 |
"source": {
|
623 |
"type": "git",
|
624 |
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
625 |
+
"reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
|
626 |
},
|
627 |
"dist": {
|
628 |
"type": "zip",
|
629 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
|
630 |
+
"reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
|
631 |
"shasum": ""
|
632 |
},
|
633 |
"require": {
|
636 |
"type": "library",
|
637 |
"autoload": {
|
638 |
"classmap": [
|
639 |
+
"src/"
|
640 |
]
|
641 |
},
|
642 |
"notification-url": "https://packagist.org/downloads/",
|
|
|
|
|
|
|
643 |
"license": [
|
644 |
"BSD-3-Clause"
|
645 |
],
|
655 |
"keywords": [
|
656 |
"timer"
|
657 |
],
|
658 |
+
"time": "2015-06-21 08:01:12"
|
659 |
},
|
660 |
{
|
661 |
"name": "phpunit/php-token-stream",
|
662 |
+
"version": "1.4.8",
|
663 |
"source": {
|
664 |
"type": "git",
|
665 |
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
666 |
+
"reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
|
667 |
},
|
668 |
"dist": {
|
669 |
"type": "zip",
|
670 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
|
671 |
+
"reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
|
672 |
"shasum": ""
|
673 |
},
|
674 |
"require": {
|
704 |
"keywords": [
|
705 |
"tokenizer"
|
706 |
],
|
707 |
+
"time": "2015-09-15 10:49:45"
|
708 |
},
|
709 |
{
|
710 |
"name": "phpunit/phpunit",
|
711 |
+
"version": "4.8.18",
|
712 |
"source": {
|
713 |
"type": "git",
|
714 |
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
715 |
+
"reference": "fa33d4ad96481b91df343d83e8c8aabed6b1dfd3"
|
716 |
},
|
717 |
"dist": {
|
718 |
"type": "zip",
|
719 |
+
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fa33d4ad96481b91df343d83e8c8aabed6b1dfd3",
|
720 |
+
"reference": "fa33d4ad96481b91df343d83e8c8aabed6b1dfd3",
|
721 |
"shasum": ""
|
722 |
},
|
723 |
"require": {
|
727 |
"ext-reflection": "*",
|
728 |
"ext-spl": "*",
|
729 |
"php": ">=5.3.3",
|
730 |
+
"phpspec/prophecy": "^1.3.1",
|
731 |
+
"phpunit/php-code-coverage": "~2.1",
|
732 |
"phpunit/php-file-iterator": "~1.4",
|
733 |
"phpunit/php-text-template": "~1.2",
|
734 |
+
"phpunit/php-timer": ">=1.0.6",
|
735 |
"phpunit/phpunit-mock-objects": "~2.3",
|
736 |
"sebastian/comparator": "~1.1",
|
737 |
"sebastian/diff": "~1.2",
|
738 |
+
"sebastian/environment": "~1.3",
|
739 |
"sebastian/exporter": "~1.2",
|
740 |
"sebastian/global-state": "~1.0",
|
741 |
"sebastian/version": "~1.0",
|
750 |
"type": "library",
|
751 |
"extra": {
|
752 |
"branch-alias": {
|
753 |
+
"dev-master": "4.8.x-dev"
|
754 |
}
|
755 |
},
|
756 |
"autoload": {
|
776 |
"testing",
|
777 |
"xunit"
|
778 |
],
|
779 |
+
"time": "2015-11-11 11:32:49"
|
780 |
},
|
781 |
{
|
782 |
"name": "phpunit/phpunit-mock-objects",
|
783 |
+
"version": "2.3.8",
|
784 |
"source": {
|
785 |
"type": "git",
|
786 |
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
|
787 |
+
"reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
|
788 |
},
|
789 |
"dist": {
|
790 |
"type": "zip",
|
791 |
+
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
|
792 |
+
"reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
|
793 |
"shasum": ""
|
794 |
},
|
795 |
"require": {
|
796 |
+
"doctrine/instantiator": "^1.0.2",
|
797 |
"php": ">=5.3.3",
|
798 |
+
"phpunit/php-text-template": "~1.2",
|
799 |
+
"sebastian/exporter": "~1.2"
|
800 |
},
|
801 |
"require-dev": {
|
802 |
"phpunit/phpunit": "~4.4"
|
832 |
"mock",
|
833 |
"xunit"
|
834 |
],
|
835 |
+
"time": "2015-10-02 06:51:40"
|
836 |
},
|
837 |
{
|
838 |
"name": "sebastian/comparator",
|
839 |
+
"version": "1.2.0",
|
840 |
"source": {
|
841 |
"type": "git",
|
842 |
"url": "https://github.com/sebastianbergmann/comparator.git",
|
843 |
+
"reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
|
844 |
},
|
845 |
"dist": {
|
846 |
"type": "zip",
|
847 |
+
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
|
848 |
+
"reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
|
849 |
"shasum": ""
|
850 |
},
|
851 |
"require": {
|
859 |
"type": "library",
|
860 |
"extra": {
|
861 |
"branch-alias": {
|
862 |
+
"dev-master": "1.2.x-dev"
|
863 |
}
|
864 |
},
|
865 |
"autoload": {
|
896 |
"compare",
|
897 |
"equality"
|
898 |
],
|
899 |
+
"time": "2015-07-26 15:48:44"
|
900 |
},
|
901 |
{
|
902 |
"name": "sebastian/diff",
|
952 |
},
|
953 |
{
|
954 |
"name": "sebastian/environment",
|
955 |
+
"version": "1.3.2",
|
956 |
"source": {
|
957 |
"type": "git",
|
958 |
"url": "https://github.com/sebastianbergmann/environment.git",
|
959 |
+
"reference": "6324c907ce7a52478eeeaede764f48733ef5ae44"
|
960 |
},
|
961 |
"dist": {
|
962 |
"type": "zip",
|
963 |
+
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44",
|
964 |
+
"reference": "6324c907ce7a52478eeeaede764f48733ef5ae44",
|
965 |
"shasum": ""
|
966 |
},
|
967 |
"require": {
|
998 |
"environment",
|
999 |
"hhvm"
|
1000 |
],
|
1001 |
+
"time": "2015-08-03 06:14:51"
|
1002 |
},
|
1003 |
{
|
1004 |
"name": "sebastian/exporter",
|
1005 |
+
"version": "1.2.1",
|
1006 |
"source": {
|
1007 |
"type": "git",
|
1008 |
"url": "https://github.com/sebastianbergmann/exporter.git",
|
1009 |
+
"reference": "7ae5513327cb536431847bcc0c10edba2701064e"
|
1010 |
},
|
1011 |
"dist": {
|
1012 |
"type": "zip",
|
1013 |
+
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
|
1014 |
+
"reference": "7ae5513327cb536431847bcc0c10edba2701064e",
|
1015 |
"shasum": ""
|
1016 |
},
|
1017 |
"require": {
|
1064 |
"export",
|
1065 |
"exporter"
|
1066 |
],
|
1067 |
+
"time": "2015-06-21 07:55:53"
|
1068 |
},
|
1069 |
{
|
1070 |
"name": "sebastian/global-state",
|
1071 |
+
"version": "1.1.1",
|
1072 |
"source": {
|
1073 |
"type": "git",
|
1074 |
"url": "https://github.com/sebastianbergmann/global-state.git",
|
1075 |
+
"reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
|
1076 |
},
|
1077 |
"dist": {
|
1078 |
"type": "zip",
|
1079 |
+
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
|
1080 |
+
"reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
|
1081 |
"shasum": ""
|
1082 |
},
|
1083 |
"require": {
|
1115 |
"keywords": [
|
1116 |
"global state"
|
1117 |
],
|
1118 |
+
"time": "2015-10-12 03:26:01"
|
1119 |
},
|
1120 |
{
|
1121 |
"name": "sebastian/recursion-context",
|
1122 |
+
"version": "1.0.1",
|
1123 |
"source": {
|
1124 |
"type": "git",
|
1125 |
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
1126 |
+
"reference": "994d4a811bafe801fb06dccbee797863ba2792ba"
|
1127 |
},
|
1128 |
"dist": {
|
1129 |
"type": "zip",
|
1130 |
+
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba",
|
1131 |
+
"reference": "994d4a811bafe801fb06dccbee797863ba2792ba",
|
1132 |
"shasum": ""
|
1133 |
},
|
1134 |
"require": {
|
1168 |
],
|
1169 |
"description": "Provides functionality to recursively process PHP variables",
|
1170 |
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
1171 |
+
"time": "2015-06-21 08:04:50"
|
1172 |
},
|
1173 |
{
|
1174 |
"name": "sebastian/version",
|
1175 |
+
"version": "1.0.6",
|
1176 |
"source": {
|
1177 |
"type": "git",
|
1178 |
"url": "https://github.com/sebastianbergmann/version.git",
|
1179 |
+
"reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
|
1180 |
},
|
1181 |
"dist": {
|
1182 |
"type": "zip",
|
1183 |
+
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
|
1184 |
+
"reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
|
1185 |
"shasum": ""
|
1186 |
},
|
1187 |
"type": "library",
|
1203 |
],
|
1204 |
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
|
1205 |
"homepage": "https://github.com/sebastianbergmann/version",
|
1206 |
+
"time": "2015-06-21 13:59:46"
|
1207 |
},
|
1208 |
{
|
1209 |
"name": "symfony/yaml",
|
1210 |
+
"version": "v2.7.6",
|
|
|
1211 |
"source": {
|
1212 |
"type": "git",
|
1213 |
+
"url": "https://github.com/symfony/yaml.git",
|
1214 |
+
"reference": "eca9019c88fbe250164affd107bc8057771f3f4d"
|
1215 |
},
|
1216 |
"dist": {
|
1217 |
"type": "zip",
|
1218 |
+
"url": "https://api.github.com/repos/symfony/yaml/zipball/eca9019c88fbe250164affd107bc8057771f3f4d",
|
1219 |
+
"reference": "eca9019c88fbe250164affd107bc8057771f3f4d",
|
1220 |
"shasum": ""
|
1221 |
},
|
1222 |
"require": {
|
1223 |
+
"php": ">=5.3.9"
|
|
|
|
|
|
|
1224 |
},
|
1225 |
"type": "library",
|
1226 |
"extra": {
|
1227 |
"branch-alias": {
|
1228 |
+
"dev-master": "2.7-dev"
|
1229 |
}
|
1230 |
},
|
1231 |
"autoload": {
|
1232 |
+
"psr-4": {
|
1233 |
"Symfony\\Component\\Yaml\\": ""
|
1234 |
}
|
1235 |
},
|
1249 |
],
|
1250 |
"description": "Symfony Yaml Component",
|
1251 |
"homepage": "https://symfony.com",
|
1252 |
+
"time": "2015-10-11 09:39:48"
|
1253 |
}
|
1254 |
],
|
1255 |
"aliases": [],
|
1257 |
"stability-flags": [],
|
1258 |
"prefer-stable": false,
|
1259 |
"prefer-lowest": false,
|
1260 |
+
"platform": {
|
1261 |
+
"php": ">=5.3.0"
|
1262 |
+
},
|
1263 |
"platform-dev": []
|
1264 |
}
|
config/Dockerfile-phantomjs
CHANGED
@@ -1,17 +1,5 @@
|
|
1 |
-
FROM
|
2 |
|
3 |
EXPOSE 8910
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
RUN apt-get update
|
8 |
-
RUN apt-get install -yqq curl libfreetype6 libfontconfig
|
9 |
-
# make ruby python git g++ flex bison gperf perl \
|
10 |
-
# libfontconfig1-dev libicu-dev libfreetype6 \
|
11 |
-
# libssl-dev libpng-dev libjpeg-dev
|
12 |
-
# RUN git clone git://github.com/ariya/phantomjs.git && cd phantomjs && ./build.sh && send "y\n"
|
13 |
-
|
14 |
-
RUN curl -sSL https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-$PHANTOM_JS_VERSION.tar.bz2 | tar xjC /
|
15 |
-
RUN ln -s phantomjs-$PHANTOM_JS_VERSION /phantomjs
|
16 |
-
|
17 |
-
CMD ["/phantomjs/bin/phantomjs", "--webdriver=8910"]
|
1 |
+
FROM servebox/phantomjs:latest
|
2 |
|
3 |
EXPOSE 8910
|
4 |
|
5 |
+
CMD ["phantomjs", "--webdriver=8910"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config/Dockerfile-wordpress-37
CHANGED
@@ -2,9 +2,9 @@ FROM wordpress:4
|
|
2 |
|
3 |
RUN docker-php-ext-install mysql
|
4 |
|
5 |
-
ENV WORDPRESS_VERSION 3.7.
|
6 |
-
ENV WORDPRESS_UPSTREAM_VERSION 3.7.
|
7 |
-
ENV WORDPRESS_SHA1
|
8 |
|
9 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
10 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
2 |
|
3 |
RUN docker-php-ext-install mysql
|
4 |
|
5 |
+
ENV WORDPRESS_VERSION 3.7.11
|
6 |
+
ENV WORDPRESS_UPSTREAM_VERSION 3.7.11
|
7 |
+
ENV WORDPRESS_SHA1 7b331b23756520beee83fa1530a1e43bf510b5c5
|
8 |
|
9 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
10 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
config/Dockerfile-wordpress-38
CHANGED
@@ -2,9 +2,9 @@ FROM wordpress:4
|
|
2 |
|
3 |
RUN docker-php-ext-install mysql
|
4 |
|
5 |
-
ENV WORDPRESS_VERSION 3.8.
|
6 |
-
ENV WORDPRESS_UPSTREAM_VERSION 3.8.
|
7 |
-
ENV WORDPRESS_SHA1
|
8 |
|
9 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
10 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
2 |
|
3 |
RUN docker-php-ext-install mysql
|
4 |
|
5 |
+
ENV WORDPRESS_VERSION 3.8.11
|
6 |
+
ENV WORDPRESS_UPSTREAM_VERSION 3.8.11
|
7 |
+
ENV WORDPRESS_SHA1 d58349c2aea01aa97ce4452bfe62347a9b82d28a
|
8 |
|
9 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
10 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
config/Dockerfile-wordpress-39
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
FROM wordpress:4
|
2 |
|
3 |
-
ENV WORDPRESS_VERSION 3.9.
|
4 |
-
ENV WORDPRESS_UPSTREAM_VERSION 3.9.
|
5 |
-
ENV WORDPRESS_SHA1
|
6 |
|
7 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
8 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
1 |
FROM wordpress:4
|
2 |
|
3 |
+
ENV WORDPRESS_VERSION 3.9.9
|
4 |
+
ENV WORDPRESS_UPSTREAM_VERSION 3.9.9
|
5 |
+
ENV WORDPRESS_SHA1 559edda1c178879d73ad234b098b8080506fbd71
|
6 |
|
7 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
8 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
config/Dockerfile-wordpress-40
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
FROM wordpress:4
|
2 |
|
3 |
-
ENV WORDPRESS_VERSION 4.0.
|
4 |
-
ENV WORDPRESS_UPSTREAM_VERSION 4.0.
|
5 |
-
ENV WORDPRESS_SHA1
|
6 |
|
7 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
8 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
1 |
FROM wordpress:4
|
2 |
|
3 |
+
ENV WORDPRESS_VERSION 4.0.8
|
4 |
+
ENV WORDPRESS_UPSTREAM_VERSION 4.0.8
|
5 |
+
ENV WORDPRESS_SHA1 6a3511025d9b9ccfec45efdad27d67a85ecce595
|
6 |
|
7 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
8 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
config/Dockerfile-wordpress-41
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
FROM wordpress:4
|
2 |
|
3 |
-
ENV WORDPRESS_VERSION 4.1.
|
4 |
-
ENV WORDPRESS_UPSTREAM_VERSION 4.1.
|
5 |
-
ENV WORDPRESS_SHA1
|
6 |
|
7 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
8 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
1 |
FROM wordpress:4
|
2 |
|
3 |
+
ENV WORDPRESS_VERSION 4.1.8
|
4 |
+
ENV WORDPRESS_UPSTREAM_VERSION 4.1.8
|
5 |
+
ENV WORDPRESS_SHA1 f3dc8f554312eeee5145c7eaaf85506e01a3d738
|
6 |
|
7 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
8 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
config/Dockerfile-wordpress-42
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
FROM wordpress:4
|
2 |
|
3 |
-
ENV WORDPRESS_VERSION 4.2.
|
4 |
-
ENV WORDPRESS_UPSTREAM_VERSION 4.2.
|
5 |
-
ENV WORDPRESS_SHA1
|
6 |
|
7 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
8 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
1 |
FROM wordpress:4
|
2 |
|
3 |
+
ENV WORDPRESS_VERSION 4.2.5
|
4 |
+
ENV WORDPRESS_UPSTREAM_VERSION 4.2.5
|
5 |
+
ENV WORDPRESS_SHA1 a8944f75f51b4687648a9a272e15dc17b9e25577
|
6 |
|
7 |
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
8 |
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
config/Dockerfile-wordpress-43
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM wordpress:4
|
2 |
+
|
3 |
+
ENV WORDPRESS_VERSION 4.3.1
|
4 |
+
ENV WORDPRESS_UPSTREAM_VERSION 4.3.1
|
5 |
+
ENV WORDPRESS_SHA1 b2e5652a6d2333cabe7b37459362a3e5b8b66221
|
6 |
+
|
7 |
+
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
|
8 |
+
RUN curl -o wordpress.tar.gz -sSL https://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz \
|
9 |
+
&& echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c - \
|
10 |
+
&& tar -xzf wordpress.tar.gz -C /usr/src/ \
|
11 |
+
&& rm wordpress.tar.gz \
|
12 |
+
&& chown -R www-data:www-data /usr/src/wordpress
|
13 |
+
|
14 |
+
ENTRYPOINT ["/entrypoint.sh"]
|
15 |
+
CMD ["apache2-foreground"]
|
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.
|
7 |
-
Stable tag: 1.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -16,14 +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 |
-
* Easy bulk compression of your existing media library.
|
21 |
* Compress individual images already in your media library.
|
|
|
|
|
|
|
22 |
* Multisite support with a single API key.
|
|
|
23 |
* See your usage directly from the media settings and during bulk compression.
|
24 |
-
*
|
25 |
-
*
|
26 |
-
* No file size
|
27 |
|
28 |
= How does it work? =
|
29 |
|
@@ -31,7 +34,7 @@ After you upload an image to your WordPress site, each resized image is uploaded
|
|
31 |
|
32 |
= Getting started =
|
33 |
|
34 |
-
Install this plugin and obtain your free API key from https://tinypng.com/developers.
|
35 |
|
36 |
= Multisite support =
|
37 |
|
@@ -79,40 +82,65 @@ The API key can also be configured in wp-config.php. You can add a TINY_API_KEY
|
|
79 |
|
80 |
== Frequently Asked Questions ==
|
81 |
|
82 |
-
= Q:
|
83 |
-
|
84 |
|
85 |
= Q: What happens to the compressed images when I uninstall the plugin? =
|
86 |
A: When you remove the TinyPNG plugin all your compressed images will remain compressed.
|
87 |
|
|
|
|
|
|
|
88 |
= Q: Is there a file size limit? =
|
89 |
A: No. There are no limitations on the size of the images you want to compress.
|
90 |
|
91 |
= Q: What happens when I reach my monthly compression limit? =
|
92 |
A: Everything will keep on working, but newly uploaded images will not be compressed. Of course we encourage everyone to sign up for a full subscription.
|
93 |
|
|
|
|
|
|
|
94 |
== Changelog ==
|
95 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
= 1.3.1 =
|
97 |
-
* Media library
|
98 |
|
99 |
= 1.3.0 =
|
100 |
-
* Improved bulk
|
101 |
-
*
|
|
|
102 |
|
103 |
= 1.2.1 =
|
104 |
-
*
|
105 |
|
106 |
= 1.2.0 =
|
107 |
-
*
|
108 |
-
*
|
109 |
-
*
|
110 |
-
*
|
|
|
111 |
|
112 |
= 1.1.0 =
|
113 |
* 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.
|
114 |
-
*
|
115 |
-
* Improved display of original sizes and compressed sizes showing the total size
|
116 |
|
117 |
= 1.0.0 =
|
118 |
* Initial version.
|
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.6.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 |
* Compress individual images already in your media library.
|
21 |
+
* Easy bulk compression of your existing media library.
|
22 |
+
* Resize large original images by setting a maximum width and/or height.
|
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 |
|
34 |
|
35 |
= Getting started =
|
36 |
|
37 |
+
Install this plugin and obtain your free API key from https://tinypng.com/developers. With a free account you can compress **roughly 100 images each month** (based on a regular WordPress installation). The exact number depends on the number of thumbnail sizes you use. You can change which of the generated thumbnail sizes should be compressed, because each one of them counts as a compression. And if you’re a heavy user, you can compress more images for a small additional fee per image.
|
38 |
|
39 |
= Multisite support =
|
40 |
|
82 |
|
83 |
== Frequently Asked Questions ==
|
84 |
|
85 |
+
= Q: How many images can I compress for free? =
|
86 |
+
In a default Wordpress installation you can compress around 100 images for free each month. WordPress creates different sized versions of your images which all have to be compressed. Some plugins even add more sizes, so take a look at the Settings > Media page before you start compressing.
|
87 |
|
88 |
= Q: What happens to the compressed images when I uninstall the plugin? =
|
89 |
A: When you remove the TinyPNG plugin all your compressed images will remain compressed.
|
90 |
|
91 |
+
= Q: I don't recall uploading 500 photos this month but my limit is already reached. How is this number calculated? =
|
92 |
+
A: When you upload an image to your website, WordPress will create different sized versions of it (see Settings > Media). The plugin will compress each of these sizes, so when you have 100 images and 5 different sizes you will do 500 compressions.
|
93 |
+
|
94 |
= Q: Is there a file size limit? =
|
95 |
A: No. There are no limitations on the size of the images you want to compress.
|
96 |
|
97 |
= Q: What happens when I reach my monthly compression limit? =
|
98 |
A: Everything will keep on working, but newly uploaded images will not be compressed. Of course we encourage everyone to sign up for a full subscription.
|
99 |
|
100 |
+
= Q: Can I compress all existing images in my media library? =
|
101 |
+
A: Yes! After installing the plugin, go to Media > Compress All Images, and click on the button to compress all uncompressed images in your media library.
|
102 |
+
|
103 |
== Changelog ==
|
104 |
|
105 |
+
= 1.6.0 =
|
106 |
+
* Improved compression status in the Media Library with new details window.
|
107 |
+
* Show total compression savings on the Media Settings page with link to bulk compression page when no images have been compressed yet.
|
108 |
+
* Moved Compress All Images from the Tools to the Media menu.
|
109 |
+
|
110 |
+
= 1.5.0 =
|
111 |
+
* Resize original images by specifying a maximum width and/or height. During compression your original images will also be scaled down if they are bigger.
|
112 |
+
* Support for the mobile WordPress app (thanks to David Goodwin).
|
113 |
+
|
114 |
+
= 1.4.0 =
|
115 |
+
* Indication of the number of images you can compress for free each month.
|
116 |
+
* Link to the Media Settings page from the plugin listing.
|
117 |
+
* Clarification that original images will be overwritten when compressed.
|
118 |
+
|
119 |
+
= 1.3.2 =
|
120 |
+
* Detect different thumbnail sizes with the same dimensions so they will not be compressed again.
|
121 |
+
|
122 |
= 1.3.1 =
|
123 |
+
* Media library shows files that are in the process of compression.
|
124 |
|
125 |
= 1.3.0 =
|
126 |
+
* Improved bulk compression from media library. Bulk compress your whole media library in one step.
|
127 |
+
* Better indication of image sizes that have been compressed.
|
128 |
+
* Detection of image sizes modified after compression by other plugins.
|
129 |
|
130 |
= 1.2.1 =
|
131 |
+
* Prevent compressing the original image if it is the only selected image size.
|
132 |
|
133 |
= 1.2.0 =
|
134 |
+
* Show if you entered a valid API key.
|
135 |
+
* Display connection status and number of compressions this month.
|
136 |
+
* Show a notice to administrators when the free compression limit is reached.
|
137 |
+
* The plugin now works when php's parse_ini_file is disabled on your host.
|
138 |
+
* Avoid warnings when no image thumbnail sizes have been selected.
|
139 |
|
140 |
= 1.1.0 =
|
141 |
* 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.
|
142 |
+
* Enable or disable compression of the original uploaded image.
|
143 |
+
* Improved display of original sizes and compressed sizes showing the total compression size in the Media Library list view.
|
144 |
|
145 |
= 1.0.0 =
|
146 |
* Initial version.
|
src/class-tiny-compress-curl.php
CHANGED
@@ -45,39 +45,50 @@ class Tiny_Compress_Curl extends Tiny_Compress {
|
|
45 |
$request = curl_init();
|
46 |
curl_setopt_array($request, $this->shrink_options($input));
|
47 |
|
48 |
-
$output_url = null;
|
49 |
$response = curl_exec($request);
|
50 |
-
if ($response === false) {
|
51 |
return array(array(
|
52 |
'error' => 'CurlError',
|
53 |
-
'message' => sprintf("%s [%d]", curl_error($request), curl_errno($request))
|
54 |
-
), null
|
55 |
);
|
56 |
}
|
57 |
|
58 |
$header_size = curl_getinfo($request, CURLINFO_HEADER_SIZE);
|
|
|
59 |
$headers = self::parse_headers(substr($response, 0, $header_size));
|
60 |
curl_close($request);
|
61 |
|
62 |
-
return array(self::decode(substr($response, $header_size)), $headers);
|
63 |
}
|
64 |
|
65 |
-
protected function output_options($url) {
|
66 |
-
|
67 |
CURLOPT_URL => $url,
|
68 |
CURLOPT_RETURNTRANSFER => true,
|
|
|
69 |
CURLOPT_CAINFO => self::get_ca_file(),
|
70 |
-
CURLOPT_SSL_VERIFYPEER => true
|
|
|
71 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
73 |
|
74 |
-
protected function output($url) {
|
75 |
$request = curl_init();
|
76 |
-
|
|
|
77 |
|
78 |
$response = curl_exec($request);
|
|
|
|
|
79 |
curl_close($request);
|
80 |
|
81 |
-
return $response;
|
82 |
}
|
83 |
}
|
45 |
$request = curl_init();
|
46 |
curl_setopt_array($request, $this->shrink_options($input));
|
47 |
|
|
|
48 |
$response = curl_exec($request);
|
49 |
+
if ($response === false || $response === null) {
|
50 |
return array(array(
|
51 |
'error' => 'CurlError',
|
52 |
+
'message' => sprintf("cURL: %s [%d]", curl_error($request), curl_errno($request))
|
53 |
+
), null, null
|
54 |
);
|
55 |
}
|
56 |
|
57 |
$header_size = curl_getinfo($request, CURLINFO_HEADER_SIZE);
|
58 |
+
$status_code = curl_getinfo($request, CURLINFO_HTTP_CODE);
|
59 |
$headers = self::parse_headers(substr($response, 0, $header_size));
|
60 |
curl_close($request);
|
61 |
|
62 |
+
return array(self::decode(substr($response, $header_size)), $headers, $status_code);
|
63 |
}
|
64 |
|
65 |
+
protected function output_options($url, $resize) {
|
66 |
+
$options = array(
|
67 |
CURLOPT_URL => $url,
|
68 |
CURLOPT_RETURNTRANSFER => true,
|
69 |
+
CURLOPT_HEADER => true,
|
70 |
CURLOPT_CAINFO => self::get_ca_file(),
|
71 |
+
CURLOPT_SSL_VERIFYPEER => true,
|
72 |
+
CURLOPT_USERAGENT => Tiny_WP_Base::plugin_identification() . ' cURL'
|
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
@@ -28,7 +28,10 @@ class Tiny_Compress_Fopen extends Tiny_Compress {
|
|
28 |
'Authorization: Basic ' . base64_encode('api:' . $this->api_key),
|
29 |
'User-Agent: ' . Tiny_WP_Base::plugin_identification() . ' fopen',
|
30 |
),
|
31 |
-
'content' => $input
|
|
|
|
|
|
|
32 |
),
|
33 |
'ssl' => array(
|
34 |
'cafile' => self::get_ca_file(),
|
@@ -41,11 +44,21 @@ class Tiny_Compress_Fopen extends Tiny_Compress {
|
|
41 |
$context = stream_context_create($this->shrink_options($input));
|
42 |
$request = @fopen(Tiny_Config::URL, 'r', false, $context);
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
if (!$request) {
|
|
|
|
|
45 |
return array(array(
|
46 |
'error' => 'FopenError',
|
47 |
-
'message' => 'Could not compress, enable cURL for detailed error'
|
48 |
-
),
|
49 |
);
|
50 |
}
|
51 |
|
@@ -54,11 +67,11 @@ class Tiny_Compress_Fopen extends Tiny_Compress {
|
|
54 |
$headers = self::parse_headers($meta_data['wrapper_data']);
|
55 |
fclose($request);
|
56 |
|
57 |
-
return array(self::decode($response), $headers);
|
58 |
}
|
59 |
|
60 |
-
protected function output_options() {
|
61 |
-
|
62 |
'http' => array(
|
63 |
'method' => 'GET',
|
64 |
),
|
@@ -67,23 +80,30 @@ class Tiny_Compress_Fopen extends Tiny_Compress {
|
|
67 |
'verify_peer' => true
|
68 |
)
|
69 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
}
|
71 |
|
72 |
-
protected function output($url) {
|
73 |
-
$context = stream_context_create($this->output_options());
|
74 |
$request = @fopen($url, 'rb', false, $context);
|
75 |
|
76 |
if ($request) {
|
77 |
$response = stream_get_contents($request);
|
|
|
|
|
78 |
fclose($request);
|
79 |
} else {
|
80 |
$response = '';
|
|
|
81 |
}
|
82 |
-
|
83 |
-
return $response;
|
84 |
-
}
|
85 |
-
|
86 |
-
public function get_status(&$details) {
|
87 |
-
return null;
|
88 |
}
|
89 |
}
|
28 |
'Authorization: Basic ' . base64_encode('api:' . $this->api_key),
|
29 |
'User-Agent: ' . Tiny_WP_Base::plugin_identification() . ' fopen',
|
30 |
),
|
31 |
+
'content' => $input,
|
32 |
+
'follow_location' => 0,
|
33 |
+
'max_redirects' => 1, // Necessary for PHP 5.2
|
34 |
+
'ignore_errors' => true // Apparently, a 201 is a failure
|
35 |
),
|
36 |
'ssl' => array(
|
37 |
'cafile' => self::get_ca_file(),
|
44 |
$context = stream_context_create($this->shrink_options($input));
|
45 |
$request = @fopen(Tiny_Config::URL, 'r', false, $context);
|
46 |
|
47 |
+
$status_code = null;
|
48 |
+
if ($http_response_header && count($http_response_header) > 0) {
|
49 |
+
$http_code_values = explode(' ', $http_response_header[0]);
|
50 |
+
if (count($http_code_values) > 1) {
|
51 |
+
$status_code = intval($http_code_values[1]);
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
if (!$request) {
|
56 |
+
$headers = self::parse_headers($http_response_header);
|
57 |
+
|
58 |
return array(array(
|
59 |
'error' => 'FopenError',
|
60 |
+
'message' => 'Could not compress, enable cURL for detailed error',
|
61 |
+
), $headers, $status_code
|
62 |
);
|
63 |
}
|
64 |
|
67 |
$headers = self::parse_headers($meta_data['wrapper_data']);
|
68 |
fclose($request);
|
69 |
|
70 |
+
return array(self::decode($response), $headers, $status_code);
|
71 |
}
|
72 |
|
73 |
+
protected function output_options($resize) {
|
74 |
+
$options = array(
|
75 |
'http' => array(
|
76 |
'method' => 'GET',
|
77 |
),
|
80 |
'verify_peer' => true
|
81 |
)
|
82 |
);
|
83 |
+
if ($resize) {
|
84 |
+
$options['http']['header'] = array(
|
85 |
+
'Authorization: Basic ' . base64_encode('api:' . $this->api_key),
|
86 |
+
'Content-Type: application/json',
|
87 |
+
'User-Agent: ' . Tiny_WP_Base::plugin_identification() . ' fopen'
|
88 |
+
);
|
89 |
+
$options['http']['content'] = json_encode(array('resize' => $resize));
|
90 |
+
}
|
91 |
+
return $options;
|
92 |
}
|
93 |
|
94 |
+
protected function output($url, $resize) {
|
95 |
+
$context = stream_context_create($this->output_options($resize));
|
96 |
$request = @fopen($url, 'rb', false, $context);
|
97 |
|
98 |
if ($request) {
|
99 |
$response = stream_get_contents($request);
|
100 |
+
$meta_data = stream_get_meta_data($request);
|
101 |
+
$headers = self::parse_headers($meta_data['wrapper_data']);
|
102 |
fclose($request);
|
103 |
} else {
|
104 |
$response = '';
|
105 |
+
$headers = array();
|
106 |
}
|
107 |
+
return array($response, $headers);
|
|
|
|
|
|
|
|
|
|
|
108 |
}
|
109 |
}
|
src/class-tiny-compress.php
CHANGED
@@ -41,20 +41,20 @@ 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) = $this->shrink(null);
|
48 |
|
49 |
$this->call_after_compress_callback($details, $headers);
|
50 |
-
if (
|
51 |
return true;
|
52 |
} else {
|
53 |
return false;
|
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
|
|
|
|
|
|
|
|
|
76 |
}
|
77 |
-
|
|
|
78 |
file_put_contents($file, $output);
|
|
|
|
|
|
|
|
|
|
|
79 |
return $details;
|
80 |
}
|
81 |
|
@@ -102,9 +114,33 @@ abstract class Tiny_Compress {
|
|
102 |
protected static function decode($text) {
|
103 |
$result = json_decode($text, true);
|
104 |
if ($result === null) {
|
105 |
-
throw new Tiny_Exception('
|
|
|
|
|
|
|
106 |
}
|
107 |
return $result;
|
108 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
}
|
110 |
|
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);
|
48 |
|
49 |
$this->call_after_compress_callback($details, $headers);
|
50 |
+
if ($status_code >= 400 && $status_code < 500 && $status_code != 401) {
|
51 |
return true;
|
52 |
} else {
|
53 |
return false;
|
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 |
|
114 |
protected static function decode($text) {
|
115 |
$result = json_decode($text, true);
|
116 |
if ($result === null) {
|
117 |
+
throw new Tiny_Exception(sprintf('JSON: %s [%d]',
|
118 |
+
PHP_VERSION_ID >= 50500 ? json_last_error_msg() : 'Unknown error',
|
119 |
+
PHP_VERSION_ID >= 50300 ? json_last_error() : 'Error'),
|
120 |
+
'JsonError');
|
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
@@ -23,6 +23,7 @@ class Tiny_Metadata {
|
|
23 |
const ORIGINAL = 0;
|
24 |
|
25 |
private $id;
|
|
|
26 |
private $values;
|
27 |
private $filenames;
|
28 |
private $urls;
|
@@ -34,7 +35,7 @@ class Tiny_Metadata {
|
|
34 |
$wp_metadata = wp_get_attachment_metadata($id);
|
35 |
}
|
36 |
$this->parse_wp_metadata($wp_metadata);
|
37 |
-
$this->values = get_post_meta($id, self::META_KEY, true);
|
38 |
if (!is_array($this->values)) {
|
39 |
$this->values = array();
|
40 |
}
|
@@ -56,27 +57,36 @@ class Tiny_Metadata {
|
|
56 |
$url_prefix .= $path_info['dirname'] .'/';
|
57 |
}
|
58 |
|
|
|
|
|
59 |
$this->filenames[self::ORIGINAL] = "$path_prefix${path_info['basename']}";
|
60 |
$this->urls[self::ORIGINAL] = "$url_prefix${path_info['basename']}";
|
|
|
|
|
61 |
if (isset($wp_metadata['sizes']) && is_array($wp_metadata['sizes'])) {
|
62 |
foreach ($wp_metadata['sizes'] as $size => $info) {
|
63 |
-
$
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
66 |
}
|
67 |
}
|
68 |
|
69 |
-
public function
|
70 |
-
|
|
|
|
|
|
|
|
|
|
|
71 |
}
|
72 |
|
73 |
-
public function
|
74 |
-
$
|
75 |
-
'input' => array('size' => $response['input']['size']),
|
76 |
-
'output' => array('size' => $response['output']['size']),
|
77 |
-
'end' => time()
|
78 |
-
);
|
79 |
-
$this->values[$size] = array_merge($this->values[$size], $data);
|
80 |
}
|
81 |
|
82 |
public function add_request($size=self::ORIGINAL) {
|
@@ -85,6 +95,11 @@ class Tiny_Metadata {
|
|
85 |
);
|
86 |
}
|
87 |
|
|
|
|
|
|
|
|
|
|
|
88 |
public function add_exception($exception, $size=self::ORIGINAL) {
|
89 |
$this->values[$size] = array(
|
90 |
'error' => $exception->get_error(),
|
@@ -97,6 +112,10 @@ class Tiny_Metadata {
|
|
97 |
return $this->id;
|
98 |
}
|
99 |
|
|
|
|
|
|
|
|
|
100 |
public function get_filename($size=self::ORIGINAL) {
|
101 |
return isset($this->filenames[$size]) ? $this->filenames[$size] : null;
|
102 |
}
|
@@ -109,10 +128,30 @@ class Tiny_Metadata {
|
|
109 |
return isset($this->values[$size]) ? $this->values[$size] : null;
|
110 |
}
|
111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
public function is_compressed($size=self::ORIGINAL) {
|
113 |
-
$
|
114 |
-
|
115 |
-
&& file_exists($filename) && filesize($filename) == $this->values[$size]['output']['size'];
|
116 |
}
|
117 |
|
118 |
public function is_compressing($size=self::ORIGINAL) {
|
@@ -120,23 +159,60 @@ class Tiny_Metadata {
|
|
120 |
return isset($meta) && isset($meta['start']) && !isset($meta['output']);
|
121 |
}
|
122 |
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
public function get_sizes() {
|
124 |
return array_keys($this->filenames);
|
125 |
}
|
126 |
|
|
|
|
|
|
|
|
|
127 |
public function get_success_sizes() {
|
128 |
return array_filter(array_keys($this->values), array($this, 'is_compressed'));
|
129 |
}
|
130 |
|
131 |
-
public function
|
132 |
-
$sizes = array_intersect($this->get_sizes(), $
|
133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
}
|
135 |
|
136 |
public function get_in_progress_sizes() {
|
137 |
return array_filter(array_keys($this->values), array($this, 'is_compressing'));
|
138 |
}
|
139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
public function get_latest_error() {
|
141 |
$last_time = null;
|
142 |
$message = null;
|
@@ -164,4 +240,8 @@ class Tiny_Metadata {
|
|
164 |
}
|
165 |
return $result;
|
166 |
}
|
|
|
|
|
|
|
|
|
167 |
}
|
23 |
const ORIGINAL = 0;
|
24 |
|
25 |
private $id;
|
26 |
+
private $name;
|
27 |
private $values;
|
28 |
private $filenames;
|
29 |
private $urls;
|
35 |
$wp_metadata = wp_get_attachment_metadata($id);
|
36 |
}
|
37 |
$this->parse_wp_metadata($wp_metadata);
|
38 |
+
$this->values = get_post_meta($this->id, self::META_KEY, true);
|
39 |
if (!is_array($this->values)) {
|
40 |
$this->values = array();
|
41 |
}
|
57 |
$url_prefix .= $path_info['dirname'] .'/';
|
58 |
}
|
59 |
|
60 |
+
$this->name = $path_info['basename'];
|
61 |
+
|
62 |
$this->filenames[self::ORIGINAL] = "$path_prefix${path_info['basename']}";
|
63 |
$this->urls[self::ORIGINAL] = "$url_prefix${path_info['basename']}";
|
64 |
+
|
65 |
+
$unique_sizes = array();
|
66 |
if (isset($wp_metadata['sizes']) && is_array($wp_metadata['sizes'])) {
|
67 |
foreach ($wp_metadata['sizes'] as $size => $info) {
|
68 |
+
$filename = $info['file'];
|
69 |
+
|
70 |
+
if (!isset($unique_sizes[$filename])) {
|
71 |
+
$this->filenames[$size] = "$path_prefix$filename";
|
72 |
+
$this->urls[$size] = "$url_prefix$filename";
|
73 |
+
$unique_sizes[$filename] = true;
|
74 |
+
}
|
75 |
}
|
76 |
}
|
77 |
}
|
78 |
|
79 |
+
public function update_wp_metadata($wp_metadata) {
|
80 |
+
$tiny_metadata = $this->get_value();
|
81 |
+
if (isset($tiny_metadata) && isset($tiny_metadata['output']) && isset($tiny_metadata['output']['width']) && isset($tiny_metadata['output']['height'])) {
|
82 |
+
$wp_metadata['width'] = $tiny_metadata['output']['width'];
|
83 |
+
$wp_metadata['height'] = $tiny_metadata['output']['height'];
|
84 |
+
}
|
85 |
+
return $wp_metadata;
|
86 |
}
|
87 |
|
88 |
+
public function update() {
|
89 |
+
update_post_meta($this->id, self::META_KEY, $this->values);
|
|
|
|
|
|
|
|
|
|
|
90 |
}
|
91 |
|
92 |
public function add_request($size=self::ORIGINAL) {
|
95 |
);
|
96 |
}
|
97 |
|
98 |
+
public function add_response($response, $size=self::ORIGINAL) {
|
99 |
+
$response['end'] = time();
|
100 |
+
$this->values[$size] = array_merge($this->values[$size], $response);
|
101 |
+
}
|
102 |
+
|
103 |
public function add_exception($exception, $size=self::ORIGINAL) {
|
104 |
$this->values[$size] = array(
|
105 |
'error' => $exception->get_error(),
|
112 |
return $this->id;
|
113 |
}
|
114 |
|
115 |
+
public function get_name() {
|
116 |
+
return $this->name;
|
117 |
+
}
|
118 |
+
|
119 |
public function get_filename($size=self::ORIGINAL) {
|
120 |
return isset($this->filenames[$size]) ? $this->filenames[$size] : null;
|
121 |
}
|
128 |
return isset($this->values[$size]) ? $this->values[$size] : null;
|
129 |
}
|
130 |
|
131 |
+
public function get_end_time($size=self::ORIGINAL) {
|
132 |
+
$value = $this->get_value($size);
|
133 |
+
if (array_key_exists("end", $value)) {
|
134 |
+
return $value["end"];
|
135 |
+
} else if (array_key_exists("timestamp", $value)) {
|
136 |
+
return $value["timestamp"];
|
137 |
+
}
|
138 |
+
}
|
139 |
+
|
140 |
+
public function has_been_compressed($size=self::ORIGINAL) {
|
141 |
+
return isset($this->values[$size]) && isset($this->values[$size]['output']);
|
142 |
+
}
|
143 |
+
|
144 |
+
public function exists($size=self::ORIGINAL) {
|
145 |
+
return file_exists($this->get_filename($size));
|
146 |
+
}
|
147 |
+
|
148 |
+
public function still_exists($size=self::ORIGINAL) {
|
149 |
+
return $this->has_been_compressed($size) && file_exists($this->get_filename($size));
|
150 |
+
}
|
151 |
+
|
152 |
public function is_compressed($size=self::ORIGINAL) {
|
153 |
+
return $this->has_been_compressed($size) && $this->still_exists($size)
|
154 |
+
&& filesize($this->get_filename($size)) == $this->values[$size]['output']['size'];
|
|
|
155 |
}
|
156 |
|
157 |
public function is_compressing($size=self::ORIGINAL) {
|
159 |
return isset($meta) && isset($meta['start']) && !isset($meta['output']);
|
160 |
}
|
161 |
|
162 |
+
public function is_resized($size=self::ORIGINAL) {
|
163 |
+
$meta = $this->values[$size];
|
164 |
+
return isset($meta) && isset($meta['output']) && isset($meta['output']['resized'])
|
165 |
+
&& $meta['output']['resized'];
|
166 |
+
}
|
167 |
+
|
168 |
public function get_sizes() {
|
169 |
return array_keys($this->filenames);
|
170 |
}
|
171 |
|
172 |
+
public function get_compressed_sizes() {
|
173 |
+
return array_filter(array_keys($this->values), array($this, 'has_been_compressed'));
|
174 |
+
}
|
175 |
+
|
176 |
public function get_success_sizes() {
|
177 |
return array_filter(array_keys($this->values), array($this, 'is_compressed'));
|
178 |
}
|
179 |
|
180 |
+
public function get_uncompressed_sizes($active_tinify_sizes) {
|
181 |
+
$sizes = array_intersect($this->get_sizes(), $active_tinify_sizes);
|
182 |
+
$uncompressed = array_diff($sizes, $this->get_success_sizes());
|
183 |
+
return array_filter($uncompressed, array($this, 'exists'));
|
184 |
+
}
|
185 |
+
|
186 |
+
public function get_not_compressed_active_sizes($active_tinify_sizes) {
|
187 |
+
$sizes = array_intersect($this->get_sizes(), $active_tinify_sizes);
|
188 |
+
return array_diff($sizes, $this->get_compressed_sizes());
|
189 |
}
|
190 |
|
191 |
public function get_in_progress_sizes() {
|
192 |
return array_filter(array_keys($this->values), array($this, 'is_compressing'));
|
193 |
}
|
194 |
|
195 |
+
public function get_success_count() {
|
196 |
+
return count($this->get_success_sizes());
|
197 |
+
}
|
198 |
+
|
199 |
+
public function get_in_progress_count() {
|
200 |
+
return count($this->get_in_progress_sizes());
|
201 |
+
}
|
202 |
+
|
203 |
+
public function get_compressed_count() {
|
204 |
+
return count($this->get_compressed_sizes());
|
205 |
+
}
|
206 |
+
|
207 |
+
public function get_missing_count() {
|
208 |
+
return count($this->get_compressed_sizes()) -
|
209 |
+
count(array_filter($this->get_compressed_sizes(), array($this, 'still_exists')));
|
210 |
+
}
|
211 |
+
|
212 |
+
public function get_modified_count() {
|
213 |
+
return count($this->get_compressed_sizes()) - $this->get_success_count() - $this->get_missing_count();
|
214 |
+
}
|
215 |
+
|
216 |
public function get_latest_error() {
|
217 |
$last_time = null;
|
218 |
$message = null;
|
240 |
}
|
241 |
return $result;
|
242 |
}
|
243 |
+
|
244 |
+
public function is_resizable($size) {
|
245 |
+
return $size === self::ORIGINAL;
|
246 |
+
}
|
247 |
}
|
src/class-tiny-plugin.php
CHANGED
@@ -21,8 +21,10 @@
|
|
21 |
class Tiny_Plugin extends Tiny_WP_Base {
|
22 |
const MEDIA_COLUMN = self::NAME;
|
23 |
const MEDIA_COLUMN_HEADER = 'Compression';
|
|
|
24 |
|
25 |
private $settings;
|
|
|
26 |
|
27 |
public static function jpeg_quality() {
|
28 |
return 95;
|
@@ -54,14 +56,22 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
54 |
add_action('wp_ajax_tiny_compress_image', $this->get_method('compress_image'));
|
55 |
add_action('admin_action_tiny_bulk_compress', $this->get_method('bulk_compress'));
|
56 |
add_action('admin_enqueue_scripts', $this->get_method('enqueue_scripts'));
|
|
|
|
|
|
|
57 |
}
|
58 |
|
59 |
public function admin_menu() {
|
60 |
-
|
61 |
self::translate('Compress JPEG & PNG Images'), self::translate('Compress All Images'),
|
62 |
'upload_files', 'tiny-bulk-compress', $this->get_method('bulk_compress_page')
|
63 |
);
|
|
|
64 |
|
|
|
|
|
|
|
|
|
65 |
}
|
66 |
|
67 |
public function enqueue_scripts($hook) {
|
@@ -72,7 +82,7 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
72 |
wp_register_script($handle, plugins_url('/scripts/admin.js', __FILE__),
|
73 |
array(), self::plugin_version(), true);
|
74 |
|
75 |
-
//
|
76 |
wp_localize_script($handle, 'tinyCompress', array(
|
77 |
'nonce' => wp_create_nonce('tiny-compress'),
|
78 |
'wpVersion' => self::wp_version(),
|
@@ -94,36 +104,42 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
94 |
$tiny_metadata = new Tiny_Metadata($attachment_id, $metadata);
|
95 |
|
96 |
if ($this->settings->get_compressor() === null || strpos($mime_type, 'image/') !== 0) {
|
97 |
-
return $
|
98 |
}
|
99 |
|
100 |
$success = 0;
|
101 |
$failed = 0;
|
102 |
|
103 |
$compressor = $this->settings->get_compressor();
|
104 |
-
$
|
105 |
-
$
|
106 |
-
|
|
|
107 |
try {
|
108 |
-
$tiny_metadata->add_request($
|
109 |
$tiny_metadata->update();
|
110 |
|
111 |
-
$
|
112 |
-
$tiny_metadata->
|
|
|
|
|
|
|
113 |
$success++;
|
114 |
} catch (Tiny_Exception $e) {
|
115 |
-
$tiny_metadata->add_exception($e, $
|
|
|
116 |
$failed++;
|
117 |
}
|
118 |
}
|
119 |
-
$tiny_metadata->update();
|
120 |
|
121 |
return array($tiny_metadata, array('success' => $success, 'failed' => $failed));
|
122 |
}
|
123 |
|
124 |
public function compress_attachment($metadata, $attachment_id) {
|
125 |
-
|
126 |
-
|
|
|
|
|
127 |
}
|
128 |
|
129 |
public function compress_image() {
|
@@ -150,6 +166,8 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
150 |
}
|
151 |
|
152 |
list($tiny_metadata, $result) = $this->compress($metadata, $id);
|
|
|
|
|
153 |
if ($json) {
|
154 |
$result['message'] = $tiny_metadata->get_latest_error();
|
155 |
$result['status'] = $this->settings->get_status();
|
@@ -173,7 +191,7 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
173 |
wp_redirect(add_query_arg(
|
174 |
'_wpnonce',
|
175 |
wp_create_nonce('tiny-bulk-compress'),
|
176 |
-
admin_url("
|
177 |
));
|
178 |
exit();
|
179 |
}
|
@@ -190,30 +208,19 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
190 |
}
|
191 |
|
192 |
private function render_compress_details($tiny_metadata) {
|
193 |
-
$
|
194 |
-
$
|
195 |
-
$
|
196 |
-
$
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
echo '<button type="button" class="tiny-compress" data-id="' . $tiny_metadata->get_id() . '">' .
|
205 |
-
self::translate_escape('Compress') . '</button>';
|
206 |
-
echo '<div class="spinner hidden"></div>';
|
207 |
-
} elseif ($progress > 0) {
|
208 |
-
printf(self::translate_escape('Compressing %d sizes...'), count($this->settings->get_tinify_sizes()));
|
209 |
} else {
|
210 |
-
|
211 |
-
$savings = $tiny_metadata->get_savings();
|
212 |
-
if ($savings['count'] > 0) {
|
213 |
-
echo '<br/>';
|
214 |
-
echo self::translate_escape('Total size') . ': ' . size_format($savings['input']) . '<br/>';
|
215 |
-
echo self::translate_escape('Compressed size') . ': ' . size_format($savings['output']);
|
216 |
-
}
|
217 |
}
|
218 |
}
|
219 |
|
@@ -224,18 +231,29 @@ class Tiny_Plugin extends Tiny_WP_Base {
|
|
224 |
echo '<h2>' . self::translate('Compress JPEG & PNG Images') . '</h2>';
|
225 |
if (empty($_POST['tiny-bulk-compress']) && empty($_REQUEST['ids'])) {
|
226 |
$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);
|
227 |
-
$
|
|
|
228 |
|
229 |
-
echo '<p>'
|
230 |
-
echo self::translate_escape("
|
231 |
-
echo
|
232 |
-
echo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
|
234 |
echo '<form method="POST" action="?page=tiny-bulk-compress">';
|
235 |
echo '<input type="hidden" name="_wpnonce" value="' . wp_create_nonce('tiny-bulk-compress') . '">';
|
236 |
echo '<input type="hidden" name="tiny-bulk-compress" value="1">';
|
237 |
-
echo '<p
|
238 |
-
|
|
|
|
|
|
|
239 |
echo '</form>';
|
240 |
} else {
|
241 |
check_admin_referer('tiny-bulk-compress');
|
21 |
class Tiny_Plugin extends Tiny_WP_Base {
|
22 |
const MEDIA_COLUMN = self::NAME;
|
23 |
const MEDIA_COLUMN_HEADER = 'Compression';
|
24 |
+
const DATETIME_FORMAT = 'Y-m-d G:i:s';
|
25 |
|
26 |
private $settings;
|
27 |
+
private $twig;
|
28 |
|
29 |
public static function jpeg_quality() {
|
30 |
return 95;
|
56 |
add_action('wp_ajax_tiny_compress_image', $this->get_method('compress_image'));
|
57 |
add_action('admin_action_tiny_bulk_compress', $this->get_method('bulk_compress'));
|
58 |
add_action('admin_enqueue_scripts', $this->get_method('enqueue_scripts'));
|
59 |
+
$plugin = plugin_basename(dirname(dirname(__FILE__)) . '/tiny-compress-images.php');
|
60 |
+
add_filter("plugin_action_links_$plugin", $this->get_method('add_plugin_links'));
|
61 |
+
add_thickbox();
|
62 |
}
|
63 |
|
64 |
public function admin_menu() {
|
65 |
+
add_media_page(
|
66 |
self::translate('Compress JPEG & PNG Images'), self::translate('Compress All Images'),
|
67 |
'upload_files', 'tiny-bulk-compress', $this->get_method('bulk_compress_page')
|
68 |
);
|
69 |
+
}
|
70 |
|
71 |
+
public function add_plugin_links($current_links) {
|
72 |
+
$additional[] = sprintf('<a href="options-media.php#%s">%s</a>', self::NAME,
|
73 |
+
self::translate_escape('Settings'));
|
74 |
+
return array_merge($additional, $current_links);
|
75 |
}
|
76 |
|
77 |
public function enqueue_scripts($hook) {
|
82 |
wp_register_script($handle, plugins_url('/scripts/admin.js', __FILE__),
|
83 |
array(), self::plugin_version(), true);
|
84 |
|
85 |
+
// WordPress < 3.3 does not handle multidimensional arrays
|
86 |
wp_localize_script($handle, 'tinyCompress', array(
|
87 |
'nonce' => wp_create_nonce('tiny-compress'),
|
88 |
'wpVersion' => self::wp_version(),
|
104 |
$tiny_metadata = new Tiny_Metadata($attachment_id, $metadata);
|
105 |
|
106 |
if ($this->settings->get_compressor() === null || strpos($mime_type, 'image/') !== 0) {
|
107 |
+
return array($tiny_metadata, null);
|
108 |
}
|
109 |
|
110 |
$success = 0;
|
111 |
$failed = 0;
|
112 |
|
113 |
$compressor = $this->settings->get_compressor();
|
114 |
+
$active_tinify_sizes = $this->settings->get_active_tinify_sizes();
|
115 |
+
$uncompressed_sizes = $tiny_metadata->get_uncompressed_sizes($active_tinify_sizes);
|
116 |
+
|
117 |
+
foreach ($uncompressed_sizes as $uncompressed_size) {
|
118 |
try {
|
119 |
+
$tiny_metadata->add_request($uncompressed_size);
|
120 |
$tiny_metadata->update();
|
121 |
|
122 |
+
$resize = $tiny_metadata->is_resizable($uncompressed_size) ? $this->settings->get_resize_options() : false;
|
123 |
+
$response = $compressor->compress_file($tiny_metadata->get_filename($uncompressed_size), $resize);
|
124 |
+
|
125 |
+
$tiny_metadata->add_response($response, $uncompressed_size);
|
126 |
+
$tiny_metadata->update();
|
127 |
$success++;
|
128 |
} catch (Tiny_Exception $e) {
|
129 |
+
$tiny_metadata->add_exception($e, $uncompressed_size);
|
130 |
+
$tiny_metadata->update();
|
131 |
$failed++;
|
132 |
}
|
133 |
}
|
|
|
134 |
|
135 |
return array($tiny_metadata, array('success' => $success, 'failed' => $failed));
|
136 |
}
|
137 |
|
138 |
public function compress_attachment($metadata, $attachment_id) {
|
139 |
+
if (!empty($metadata)) {
|
140 |
+
list($tiny_metadata, $result) = $this->compress($metadata, $attachment_id);
|
141 |
+
return $tiny_metadata->update_wp_metadata($metadata);
|
142 |
+
}
|
143 |
}
|
144 |
|
145 |
public function compress_image() {
|
166 |
}
|
167 |
|
168 |
list($tiny_metadata, $result) = $this->compress($metadata, $id);
|
169 |
+
wp_update_attachment_metadata($id, $tiny_metadata->update_wp_metadata($metadata));
|
170 |
+
|
171 |
if ($json) {
|
172 |
$result['message'] = $tiny_metadata->get_latest_error();
|
173 |
$result['status'] = $this->settings->get_status();
|
191 |
wp_redirect(add_query_arg(
|
192 |
'_wpnonce',
|
193 |
wp_create_nonce('tiny-bulk-compress'),
|
194 |
+
admin_url("upload.php?page=tiny-bulk-compress&ids=$ids")
|
195 |
));
|
196 |
exit();
|
197 |
}
|
208 |
}
|
209 |
|
210 |
private function render_compress_details($tiny_metadata) {
|
211 |
+
$active = $this->settings->get_active_tinify_sizes();
|
212 |
+
$uncompressed = $tiny_metadata->get_uncompressed_sizes($active);
|
213 |
+
$not_compressed_active = count($tiny_metadata->get_not_compressed_active_sizes($active));
|
214 |
+
$savings = $tiny_metadata->get_savings();
|
215 |
+
$error = $tiny_metadata->get_latest_error();
|
216 |
+
$missing = $tiny_metadata->get_missing_count();
|
217 |
+
$modified = $tiny_metadata->get_modified_count();
|
218 |
+
$compressing = (count($uncompressed) > 0) ? count($uncompressed) : count($active);
|
219 |
+
|
220 |
+
if ($tiny_metadata->get_in_progress_count() > 0) {
|
221 |
+
include(dirname(__FILE__) . '/views/compress-details-processing.php');
|
|
|
|
|
|
|
|
|
|
|
222 |
} else {
|
223 |
+
include(dirname(__FILE__) . '/views/compress-details.php');
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
}
|
225 |
}
|
226 |
|
231 |
echo '<h2>' . self::translate('Compress JPEG & PNG Images') . '</h2>';
|
232 |
if (empty($_POST['tiny-bulk-compress']) && empty($_REQUEST['ids'])) {
|
233 |
$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);
|
234 |
+
$image_count = $result[0]['count'];
|
235 |
+
$sizes_count = count($this->settings->get_active_tinify_sizes());
|
236 |
|
237 |
+
echo '<p>';
|
238 |
+
echo self::translate_escape("Use this tool to compress all images in your media library") . '. ';
|
239 |
+
echo self::translate_escape("Only images that have not been compressed will be compressed") . '. ';
|
240 |
+
echo '</p>';
|
241 |
+
echo '<p>';
|
242 |
+
echo 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) . '. ';
|
243 |
+
echo sprintf(self::translate_escape('This results in %d compressions at most'), $image_count*$sizes_count) . '. ';
|
244 |
+
echo '</p>';
|
245 |
+
echo '<p>';
|
246 |
+
echo self::translate_escape("To begin, just press the button below") . '. ';
|
247 |
+
echo '</p>';
|
248 |
|
249 |
echo '<form method="POST" action="?page=tiny-bulk-compress">';
|
250 |
echo '<input type="hidden" name="_wpnonce" value="' . wp_create_nonce('tiny-bulk-compress') . '">';
|
251 |
echo '<input type="hidden" name="tiny-bulk-compress" value="1">';
|
252 |
+
echo '<p>';
|
253 |
+
echo '<button class="button button-primary button-large" type="submit">';
|
254 |
+
echo self::translate_escape('Compress All Images');
|
255 |
+
echo '</button>';
|
256 |
+
echo '</p>';
|
257 |
echo '</form>';
|
258 |
} else {
|
259 |
check_admin_referer('tiny-bulk-compress');
|
src/class-tiny-settings.php
CHANGED
@@ -31,14 +31,25 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
31 |
$this->notices = new Tiny_Notices();
|
32 |
}
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
public function admin_init() {
|
35 |
if (current_user_can('manage_options') && !$this->get_api_key()) {
|
36 |
$link = sprintf('<a href="options-media.php#%s">%s</a>', self::NAME,
|
37 |
self::translate_escape('Please fill in an API key to start compressing images'));
|
38 |
$this->notices->show('setting', $link, 'error', false);
|
39 |
}
|
40 |
-
|
41 |
-
$this->
|
42 |
} catch (Tiny_Exception $e) {
|
43 |
$this->notices->show('compressor_exception', self::translate_escape($e->getMessage()), 'error', false);
|
44 |
}
|
@@ -54,11 +65,26 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
54 |
register_setting('media', $field);
|
55 |
add_settings_field($field, self::translate('File compression'), $this->get_method('render_sizes'), 'media', $section);
|
56 |
|
|
|
|
|
|
|
|
|
57 |
$field = self::get_prefixed_name('status');
|
58 |
register_setting('media', $field);
|
59 |
add_settings_field($field, self::translate('Connection status'), $this->get_method('render_pending_status'), 'media', $section);
|
60 |
|
|
|
|
|
|
|
|
|
|
|
61 |
add_action('wp_ajax_tiny_compress_status', $this->get_method('connection_status'));
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
}
|
63 |
|
64 |
public function connection_status() {
|
@@ -66,6 +92,11 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
66 |
exit();
|
67 |
}
|
68 |
|
|
|
|
|
|
|
|
|
|
|
69 |
public function get_compressor() {
|
70 |
return $this->compressor;
|
71 |
}
|
@@ -134,7 +165,7 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
134 |
return $this->sizes;
|
135 |
}
|
136 |
|
137 |
-
public function
|
138 |
if (is_array($this->tinify_sizes)) {
|
139 |
return $this->tinify_sizes;
|
140 |
}
|
@@ -148,6 +179,32 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
148 |
return $this->tinify_sizes;
|
149 |
}
|
150 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
public function render_section() {
|
152 |
echo '<span id="' . self::NAME . '"></span>';
|
153 |
}
|
@@ -166,32 +223,114 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
166 |
if (empty($key)) {
|
167 |
printf(self::translate_escape('Visit %s to get an API key') . '.', $link);
|
168 |
} else {
|
169 |
-
printf(self::translate_escape('Visit %s to view
|
170 |
}
|
171 |
echo '</p>';
|
172 |
}
|
173 |
|
174 |
public function render_sizes() {
|
175 |
-
echo '<p>'
|
176 |
-
echo self::translate_escape('
|
177 |
-
|
178 |
-
|
|
|
179 |
foreach ($this->get_sizes() as $size => $option) {
|
180 |
$this->render_size_checkbox($size, $option);
|
181 |
}
|
|
|
|
|
|
|
|
|
182 |
}
|
183 |
|
184 |
private function render_size_checkbox($size, $option) {
|
185 |
$id = self::get_prefixed_name("sizes_$size");
|
186 |
-
$
|
|
|
187 |
if ($size === Tiny_Metadata::ORIGINAL) {
|
188 |
-
$label = self::translate_escape("original");
|
189 |
} else {
|
190 |
-
$label = $size .
|
191 |
-
}
|
192 |
-
|
193 |
-
<
|
194 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
}
|
196 |
|
197 |
public function get_compression_count() {
|
@@ -224,35 +363,44 @@ class Tiny_Settings extends Tiny_WP_Base {
|
|
224 |
$status = false;
|
225 |
$details = array('message' => $e->getMessage());
|
226 |
}
|
|
|
|
|
227 |
if ($status) {
|
228 |
-
echo '<
|
|
|
229 |
} else {
|
|
|
230 |
if ($status === false) {
|
231 |
-
echo
|
232 |
if (isset($details['message'])) {
|
233 |
-
echo
|
234 |
}
|
235 |
} else {
|
236 |
-
echo
|
237 |
}
|
238 |
-
return;
|
239 |
-
}
|
240 |
-
|
241 |
-
$compressions = self::get_compression_count();
|
242 |
-
echo '<p>';
|
243 |
-
// We currently have no way to check if a user is free or flexible.
|
244 |
-
if ($compressions == 500) {
|
245 |
-
$link = '<a href="https://tinypng.com/developers" target="_blank">' . self::translate_escape('TinyPNG API account') . '</a>';
|
246 |
-
printf(self::translate_escape('You have reached your limit of %s compressions this month') . '.', $compressions);
|
247 |
-
echo '<br>';
|
248 |
-
printf(self::translate_escape('If you need to compress more images you can change your %s') . '.', $link);
|
249 |
-
} else {
|
250 |
-
printf(self::translate_escape('You have made %s compressions this month') . '.', self::get_compression_count());
|
251 |
}
|
252 |
echo '</p>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
}
|
254 |
|
255 |
public function render_pending_status() {
|
256 |
echo '<div id="tiny-compress-status"><div class="spinner"></div></div>';
|
257 |
}
|
|
|
|
|
|
|
|
|
258 |
}
|
31 |
$this->notices = new Tiny_Notices();
|
32 |
}
|
33 |
|
34 |
+
private function init_compressor() {
|
35 |
+
$this->compressor = Tiny_Compress::get_compressor($this->get_api_key(), $this->get_method('after_compress_callback'));
|
36 |
+
}
|
37 |
+
|
38 |
+
public function xmlrpc_init() {
|
39 |
+
try {
|
40 |
+
$this->init_compressor();
|
41 |
+
} catch (Tiny_Exception $e) {
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
public function admin_init() {
|
46 |
if (current_user_can('manage_options') && !$this->get_api_key()) {
|
47 |
$link = sprintf('<a href="options-media.php#%s">%s</a>', self::NAME,
|
48 |
self::translate_escape('Please fill in an API key to start compressing images'));
|
49 |
$this->notices->show('setting', $link, 'error', false);
|
50 |
}
|
51 |
+
try {
|
52 |
+
$this->init_compressor();
|
53 |
} catch (Tiny_Exception $e) {
|
54 |
$this->notices->show('compressor_exception', self::translate_escape($e->getMessage()), 'error', false);
|
55 |
}
|
65 |
register_setting('media', $field);
|
66 |
add_settings_field($field, self::translate('File compression'), $this->get_method('render_sizes'), 'media', $section);
|
67 |
|
68 |
+
$field = self::get_prefixed_name('resize_original');
|
69 |
+
register_setting('media', $field);
|
70 |
+
add_settings_field($field, self::translate('Resize original'), $this->get_method('render_resize'), 'media', $section);
|
71 |
+
|
72 |
$field = self::get_prefixed_name('status');
|
73 |
register_setting('media', $field);
|
74 |
add_settings_field($field, self::translate('Connection status'), $this->get_method('render_pending_status'), 'media', $section);
|
75 |
|
76 |
+
$field = self::get_prefixed_name('savings');
|
77 |
+
register_setting('media', $field);
|
78 |
+
add_settings_field($field, self::translate('Savings'), $this->get_method('render_pending_savings'), 'media', $section);
|
79 |
+
|
80 |
+
add_action('wp_ajax_tiny_image_sizes_notice', $this->get_method('image_sizes_notice'));
|
81 |
add_action('wp_ajax_tiny_compress_status', $this->get_method('connection_status'));
|
82 |
+
add_action('wp_ajax_tiny_compress_savings', $this->get_method('total_savings_status'));
|
83 |
+
}
|
84 |
+
|
85 |
+
public function image_sizes_notice() {
|
86 |
+
$this->render_image_sizes_notice($_GET["image_sizes_selected"], isset($_GET["resize_original"]));
|
87 |
+
exit();
|
88 |
}
|
89 |
|
90 |
public function connection_status() {
|
92 |
exit();
|
93 |
}
|
94 |
|
95 |
+
public function total_savings_status() {
|
96 |
+
$this->render_total_savings();
|
97 |
+
exit();
|
98 |
+
}
|
99 |
+
|
100 |
public function get_compressor() {
|
101 |
return $this->compressor;
|
102 |
}
|
165 |
return $this->sizes;
|
166 |
}
|
167 |
|
168 |
+
public function get_active_tinify_sizes() {
|
169 |
if (is_array($this->tinify_sizes)) {
|
170 |
return $this->tinify_sizes;
|
171 |
}
|
179 |
return $this->tinify_sizes;
|
180 |
}
|
181 |
|
182 |
+
public function get_resize_enabled() {
|
183 |
+
$setting = get_option(self::get_prefixed_name('resize_original'));
|
184 |
+
return isset($setting['enabled']) && $setting['enabled'] === 'on';
|
185 |
+
}
|
186 |
+
|
187 |
+
public function get_resize_options() {
|
188 |
+
$setting = get_option(self::get_prefixed_name('resize_original'));
|
189 |
+
if (!$this->get_resize_enabled()) {
|
190 |
+
return false;
|
191 |
+
}
|
192 |
+
|
193 |
+
$width = intval($setting['width']);
|
194 |
+
$height = intval($setting['height']);
|
195 |
+
$method = $width > 0 && $height > 0 ? 'fit' : 'scale';
|
196 |
+
|
197 |
+
$options['method'] = $method;
|
198 |
+
if ($width > 0) {
|
199 |
+
$options['width'] = $width;
|
200 |
+
}
|
201 |
+
if ($height > 0) {
|
202 |
+
$options['height'] = $height;
|
203 |
+
}
|
204 |
+
|
205 |
+
return sizeof($options) >= 2 ? $options : false;
|
206 |
+
}
|
207 |
+
|
208 |
public function render_section() {
|
209 |
echo '<span id="' . self::NAME . '"></span>';
|
210 |
}
|
223 |
if (empty($key)) {
|
224 |
printf(self::translate_escape('Visit %s to get an API key') . '.', $link);
|
225 |
} else {
|
226 |
+
printf(self::translate_escape('Visit %s to view or upgrade your account') . '.', $link);
|
227 |
}
|
228 |
echo '</p>';
|
229 |
}
|
230 |
|
231 |
public function render_sizes() {
|
232 |
+
echo '<p>';
|
233 |
+
echo self::translate_escape('Choose sizes to compress') . '. ';
|
234 |
+
echo self::translate_escape('Remember each selected size counts as a compression') . '. ';
|
235 |
+
echo '</p>';
|
236 |
+
echo '<input type="hidden" name="' . self::get_prefixed_name('sizes[' . self::DUMMY_SIZE . ']') . '" value="on"/>';
|
237 |
foreach ($this->get_sizes() as $size => $option) {
|
238 |
$this->render_size_checkbox($size, $option);
|
239 |
}
|
240 |
+
echo '<br>';
|
241 |
+
echo '<div id="tiny-image-sizes-notice">';
|
242 |
+
$this->render_image_sizes_notice(count(self::get_active_tinify_sizes()), self::get_resize_enabled());
|
243 |
+
echo '</div>';
|
244 |
}
|
245 |
|
246 |
private function render_size_checkbox($size, $option) {
|
247 |
$id = self::get_prefixed_name("sizes_$size");
|
248 |
+
$name = self::get_prefixed_name("sizes[$size]");
|
249 |
+
$checked = ( $option['tinify'] ? ' checked="checked"' : '' );
|
250 |
if ($size === Tiny_Metadata::ORIGINAL) {
|
251 |
+
$label = self::translate_escape("original") . ' (' . self::translate_escape('overwritten by compressed image') . ')';
|
252 |
} else {
|
253 |
+
$label = $size . ' - ' . $option['width'] . 'x' . $option['height'];
|
254 |
+
}
|
255 |
+
echo '<p>';
|
256 |
+
echo '<input type="checkbox" id="' . $id . '" name="' . $name . '" value="on" ' . $checked . '/>';
|
257 |
+
echo '<label for="' . $id . '">' . $label . '</label>';
|
258 |
+
echo '</p>';
|
259 |
+
}
|
260 |
+
|
261 |
+
public function render_image_sizes_notice($active_image_sizes_count, $resize_original_enabled) {
|
262 |
+
echo '<p>';
|
263 |
+
if ($resize_original_enabled) {
|
264 |
+
$active_image_sizes_count++;
|
265 |
+
}
|
266 |
+
if ($active_image_sizes_count < 1) {
|
267 |
+
echo self::translate_escape('With these settings no images will be compressed') . '.';
|
268 |
+
} else {
|
269 |
+
$free_images_per_month = floor( Tiny_Config::MONTHLY_FREE_COMPRESSIONS / $active_image_sizes_count );
|
270 |
+
echo self::translate_escape('With these settings you can compress');
|
271 |
+
echo ' <strong>';
|
272 |
+
printf(self::translate_escape('at least %s images'), $free_images_per_month);
|
273 |
+
echo '</strong> ';
|
274 |
+
echo self::translate_escape('for free each month') . '.';
|
275 |
+
}
|
276 |
+
echo '</p>';
|
277 |
+
}
|
278 |
+
|
279 |
+
public function render_total_savings() {
|
280 |
+
global $wpdb;
|
281 |
+
|
282 |
+
$total_savings = 0;
|
283 |
+
$result = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%' ORDER BY ID DESC", ARRAY_A);
|
284 |
+
for ($i = 0; $i < sizeof($result); $i++) {
|
285 |
+
$tiny_metadata = new Tiny_Metadata($result[$i]["ID"]);
|
286 |
+
$savings = $tiny_metadata->get_savings();
|
287 |
+
$total_savings += ($savings['input'] - $savings['output']);
|
288 |
+
}
|
289 |
+
|
290 |
+
echo '<p>';
|
291 |
+
if ($total_savings > 0) {
|
292 |
+
printf( self::translate_escape( "You have saved a total of %s on images") . '!', '<strong>' . size_format( $total_savings ) . '</strong>' );
|
293 |
+
} else {
|
294 |
+
$link = '<a href="upload.php?page=tiny-bulk-compress">' . self::translate_escape('Compress All Images') . '</a>';
|
295 |
+
printf(self::translate_escape('No images compressed yet. Use %s to compress existing images') . '.', $link);
|
296 |
+
}
|
297 |
+
echo '</p>';
|
298 |
+
}
|
299 |
+
|
300 |
+
public function render_resize() {
|
301 |
+
echo '<p class="tiny-resize-unavailable" style="display: none">';
|
302 |
+
echo self::translate_escape("Enable the compression of the original image size to configure resizing") . '.';
|
303 |
+
echo '</p>';
|
304 |
+
|
305 |
+
$id = self::get_prefixed_name("resize_original_enabled");
|
306 |
+
$name = self::get_prefixed_name("resize_original[enabled]");
|
307 |
+
$checked = ( $this->get_resize_enabled() ? ' checked="checked"' : '' );
|
308 |
+
$label = self::translate_escape('Resize and compress the orginal image');
|
309 |
+
|
310 |
+
echo '<p class="tiny-resize-available">';
|
311 |
+
echo '<input type="checkbox" id="' . $id . '" name="' . $name . '" value="on" '. $checked . '/>';
|
312 |
+
echo '<label for="' . $id . '">' . $label . '</label>';
|
313 |
+
echo '<br>';
|
314 |
+
echo '</p>';
|
315 |
+
|
316 |
+
echo '<p class="tiny-resize-available tiny-resize-resolution">';
|
317 |
+
printf("%s: ", self::translate_escape('Max Width'));
|
318 |
+
$this->render_resize_input('width');
|
319 |
+
printf("%s: ", self::translate_escape('Max Height'));
|
320 |
+
$this->render_resize_input('height');
|
321 |
+
echo '</p>';
|
322 |
+
|
323 |
+
echo '<p class="tiny-resize-available">';
|
324 |
+
echo sprintf(self::translate_escape("Resizing takes %s for each image that is larger"), self::translate_escape('1 additional compression')) . '.';
|
325 |
+
echo '</p>';
|
326 |
+
}
|
327 |
+
|
328 |
+
public function render_resize_input($name) {
|
329 |
+
$id = sprintf(self::get_prefixed_name('resize_original_%s'), $name);
|
330 |
+
$field = sprintf(self::get_prefixed_name('resize_original[%s]'), $name);
|
331 |
+
$settings = get_option(self::get_prefixed_name('resize_original'));
|
332 |
+
$value = isset($settings[$name]) ? $settings[$name] : "2048";
|
333 |
+
echo '<input type="number" id="'. $id .'" name="' . $field . '" value="' . $value . '" size="5" />';
|
334 |
}
|
335 |
|
336 |
public function get_compression_count() {
|
363 |
$status = false;
|
364 |
$details = array('message' => $e->getMessage());
|
365 |
}
|
366 |
+
|
367 |
+
echo '<p>';
|
368 |
if ($status) {
|
369 |
+
echo '<img src="images/yes.png"> ';
|
370 |
+
echo self::translate_escape('API connection successful');
|
371 |
} else {
|
372 |
+
echo '<img src="images/no.png"> ';
|
373 |
if ($status === false) {
|
374 |
+
echo self::translate_escape('API connection unsuccessful') . '<br>';
|
375 |
if (isset($details['message'])) {
|
376 |
+
echo self::translate_escape('Error') . ': ' . self::translate_escape($details['message']);
|
377 |
}
|
378 |
} else {
|
379 |
+
echo self::translate_escape('API status could not be checked, enable cURL for more information');
|
380 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
381 |
}
|
382 |
echo '</p>';
|
383 |
+
if ($status) {
|
384 |
+
$compressions = self::get_compression_count();
|
385 |
+
echo '<p>';
|
386 |
+
// It is not possible to check if a subscription is free or flexible.
|
387 |
+
if ( $compressions == Tiny_Config::MONTHLY_FREE_COMPRESSIONS ) {
|
388 |
+
$link = '<a href="https://tinypng.com/developers" target="_blank">' . self::translate_escape('TinyPNG API account') . '</a>';
|
389 |
+
printf(self::translate_escape('You have reached your limit of %s compressions this month') . '.', $compressions);
|
390 |
+
echo '<br>';
|
391 |
+
printf(self::translate_escape('If you need to compress more images you can change your %s') . '.', $link);
|
392 |
+
} else {
|
393 |
+
printf(self::translate_escape('You have made %s compressions this month') . '.', self::get_compression_count());
|
394 |
+
}
|
395 |
+
echo '</p>';
|
396 |
+
}
|
397 |
}
|
398 |
|
399 |
public function render_pending_status() {
|
400 |
echo '<div id="tiny-compress-status"><div class="spinner"></div></div>';
|
401 |
}
|
402 |
+
|
403 |
+
public function render_pending_savings() {
|
404 |
+
echo '<div id="tiny-compress-savings"><div class="spinner"></div></div>';
|
405 |
+
}
|
406 |
}
|
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');
|
@@ -51,7 +55,7 @@ abstract class Tiny_WP_Base {
|
|
51 |
}
|
52 |
|
53 |
public static function plugin_identification() {
|
54 |
-
return '
|
55 |
}
|
56 |
|
57 |
protected static function get_prefixed_name($name) {
|
@@ -66,9 +70,15 @@ abstract class Tiny_WP_Base {
|
|
66 |
return htmlspecialchars(translate($phrase, self::NAME));
|
67 |
}
|
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 +102,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');
|
55 |
}
|
56 |
|
57 |
public static function plugin_identification() {
|
58 |
+
return 'WordPress/' . self::wp_version() . ' PHP/' . PHP_VERSION . ' Tiny/' . self::plugin_version();
|
59 |
}
|
60 |
|
61 |
protected static function get_prefixed_name($name) {
|
70 |
return htmlspecialchars(translate($phrase, self::NAME));
|
71 |
}
|
72 |
|
73 |
+
protected static function ntranslate_escape($single, $plural, $amount) {
|
74 |
+
return htmlspecialchars(_n($single, $plural, $amount, self::NAME));
|
75 |
+
}
|
76 |
+
|
77 |
public function __construct() {
|
78 |
add_action('init', $this->get_method('init'));
|
79 |
+
if (self::is_xmlrpc_request()) {
|
80 |
+
add_action('init', $this->get_method('xmlrpc_init'));
|
81 |
+
} elseif (is_admin()) {
|
82 |
add_action('admin_init', $this->get_method('admin_init'));
|
83 |
}
|
84 |
}
|
102 |
public function init() {
|
103 |
}
|
104 |
|
105 |
+
public function xmlrpc_init() {
|
106 |
+
}
|
107 |
+
|
108 |
public function admin_init() {
|
109 |
}
|
110 |
}
|
src/config/tiny-config.php
CHANGED
@@ -2,4 +2,5 @@
|
|
2 |
|
3 |
class Tiny_Config {
|
4 |
const URL = 'https://api.tinify.com/shrink';
|
|
|
5 |
}
|
2 |
|
3 |
class Tiny_Config {
|
4 |
const URL = 'https://api.tinify.com/shrink';
|
5 |
+
const MONTHLY_FREE_COMPRESSIONS = 500;
|
6 |
}
|
src/languages/tiny-compress-images-nl_NL.mo
CHANGED
Binary file
|
src/languages/tiny-compress-images-nl_NL.po
CHANGED
@@ -1,14 +1,14 @@
|
|
|
|
|
|
|
|
1 |
msgid "PNG and JPEG compression"
|
2 |
msgstr "PNG- en JPEG-compressie"
|
3 |
|
4 |
-
msgid "Multisite PNG and JPEG compression"
|
5 |
-
msgstr "Multisite PNG- en JPEG-compressie"
|
6 |
-
|
7 |
msgid "Visit %s to get an API key"
|
8 |
-
msgstr "Bezoek de %s om een API-sleutel te
|
9 |
|
10 |
-
msgid "Visit %s to view
|
11 |
-
msgstr "Bezoek de %s om je
|
12 |
|
13 |
msgid "TinyPNG Developer section"
|
14 |
msgstr "TinyPNG Developer pagina"
|
@@ -16,20 +16,17 @@ msgstr "TinyPNG Developer pagina"
|
|
16 |
msgid "TinyPNG API key"
|
17 |
msgstr "TinyPNG API-sleutel"
|
18 |
|
19 |
-
msgid "Multisite API key"
|
20 |
-
msgstr "Multisite API-sleutel"
|
21 |
-
|
22 |
msgid "File compression"
|
23 |
msgstr "Bestandscompressie"
|
24 |
|
25 |
msgid "original"
|
26 |
msgstr "origineel"
|
27 |
|
28 |
-
msgid "
|
29 |
-
msgstr "
|
30 |
|
31 |
-
msgid "Remember each
|
32 |
-
msgstr "Elke
|
33 |
|
34 |
msgid "Compression"
|
35 |
msgstr "Compressie"
|
@@ -40,17 +37,77 @@ msgstr "Comprimeer"
|
|
40 |
msgid "Compress Images"
|
41 |
msgstr "Comprimeer Afbeeldingen"
|
42 |
|
43 |
-
msgid "
|
44 |
-
msgstr "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
-
msgid "
|
47 |
-
msgstr "
|
|
|
|
|
|
|
48 |
|
49 |
msgid "Total size"
|
50 |
msgstr "Totale grootte"
|
51 |
|
52 |
-
msgid "
|
53 |
-
msgstr "
|
|
|
|
|
|
|
54 |
|
55 |
msgid "Latest error"
|
56 |
msgstr "Laatste fout"
|
@@ -91,12 +148,9 @@ msgstr "Kon geen outputlocatie vinden"
|
|
91 |
msgid "Could not download output"
|
92 |
msgstr "Kon output niet downloaden"
|
93 |
|
94 |
-
msgid "File does not
|
95 |
msgstr "Bestand bestaat niet"
|
96 |
|
97 |
-
msgid "Could not decode JSON"
|
98 |
-
msgstr "Kon JSON niet decoderen"
|
99 |
-
|
100 |
msgid "Could not compress, enable cURL for detailed error"
|
101 |
msgstr "Kon niet comprimeren, schakel cURL in voor een preciezere foutmelding"
|
102 |
|
@@ -142,11 +196,35 @@ msgstr "Als je meer afbeeldingen wilt comprimeren kun je je %s aanpassen"
|
|
142 |
msgid "Upgrade your %s if you like to compress more images"
|
143 |
msgstr "Upgrade je %s als je meer afbeeldingen wilt comprimeren"
|
144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
msgid "Please fill in an API key to start compressing images"
|
146 |
msgstr "Vul een API-sleutel in om te starten met comprimeren"
|
147 |
|
148 |
msgid "Compress All Images"
|
149 |
-
msgstr "Comprimeer
|
150 |
|
151 |
msgid "Compress JPEG & PNG Images"
|
152 |
msgstr "Comprimeer JPEG & PNG afbeeldingen"
|
@@ -173,13 +251,16 @@ msgid "out of"
|
|
173 |
msgstr "van de"
|
174 |
|
175 |
msgid "Use this tool to compress all images in your media library"
|
176 |
-
msgstr "Deze tool comprimeert alle afbeeldingen in je
|
177 |
|
178 |
msgid "Only images that have not been compressed will be compressed"
|
179 |
msgstr "Dit geldt alleen voor de afbeeldingen die nog niet zijn gecomprimeerd"
|
180 |
|
181 |
-
msgid "We have found %d images in your media library"
|
182 |
-
msgstr "We hebben %d afbeeldingen in de
|
|
|
|
|
|
|
183 |
|
184 |
msgid "To begin, just press the button below"
|
185 |
msgstr "Druk op de knop om te starten"
|
@@ -195,3 +276,30 @@ msgstr "Navigeer niet van deze pagina want daardoor stopt het proces"
|
|
195 |
|
196 |
msgid "You will be notified via this page when the processing is done"
|
197 |
msgstr "Je wordt genotificeerd op deze pagina bij voltooing"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid "Speed up your website. Optimize your JPEG and PNG images automatically with TinyPNG."
|
2 |
+
msgstr "Maak je website sneller. Optimaliseer alle JPEG en PNG afbeeldingen automatisch met TinyPNG."
|
3 |
+
|
4 |
msgid "PNG and JPEG compression"
|
5 |
msgstr "PNG- en JPEG-compressie"
|
6 |
|
|
|
|
|
|
|
7 |
msgid "Visit %s to get an API key"
|
8 |
+
msgstr "Bezoek de %s om een API-sleutel te verkrijgen"
|
9 |
|
10 |
+
msgid "Visit %s to view or upgrade your account"
|
11 |
+
msgstr "Bezoek de %s om je account te bekijken of aan te passen"
|
12 |
|
13 |
msgid "TinyPNG Developer section"
|
14 |
msgstr "TinyPNG Developer pagina"
|
16 |
msgid "TinyPNG API key"
|
17 |
msgstr "TinyPNG API-sleutel"
|
18 |
|
|
|
|
|
|
|
19 |
msgid "File compression"
|
20 |
msgstr "Bestandscompressie"
|
21 |
|
22 |
msgid "original"
|
23 |
msgstr "origineel"
|
24 |
|
25 |
+
msgid "Choose sizes to compress"
|
26 |
+
msgstr "Kies afmetingen om te comprimeren"
|
27 |
|
28 |
+
msgid "Remember each selected size counts as a compression"
|
29 |
+
msgstr "Elke geselecteerde afmeting telt als een compressie"
|
30 |
|
31 |
msgid "Compression"
|
32 |
msgstr "Compressie"
|
37 |
msgid "Compress Images"
|
38 |
msgstr "Comprimeer Afbeeldingen"
|
39 |
|
40 |
+
msgid "size compressed"
|
41 |
+
msgstr "afmeting gecomprimeerd"
|
42 |
+
|
43 |
+
msgid "sizes compressed"
|
44 |
+
msgstr "afmetingen gecomprimeerd"
|
45 |
+
|
46 |
+
msgid "%d size not compressed"
|
47 |
+
msgstr "%d afmeting niet gecomprimeerd"
|
48 |
+
|
49 |
+
msgid "%d sizes not compressed"
|
50 |
+
msgstr "%d afmetingen niet gecomprimeerd"
|
51 |
+
|
52 |
+
msgid "%d file removed"
|
53 |
+
msgstr "%d bestand verwijderd"
|
54 |
+
|
55 |
+
msgid "%d files removed"
|
56 |
+
msgstr "%d bestanden verwijderd"
|
57 |
+
|
58 |
+
msgid "%d file missing"
|
59 |
+
msgstr "%d bestand bestaat niet"
|
60 |
+
|
61 |
+
msgid "%d files missing"
|
62 |
+
msgstr "%d bestanden bestaan niet"
|
63 |
+
|
64 |
+
msgid "%d file modified after compression"
|
65 |
+
msgstr "%d bestand veranderd na comprimeren"
|
66 |
+
|
67 |
+
msgid "%d files modified after compression"
|
68 |
+
msgstr "%d bestanden veranderd na comprimeren"
|
69 |
+
|
70 |
+
msgid "Compression details for %s"
|
71 |
+
msgstr "Compressie details voor %s"
|
72 |
+
|
73 |
+
msgid "Size"
|
74 |
+
msgstr "Afmeting"
|
75 |
+
|
76 |
+
msgid "Date"
|
77 |
+
msgstr "Datum"
|
78 |
+
|
79 |
+
msgid "(resized to %dx%d)"
|
80 |
+
msgstr "(verkleind naar %dx%d)"
|
81 |
+
|
82 |
+
msgid "(modified after compression)"
|
83 |
+
msgstr "(veranderd na compressie)"
|
84 |
+
|
85 |
+
msgid "(file removed)"
|
86 |
+
msgstr "(bestand ontbreekt)"
|
87 |
+
|
88 |
+
msgid "ago"
|
89 |
+
msgstr "geleden"
|
90 |
+
|
91 |
+
msgid "Combined"
|
92 |
+
msgstr "Gecombineerd"
|
93 |
+
|
94 |
+
msgid "Total savings %s"
|
95 |
+
msgstr "Totaal bespaard %s"
|
96 |
|
97 |
+
msgid "size being compressed"
|
98 |
+
msgstr "afmeting wordt gecomprimeerd"
|
99 |
+
|
100 |
+
msgid "sizes being compressed"
|
101 |
+
msgstr "afmetingen worden gecomprimeerd"
|
102 |
|
103 |
msgid "Total size"
|
104 |
msgstr "Totale grootte"
|
105 |
|
106 |
+
msgid "Original"
|
107 |
+
msgstr "Origineel"
|
108 |
+
|
109 |
+
msgid "Compressed"
|
110 |
+
msgstr "Gecomprimeerd"
|
111 |
|
112 |
msgid "Latest error"
|
113 |
msgstr "Laatste fout"
|
148 |
msgid "Could not download output"
|
149 |
msgstr "Kon output niet downloaden"
|
150 |
|
151 |
+
msgid "File does not exist"
|
152 |
msgstr "Bestand bestaat niet"
|
153 |
|
|
|
|
|
|
|
154 |
msgid "Could not compress, enable cURL for detailed error"
|
155 |
msgstr "Kon niet comprimeren, schakel cURL in voor een preciezere foutmelding"
|
156 |
|
196 |
msgid "Upgrade your %s if you like to compress more images"
|
197 |
msgstr "Upgrade je %s als je meer afbeeldingen wilt comprimeren"
|
198 |
|
199 |
+
msgid "Savings"
|
200 |
+
msgstr "Besparingen"
|
201 |
+
|
202 |
+
msgid "You have saved a total of %s on images"
|
203 |
+
msgstr "Je hebt in totaal %s bespaard op afbeeldingen"
|
204 |
+
|
205 |
+
msgid "No images compressed yet. Use %s to compress existing images"
|
206 |
+
msgstr "Nog geen gecomprimeerde afbeeldingen. Gebruik %s om bestaande afbeeldingen te comprimeren"
|
207 |
+
|
208 |
+
msgid "With these settings you can compress"
|
209 |
+
msgstr "Met deze instellingen kan je elke maand"
|
210 |
+
|
211 |
+
msgid "at least %s images"
|
212 |
+
msgstr "minstens %s afbeeldingen"
|
213 |
+
|
214 |
+
msgid "for free each month"
|
215 |
+
msgstr "gratis comprimeren"
|
216 |
+
|
217 |
+
msgid "With these settings no images will be compressed"
|
218 |
+
msgstr "Met deze instellingen worden geen afbeeldingen gecomprimeerd"
|
219 |
+
|
220 |
+
msgid "overwritten by compressed image"
|
221 |
+
msgstr "overschreven door gecomprimeerde afbeelding"
|
222 |
+
|
223 |
msgid "Please fill in an API key to start compressing images"
|
224 |
msgstr "Vul een API-sleutel in om te starten met comprimeren"
|
225 |
|
226 |
msgid "Compress All Images"
|
227 |
+
msgstr "Comprimeer alle afbeeldingen"
|
228 |
|
229 |
msgid "Compress JPEG & PNG Images"
|
230 |
msgstr "Comprimeer JPEG & PNG afbeeldingen"
|
251 |
msgstr "van de"
|
252 |
|
253 |
msgid "Use this tool to compress all images in your media library"
|
254 |
+
msgstr "Deze tool comprimeert alle afbeeldingen in je mediabibliotheek"
|
255 |
|
256 |
msgid "Only images that have not been compressed will be compressed"
|
257 |
msgstr "Dit geldt alleen voor de afbeeldingen die nog niet zijn gecomprimeerd"
|
258 |
|
259 |
+
msgid "We have found %d images in your media library and for each image %d sizes will be compressed"
|
260 |
+
msgstr "We hebben %d afbeeldingen in de mediabibliotheek gevonden en voor elke afbeelding worden %d afmetingen gecomprimeerd"
|
261 |
+
|
262 |
+
msgid "This results in %d compressions at most"
|
263 |
+
msgstr "Dit resulteert in een maximaal verbruik van %d compressies"
|
264 |
|
265 |
msgid "To begin, just press the button below"
|
266 |
msgstr "Druk op de knop om te starten"
|
276 |
|
277 |
msgid "You will be notified via this page when the processing is done"
|
278 |
msgstr "Je wordt genotificeerd op deze pagina bij voltooing"
|
279 |
+
|
280 |
+
msgid "Settings"
|
281 |
+
msgstr "Instellingen"
|
282 |
+
|
283 |
+
msgid "Resize original"
|
284 |
+
msgstr "Orgineel verkleinen"
|
285 |
+
|
286 |
+
msgid "Enable the compression of the original image size to configure resizing"
|
287 |
+
msgstr "Schakel compressie van de originele afbeelding in om te kunnen verkleinen"
|
288 |
+
|
289 |
+
msgid "Resize and compress the orginal image"
|
290 |
+
msgstr "Verklein en comprimeer de originele afbeelding"
|
291 |
+
|
292 |
+
msgid "Resizing takes %s for each image that is larger"
|
293 |
+
msgstr "Verkleinen gebruikt %s voor elke afbeelding die groter is dan de vermelde afmetingen"
|
294 |
+
|
295 |
+
msgid "1 additional compression"
|
296 |
+
msgstr "1 extra compressie"
|
297 |
+
|
298 |
+
msgid "Resized original to %dx%d"
|
299 |
+
msgstr "Origineel verkleind tot %dx%d"
|
300 |
+
|
301 |
+
msgid "Max Width"
|
302 |
+
msgstr "Maximale breedte"
|
303 |
+
|
304 |
+
msgid "Max Height"
|
305 |
+
msgstr "Maximale hoogte"
|
src/languages/tiny-compress-images-ru_RU.mo
CHANGED
Binary file
|
src/languages/tiny-compress-images-ru_RU.po
CHANGED
@@ -13,16 +13,16 @@ msgstr ""
|
|
13 |
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
14 |
"Language: ru_RU\n"
|
15 |
|
|
|
|
|
|
|
16 |
msgid "PNG and JPEG compression"
|
17 |
msgstr "Сжатие PNG и JPEG"
|
18 |
|
19 |
-
msgid "Multisite PNG and JPEG compression"
|
20 |
-
msgstr "PNG и JPEG сжатие для Multisite"
|
21 |
-
|
22 |
msgid "Visit %s to get an API key"
|
23 |
msgstr "Посетите %s, чтобы получить API ключ"
|
24 |
|
25 |
-
msgid "Visit %s to view
|
26 |
msgstr "Посетите %s, чтобы посмотреть свою статистику использования сервиса и повысить статус аккаунта"
|
27 |
|
28 |
msgid "TinyPNG Developer section"
|
@@ -31,9 +31,6 @@ msgstr "раздел TinyPNG для разработчиков"
|
|
31 |
msgid "TinyPNG API key"
|
32 |
msgstr "TinyPNG API ключ"
|
33 |
|
34 |
-
msgid "Multisite API key"
|
35 |
-
msgstr "Multisite API ключ"
|
36 |
-
|
37 |
msgid "File compression"
|
38 |
msgstr "Сжатие файлов"
|
39 |
|
@@ -43,7 +40,7 @@ msgstr "оригинальное изображение"
|
|
43 |
msgid "You can choose to compress different image sizes created by WordPress here"
|
44 |
msgstr "Здесь вы можете выбрать, какие размеры изображений сжимать"
|
45 |
|
46 |
-
msgid "Remember each
|
47 |
msgstr "Помните, каждый дополнительный типоразмер влияет на месячное использование сервиса TinyPNG"
|
48 |
|
49 |
msgid "Compression"
|
@@ -103,12 +100,9 @@ msgstr "Не могу найти url результата"
|
|
103 |
msgid "Could not download output"
|
104 |
msgstr "Не могу загрузить результат"
|
105 |
|
106 |
-
msgid "File does not
|
107 |
msgstr "Файл не существует или не найден плагином"
|
108 |
|
109 |
-
msgid "Could not decode JSON"
|
110 |
-
msgstr "Не могу раскодировать JSON"
|
111 |
-
|
112 |
msgid "Could not compress, enable cURL for detailed error"
|
113 |
msgstr "Не могу сжать. Подключите cURL для деталей"
|
114 |
|
13 |
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
14 |
"Language: ru_RU\n"
|
15 |
|
16 |
+
msgid "Speed up your website. Optimize your JPEG and PNG images automatically with TinyPNG."
|
17 |
+
msgstr "Speed up your website. Optimize your JPEG and PNG images automatically with TinyPNG."
|
18 |
+
|
19 |
msgid "PNG and JPEG compression"
|
20 |
msgstr "Сжатие PNG и JPEG"
|
21 |
|
|
|
|
|
|
|
22 |
msgid "Visit %s to get an API key"
|
23 |
msgstr "Посетите %s, чтобы получить API ключ"
|
24 |
|
25 |
+
msgid "Visit %s to view or upgrade your account"
|
26 |
msgstr "Посетите %s, чтобы посмотреть свою статистику использования сервиса и повысить статус аккаунта"
|
27 |
|
28 |
msgid "TinyPNG Developer section"
|
31 |
msgid "TinyPNG API key"
|
32 |
msgstr "TinyPNG API ключ"
|
33 |
|
|
|
|
|
|
|
34 |
msgid "File compression"
|
35 |
msgstr "Сжатие файлов"
|
36 |
|
40 |
msgid "You can choose to compress different image sizes created by WordPress here"
|
41 |
msgstr "Здесь вы можете выбрать, какие размеры изображений сжимать"
|
42 |
|
43 |
+
msgid "Remember each selected size counts as a compression"
|
44 |
msgstr "Помните, каждый дополнительный типоразмер влияет на месячное использование сервиса TinyPNG"
|
45 |
|
46 |
msgid "Compression"
|
100 |
msgid "Could not download output"
|
101 |
msgstr "Не могу загрузить результат"
|
102 |
|
103 |
+
msgid "File does not exist"
|
104 |
msgstr "Файл не существует или не найден плагином"
|
105 |
|
|
|
|
|
|
|
106 |
msgid "Could not compress, enable cURL for detailed error"
|
107 |
msgstr "Не могу сжать. Подключите cURL для деталей"
|
108 |
|
src/languages/tiny-compress-images-zh_TW.mo
ADDED
Binary file
|
src/languages/tiny-compress-images-zh_TW.po
ADDED
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: \n"
|
4 |
+
"POT-Creation-Date: \n"
|
5 |
+
"PO-Revision-Date: \n"
|
6 |
+
"Language-Team: \n"
|
7 |
+
"MIME-Version: 1.0\n"
|
8 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
9 |
+
"Content-Transfer-Encoding: 8bit\n"
|
10 |
+
"X-Generator: Poedit 1.8.4\n"
|
11 |
+
"Last-Translator: Pseric <pserics@gmail.com>\n"
|
12 |
+
"Plural-Forms: nplurals=1; plural=0;\n"
|
13 |
+
"Language: zh_TW\n"
|
14 |
+
|
15 |
+
msgid "Speed up your website. Optimize your JPEG and PNG images automatically with TinyPNG."
|
16 |
+
msgstr "Speed up your website. Optimize your JPEG and PNG images automatically with TinyPNG."
|
17 |
+
|
18 |
+
msgid "PNG and JPEG compression"
|
19 |
+
msgstr "PNG 和 JPEG 壓縮"
|
20 |
+
|
21 |
+
msgid "Visit %s to get an API key"
|
22 |
+
msgstr "訪問 %s 取得一個 API 金鑰"
|
23 |
+
|
24 |
+
msgid "Visit %s to view or upgrade your account"
|
25 |
+
msgstr "訪問 %s 檢視你的使用量或升級你的帳號"
|
26 |
+
|
27 |
+
msgid "TinyPNG Developer section"
|
28 |
+
msgstr "TinyPNG 開發者功能"
|
29 |
+
|
30 |
+
msgid "TinyPNG API key"
|
31 |
+
msgstr "TinyPNG API 金鑰"
|
32 |
+
|
33 |
+
msgid "File compression"
|
34 |
+
msgstr "檔案壓縮"
|
35 |
+
|
36 |
+
msgid "original"
|
37 |
+
msgstr "原始大小"
|
38 |
+
|
39 |
+
msgid "You can choose to compress different image sizes created by WordPress here"
|
40 |
+
msgstr "你可以在這裡選擇要壓縮的圖片大小,由 WordPress 建立"
|
41 |
+
|
42 |
+
msgid "Remember each selected size counts as a compression"
|
43 |
+
msgstr "請記住,每個額外圖片尺寸都會影響你的 TinyPNG 每月使用量"
|
44 |
+
|
45 |
+
msgid "Compression"
|
46 |
+
msgstr "壓縮"
|
47 |
+
|
48 |
+
msgid "Compress"
|
49 |
+
msgstr "壓縮"
|
50 |
+
|
51 |
+
msgid "Compress Images"
|
52 |
+
msgstr "壓縮圖片"
|
53 |
+
|
54 |
+
msgid "Compressed %d out of %d sizes"
|
55 |
+
msgstr "已壓縮 %d/%d 個尺寸"
|
56 |
+
|
57 |
+
msgid "Compressing %d sizes..."
|
58 |
+
msgstr "壓縮 %d 個尺寸..."
|
59 |
+
|
60 |
+
msgid "Total size"
|
61 |
+
msgstr "總共大小"
|
62 |
+
|
63 |
+
msgid "Compressed size"
|
64 |
+
msgstr "已壓縮尺寸"
|
65 |
+
|
66 |
+
msgid "Latest error"
|
67 |
+
msgstr "最近錯誤"
|
68 |
+
|
69 |
+
msgid "Error"
|
70 |
+
msgstr "錯誤"
|
71 |
+
|
72 |
+
msgid "Internal error"
|
73 |
+
msgstr "內部錯誤"
|
74 |
+
|
75 |
+
msgid "Credentials are invalid"
|
76 |
+
msgstr "憑證無效"
|
77 |
+
|
78 |
+
msgid "Your monthly limit has been exceeded"
|
79 |
+
msgstr "你的每月限額已經超過"
|
80 |
+
|
81 |
+
msgid "File is empty"
|
82 |
+
msgstr "檔案是空的"
|
83 |
+
|
84 |
+
msgid "Does not appear to be a PNG or JPEG file"
|
85 |
+
msgstr "似乎不是一個 PNG 或 JPEG 檔案"
|
86 |
+
|
87 |
+
msgid "CMYK color space is not supported"
|
88 |
+
msgstr "不支援 CMYK 色彩空間"
|
89 |
+
|
90 |
+
msgid "Image appears corrupt"
|
91 |
+
msgstr "圖片似乎已經損壞"
|
92 |
+
|
93 |
+
msgid "Compression failed"
|
94 |
+
msgstr "壓縮失敗"
|
95 |
+
|
96 |
+
msgid "No HTTP client is available (cURL or fopen)"
|
97 |
+
msgstr "沒有 HTTP 客戶端可用(cURL 或 fopen)"
|
98 |
+
|
99 |
+
msgid "Could not find output url"
|
100 |
+
msgstr "找不到輸出網址"
|
101 |
+
|
102 |
+
msgid "Could not download output"
|
103 |
+
msgstr "無法下載輸出"
|
104 |
+
|
105 |
+
msgid "File does not exist"
|
106 |
+
msgstr "檔案不存在"
|
107 |
+
|
108 |
+
msgid "Could not compress, enable cURL for detailed error"
|
109 |
+
msgstr "無法壓縮,啟用 cURL 取得詳細錯誤資訊"
|
110 |
+
|
111 |
+
msgid "You don't have permission to work with uploaded files"
|
112 |
+
msgstr "你沒有權限來處理上傳的檔案"
|
113 |
+
|
114 |
+
msgid "Not a valid media file"
|
115 |
+
msgstr "不是一個有效的媒體檔案"
|
116 |
+
|
117 |
+
msgid "Could not find metadata of media file"
|
118 |
+
msgstr "找不到媒體檔案的 metadata"
|
119 |
+
|
120 |
+
msgid "The API key has been configured in %s"
|
121 |
+
msgstr "這個 API 金鑰已經設定在 %s"
|
122 |
+
|
123 |
+
msgid "Connection status"
|
124 |
+
msgstr "連線狀態"
|
125 |
+
|
126 |
+
msgid "Dismiss"
|
127 |
+
msgstr "拒絕"
|
128 |
+
|
129 |
+
msgid "TinyPNG API account"
|
130 |
+
msgstr "TinyPNG API 帳號"
|
131 |
+
|
132 |
+
msgid "API connection successful"
|
133 |
+
msgstr "API 連線成功"
|
134 |
+
|
135 |
+
msgid "API connection unsuccessful"
|
136 |
+
msgstr "API 連線不成功"
|
137 |
+
|
138 |
+
msgid "API status could not be checked, enable cURL for more information"
|
139 |
+
msgstr "無法檢查 API 狀態,啟用 cURL 取得更多資訊"
|
140 |
+
|
141 |
+
msgid "You have made %s compressions this month"
|
142 |
+
msgstr "本月你已經壓縮 %s 張圖片"
|
143 |
+
|
144 |
+
msgid "You have reached your limit of %s compressions this month"
|
145 |
+
msgstr "本月你已經到達你的壓縮限制 %s 張圖片"
|
146 |
+
|
147 |
+
msgid "If you need to compress more images you can change your %s"
|
148 |
+
msgstr "如果你需要壓縮更多圖片,你可以變更你的 %s"
|
149 |
+
|
150 |
+
msgid "Upgrade your %s if you like to compress more images"
|
151 |
+
msgstr "如果你想壓縮更多圖片,升級你的 %s"
|
152 |
+
|
153 |
+
msgid "Please fill in an API key to start compressing images"
|
154 |
+
msgstr "請填入一個 API 金鑰來開始壓縮圖片"
|
155 |
+
|
156 |
+
msgid "Compress All Images"
|
157 |
+
msgstr "壓縮所有圖片"
|
158 |
+
|
159 |
+
msgid "Compress JPEG & PNG Images"
|
160 |
+
msgstr "壓縮 JPEG & PNG 圖片"
|
161 |
+
|
162 |
+
msgid "All images are processed"
|
163 |
+
msgstr "所有圖片皆處理完成"
|
164 |
+
|
165 |
+
msgid "Compressions this month"
|
166 |
+
msgstr "本月壓縮"
|
167 |
+
|
168 |
+
msgid "Processing"
|
169 |
+
msgstr "處理中"
|
170 |
+
|
171 |
+
msgid "Waiting"
|
172 |
+
msgstr "等待中"
|
173 |
+
|
174 |
+
msgid "Compressing"
|
175 |
+
msgstr "壓縮中"
|
176 |
+
|
177 |
+
msgid "compressions"
|
178 |
+
msgstr "壓縮"
|
179 |
+
|
180 |
+
msgid "out of"
|
181 |
+
msgstr "以外"
|
182 |
+
|
183 |
+
msgid "Use this tool to compress all images in your media library"
|
184 |
+
msgstr "使用這個工具來壓縮你媒體庫的所有圖片"
|
185 |
+
|
186 |
+
msgid "Only images that have not been compressed will be compressed"
|
187 |
+
msgstr "只有沒被壓縮過的圖片才會壓縮"
|
188 |
+
|
189 |
+
msgid "We have found %d images in your media library"
|
190 |
+
msgstr "我們在你的媒體庫找到 %d 張圖片"
|
191 |
+
|
192 |
+
msgid "To begin, just press the button below"
|
193 |
+
msgstr "如要開始,只要點選下方案扭"
|
194 |
+
|
195 |
+
msgid "Please be patient while the images are being compressed"
|
196 |
+
msgstr "相片壓縮時請耐心等待"
|
197 |
+
|
198 |
+
msgid "This can take a while if you have many images"
|
199 |
+
msgstr "如果你有許多圖片,這可能需要一段時間"
|
200 |
+
|
201 |
+
msgid "Do not navigate away from this page because it will stop the process"
|
202 |
+
msgstr "請不要離開此頁面,因為它會停止壓縮程序"
|
203 |
+
|
204 |
+
msgid "You will be notified via this page when the processing is done"
|
205 |
+
msgstr "當處理完成後,你將透過此頁面取得通知"
|
src/scripts/admin.js
CHANGED
@@ -8,6 +8,7 @@
|
|
8 |
var element = jQuery(event.target)
|
9 |
element.attr('disabled', 'disabled')
|
10 |
element.closest('td').find('.spinner').removeClass('hidden')
|
|
|
11 |
jQuery.ajax({
|
12 |
url: ajaxurl,
|
13 |
type: "POST",
|
@@ -155,6 +156,34 @@
|
|
155 |
|
156 |
if (adminpage === "options-media-php") {
|
157 |
jQuery('#tiny-compress-status').load(ajaxurl + '?action=tiny_compress_status')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
}
|
159 |
|
160 |
jQuery('.tiny-notice a.tiny-dismiss').click(dismiss_notice)
|
@@ -163,4 +192,4 @@
|
|
163 |
})
|
164 |
|
165 |
window.tinyBulkCompress = bulk_compress
|
166 |
-
}).call()
|
8 |
var element = jQuery(event.target)
|
9 |
element.attr('disabled', 'disabled')
|
10 |
element.closest('td').find('.spinner').removeClass('hidden')
|
11 |
+
element.closest('td').find('span.dashicons').addClass('hidden')
|
12 |
jQuery.ajax({
|
13 |
url: ajaxurl,
|
14 |
type: "POST",
|
156 |
|
157 |
if (adminpage === "options-media-php") {
|
158 |
jQuery('#tiny-compress-status').load(ajaxurl + '?action=tiny_compress_status')
|
159 |
+
jQuery('#tiny-compress-savings').load(ajaxurl + '?action=tiny_compress_savings')
|
160 |
+
|
161 |
+
jQuery('input[name*="tinypng_sizes"], input#tinypng_resize_original_enabled').on("click", function() {
|
162 |
+
// Unfortunately, we need some additional information to display the correct notice.
|
163 |
+
totalSelectedSizes = jQuery('input[name*="tinypng_sizes"]:checked').length
|
164 |
+
var image_count_url = ajaxurl + '?action=tiny_image_sizes_notice&image_sizes_selected=' + totalSelectedSizes
|
165 |
+
if (jQuery('input#tinypng_resize_original_enabled').prop('checked') && jQuery('input#tinypng_sizes_0').prop('checked')) {
|
166 |
+
image_count_url += '&resize_original=true'
|
167 |
+
}
|
168 |
+
jQuery('#tiny-image-sizes-notice').load(image_count_url)
|
169 |
+
})
|
170 |
+
|
171 |
+
function update_resize_settings() {
|
172 |
+
if (jQuery('#tinypng_sizes_0').prop('checked')) {
|
173 |
+
jQuery('.tiny-resize-available').show()
|
174 |
+
jQuery('.tiny-resize-unavailable').hide()
|
175 |
+
} else {
|
176 |
+
jQuery('.tiny-resize-available').hide()
|
177 |
+
jQuery('.tiny-resize-unavailable').show()
|
178 |
+
}
|
179 |
+
|
180 |
+
var elements = jQuery('#tinypng_resize_original_width, #tinypng_resize_original_height')
|
181 |
+
for (var i = 0; i < elements.length; i++) {
|
182 |
+
elements[i].disabled = !jQuery('#tinypng_resize_original_enabled').prop('checked')
|
183 |
+
}
|
184 |
+
}
|
185 |
+
update_resize_settings()
|
186 |
+
jQuery('#tinypng_sizes_0, #tinypng_resize_original_enabled').click(update_resize_settings)
|
187 |
}
|
188 |
|
189 |
jQuery('.tiny-notice a.tiny-dismiss').click(dismiss_notice)
|
192 |
})
|
193 |
|
194 |
window.tinyBulkCompress = bulk_compress
|
195 |
+
}).call()
|
src/styles/admin.css
CHANGED
@@ -5,20 +5,93 @@
|
|
5 |
margin-top: 0;
|
6 |
}
|
7 |
|
8 |
-
.tiny-compress-images .spinner {
|
9 |
display: inline-block;
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
visibility: visible;
|
11 |
float: none;
|
12 |
-
margin
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
}
|
14 |
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
display: inline;
|
17 |
visibility: visible;
|
18 |
float: left;
|
19 |
margin: 0;
|
20 |
}
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
#tiny-bulk-compress #media-items .bar.failed {
|
23 |
background-color: #DD3D36;
|
24 |
}
|
@@ -51,3 +124,15 @@
|
|
51 |
box-shadow: 0px 1px 0px #DFDFDF;
|
52 |
padding: 5px;
|
53 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
margin-top: 0;
|
6 |
}
|
7 |
|
8 |
+
.tiny-compress-images div.spinner {
|
9 |
display: inline-block;
|
10 |
+
visibility: visible;
|
11 |
+
float: right;
|
12 |
+
margin-top: 4px;
|
13 |
+
}
|
14 |
+
|
15 |
+
.tiny-compress-images span.spinner {
|
16 |
visibility: visible;
|
17 |
float: none;
|
18 |
+
margin: 0;
|
19 |
+
}
|
20 |
+
|
21 |
+
.tiny-compress-images .details-container {
|
22 |
+
overflow: auto;
|
23 |
+
}
|
24 |
+
|
25 |
+
.tiny-compress-images .details-container button {
|
26 |
+
display: block;
|
27 |
+
margin: 5px 0 10px 24px;
|
28 |
+
}
|
29 |
+
|
30 |
+
.tiny-compress-images .details-container span.icon {
|
31 |
+
position: absolute;
|
32 |
}
|
33 |
|
34 |
+
.tiny-compress-images .details-container .message {
|
35 |
+
display: inline-block;
|
36 |
+
margin-left: 24px;
|
37 |
+
}
|
38 |
+
|
39 |
+
.tiny-compress-images .details-container span.success {
|
40 |
+
color: #0EE00E;
|
41 |
+
}
|
42 |
+
|
43 |
+
.tiny-compress-images .details-container span.error {
|
44 |
+
color: #D54E21;
|
45 |
+
}
|
46 |
+
|
47 |
+
.tiny-compress-images .details-container span.alert {
|
48 |
+
color: gray;
|
49 |
+
}
|
50 |
+
|
51 |
+
#tiny-compress-status .spinner, #tiny-compress-savings .spinner {
|
52 |
display: inline;
|
53 |
visibility: visible;
|
54 |
float: left;
|
55 |
margin: 0;
|
56 |
}
|
57 |
|
58 |
+
.tiny-compression-details {
|
59 |
+
padding: 10px;
|
60 |
+
}
|
61 |
+
|
62 |
+
.tiny-compression-details table {
|
63 |
+
border: 1px solid #E5E5E5;
|
64 |
+
border-collapse: collapse;
|
65 |
+
white-space: nowrap;
|
66 |
+
width: 100%;
|
67 |
+
}
|
68 |
+
|
69 |
+
.tiny-compression-details table tr.even {
|
70 |
+
background-color: #F9F9F9;
|
71 |
+
}
|
72 |
+
|
73 |
+
.tiny-compression-details table td {
|
74 |
+
padding: 6px 10px;
|
75 |
+
}
|
76 |
+
|
77 |
+
.tiny-compression-details table th {
|
78 |
+
padding: 8px 10px;
|
79 |
+
border-bottom: 1px solid #E5E5E5;
|
80 |
+
font-size: 14px;
|
81 |
+
}
|
82 |
+
|
83 |
+
.tiny-compression-details table tfoot {
|
84 |
+
border-top: 1px solid #E5E5E5;
|
85 |
+
}
|
86 |
+
|
87 |
+
.tiny-compression-details table tfoot td {
|
88 |
+
padding: 8px 10px;
|
89 |
+
}
|
90 |
+
|
91 |
+
.tiny-compress-images .modal {
|
92 |
+
display: none;
|
93 |
+
}
|
94 |
+
|
95 |
#tiny-bulk-compress #media-items .bar.failed {
|
96 |
background-color: #DD3D36;
|
97 |
}
|
124 |
box-shadow: 0px 1px 0px #DFDFDF;
|
125 |
padding: 5px;
|
126 |
}
|
127 |
+
|
128 |
+
p.tiny-resize-resolution {
|
129 |
+
margin-left: 24px;
|
130 |
+
}
|
131 |
+
|
132 |
+
p.tiny-resize-resolution input {
|
133 |
+
margin-right: 6px;
|
134 |
+
}
|
135 |
+
|
136 |
+
input[type=number][name*="tinypng_resize_original"] {
|
137 |
+
width: 65px;
|
138 |
+
}
|
src/views/compress-details-processing.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="details-container">
|
2 |
+
<div class="details">
|
3 |
+
<span class="icon spinner"></span>
|
4 |
+
<span class="message">
|
5 |
+
<strong><?php echo $compressing ?></strong>
|
6 |
+
<span><?php printf(self::ntranslate_escape('size being compressed', 'sizes being compressed', $compressing)) ?></span>
|
7 |
+
</span>
|
8 |
+
</div>
|
9 |
+
</div>
|
src/views/compress-details.php
ADDED
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="details-container">
|
2 |
+
<div class="details">
|
3 |
+
<?php if ($error) { ?>
|
4 |
+
<span class="icon dashicons dashicons-warning error"></span>
|
5 |
+
<?php } else if ($missing > 0 || $modified > 0) { ?>
|
6 |
+
<span class="icon dashicons dashicons-yes alert"></span>
|
7 |
+
<?php } else if ($tiny_metadata->get_success_count() > 0 && count($uncompressed) > 0) { ?>
|
8 |
+
<span class="icon dashicons dashicons-yes alert"></span>
|
9 |
+
<?php } else if ($tiny_metadata->get_success_count() > 0) { ?>
|
10 |
+
<span class="icon dashicons dashicons-yes success"></span>
|
11 |
+
<?php } ?>
|
12 |
+
<span class="icon spinner hidden"></span>
|
13 |
+
|
14 |
+
<?php if ($tiny_metadata->get_compressed_count() > 0 || ($tiny_metadata->get_compressed_count() == 0 && count($uncompressed) == 0)) { ?>
|
15 |
+
<span class="message">
|
16 |
+
<strong><?php echo $tiny_metadata->get_compressed_count() ?></strong>
|
17 |
+
<span><?php printf(self::ntranslate_escape('size compressed', 'sizes compressed', $tiny_metadata->get_compressed_count())) ?></span>
|
18 |
+
</span>
|
19 |
+
<br/>
|
20 |
+
<?php } ?>
|
21 |
+
|
22 |
+
<?php if ($not_compressed_active > 0) { ?>
|
23 |
+
<span class="message">
|
24 |
+
<?php printf(self::ntranslate_escape('%d size not compressed', '%d sizes not compressed', $not_compressed_active), $not_compressed_active) ?>
|
25 |
+
</span>
|
26 |
+
<br />
|
27 |
+
<?php } ?>
|
28 |
+
|
29 |
+
<?php if ($missing > 0) { ?>
|
30 |
+
<span class="message">
|
31 |
+
<?php printf(self::ntranslate_escape('%d file removed', '%d files removed', $missing), $missing) ?>
|
32 |
+
</span>
|
33 |
+
<br />
|
34 |
+
<?php } ?>
|
35 |
+
|
36 |
+
<?php if ($modified > 0) { ?>
|
37 |
+
<span class="message">
|
38 |
+
<?php printf(self::ntranslate_escape('%d file modified after compression', '%d files modified after compression', $modified), $modified) ?>
|
39 |
+
</span>
|
40 |
+
<br />
|
41 |
+
<?php } ?>
|
42 |
+
|
43 |
+
<?php if ($savings["input"] - $savings["output"]) { ?>
|
44 |
+
<span class="message">
|
45 |
+
<?php printf(self::translate_escape('Total savings %s' ), str_replace( " ", " ", size_format($savings["input"] - $savings["output"], 1))) ?>
|
46 |
+
</span>
|
47 |
+
<br />
|
48 |
+
<?php } ?>
|
49 |
+
|
50 |
+
<?php if ($error) { ?>
|
51 |
+
<span class="message error_message">
|
52 |
+
<?php echo self::translate_escape('Latest error') . ': '. self::translate_escape($error) ?>
|
53 |
+
</span>
|
54 |
+
<br/>
|
55 |
+
<?php } ?>
|
56 |
+
|
57 |
+
<?php if ($tiny_metadata->get_compressed_count() > 0) { ?>
|
58 |
+
<a class="thickbox message" href="#TB_inline?width=700&height=500&inlineId=modal_<?php echo $tiny_metadata->get_id() ?>">Details</a>
|
59 |
+
<?php } ?>
|
60 |
+
</div>
|
61 |
+
|
62 |
+
<?php if (count($uncompressed) > 0) { ?>
|
63 |
+
<button type="button" class="tiny-compress button button-small button-primary" data-id="<?php echo $tiny_metadata->get_id() ?>">
|
64 |
+
<?php echo self::translate_escape('Compress') ?>
|
65 |
+
</button>
|
66 |
+
<?php } ?>
|
67 |
+
</div>
|
68 |
+
<?php if ($tiny_metadata->get_compressed_count() > 0) { ?>
|
69 |
+
<div class="modal" id="modal_<?php echo $tiny_metadata->get_id() ?>">
|
70 |
+
<div class="tiny-compression-details">
|
71 |
+
<h3><?php printf(self::translate_escape('Compression details for %s'), $tiny_metadata->get_name()) ?></h3>
|
72 |
+
<table>
|
73 |
+
<tr>
|
74 |
+
<th><?php echo self::translate_escape('Size') ?></th>
|
75 |
+
<th><?php echo self::translate_escape('Original') ?></th>
|
76 |
+
<th><?php echo self::translate_escape('Compressed') ?></th>
|
77 |
+
<th><?php echo self::translate_escape('Date') ?></th>
|
78 |
+
</tr>
|
79 |
+
<?php $i = 0; ?>
|
80 |
+
<?php foreach ($tiny_metadata->get_compressed_sizes() as $size) { ?>
|
81 |
+
<?php $meta = $tiny_metadata->get_value($size); ?>
|
82 |
+
<tr class="<?php echo ($i % 2 == 0) ? 'even' : 'odd' ?>">
|
83 |
+
<td>
|
84 |
+
<?php
|
85 |
+
echo ($size == "0" ? self::translate_escape('original') : $size ) . ' ';
|
86 |
+
if ($tiny_metadata->still_exists($size)) {
|
87 |
+
if ($tiny_metadata->is_compressed($size)) {
|
88 |
+
if ($tiny_metadata->is_resized($size)) {
|
89 |
+
printf('<em>' . self::translate_escape('(resized to %dx%d)') . '</em>', $meta['output']['width'], $meta['output']['height']);
|
90 |
+
}
|
91 |
+
} else {
|
92 |
+
echo '<em>' . self::translate_escape('(modified after compression)') . '</em>';
|
93 |
+
}
|
94 |
+
} else {
|
95 |
+
echo '<em>' . self::translate_escape('(file removed)') . '</em>';
|
96 |
+
}
|
97 |
+
?>
|
98 |
+
</td>
|
99 |
+
<td><?php echo size_format($meta["input"]["size"], 1) ?></td>
|
100 |
+
<td><?php echo size_format($meta["output"]["size"], 1) ?></td>
|
101 |
+
<td><?php echo human_time_diff($tiny_metadata->get_end_time($size)) . ' ' . self::translate_escape('ago') ?></td>
|
102 |
+
</tr>
|
103 |
+
<?php $i++; ?>
|
104 |
+
<?php } ?>
|
105 |
+
<?php if ($savings['count'] > 0) { ?>
|
106 |
+
<tfoot>
|
107 |
+
<tr>
|
108 |
+
<td><?php echo self::translate_escape('Combined') ?></td>
|
109 |
+
<td><?php echo size_format($savings['input'], 1) ?></td>
|
110 |
+
<td><?php echo size_format($savings['output'], 1) ?></td>
|
111 |
+
<td></td>
|
112 |
+
</tr>
|
113 |
+
</tfoot>
|
114 |
+
<?php } ?>
|
115 |
+
</table>
|
116 |
+
<p><strong><?php printf( self::translate_escape( 'Total savings %s' ), size_format($savings["input"] - $savings["output"], 1)) ?></strong></p>
|
117 |
+
</div>
|
118 |
+
</div>
|
119 |
+
<?php } ?>
|
test/fixtures/input-large.jpg
ADDED
Binary file
|
test/fixtures/json/wp_meta_default_sizes.json
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"width": 1256,
|
3 |
+
"height": 1256,
|
4 |
+
"file": "2015/09/tinypng_gravatar.png",
|
5 |
+
"sizes": {
|
6 |
+
"thumbnail": {
|
7 |
+
"file": "tinypng_gravatar-150x150.png",
|
8 |
+
"width": 150,
|
9 |
+
"height": 150,
|
10 |
+
"mime-type": "image/png"
|
11 |
+
},
|
12 |
+
"medium": {
|
13 |
+
"file": "tinypng_gravatar-300x300.png",
|
14 |
+
"width": 300,
|
15 |
+
"height": 300,
|
16 |
+
"mime-type": "image/png"
|
17 |
+
},
|
18 |
+
"large": {
|
19 |
+
"file": "tinypng_gravatar-600x600.png",
|
20 |
+
"width": 600,
|
21 |
+
"height": 600,
|
22 |
+
"mime-type": "image/png"
|
23 |
+
}
|
24 |
+
},
|
25 |
+
"image_meta": {
|
26 |
+
}
|
27 |
+
}
|
test/fixtures/json/wp_meta_sizes_with_same_files.json
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"width": 1080,
|
3 |
+
"height": 720,
|
4 |
+
"file": "2015/09/panda.png",
|
5 |
+
"sizes": {
|
6 |
+
"custom-size": {
|
7 |
+
"file": "panda-150x150.png",
|
8 |
+
"width": 150,
|
9 |
+
"height": 150,
|
10 |
+
"mime-type": "image/png"
|
11 |
+
},
|
12 |
+
"custom-size-2": {
|
13 |
+
"file": "panda-150x150.png",
|
14 |
+
"width": 150,
|
15 |
+
"height": 150,
|
16 |
+
"mime-type": "image/png"
|
17 |
+
}
|
18 |
+
},
|
19 |
+
"image_meta": {
|
20 |
+
}
|
21 |
+
}
|
test/helpers/setup.php
CHANGED
@@ -103,8 +103,12 @@ function setup_wordpress_site($driver) {
|
|
103 |
}
|
104 |
$driver->findElement(WebDriverBy::name('weblog_title'))->sendKeys('Wordpress test');
|
105 |
$driver->findElement(WebDriverBy::name('user_name'))->clear()->sendKeys('admin');
|
106 |
-
|
107 |
-
|
|
|
|
|
|
|
|
|
108 |
$driver->findElement(WebDriverBy::name('admin_email'))->sendKeys('developers@voormedia.com');
|
109 |
$driver->findElement(WebDriverBy::tagName('form'))->submit();
|
110 |
$h1s = $driver->findElements(WebDriverBy::tagName('h1'));
|
@@ -118,13 +122,16 @@ function setup_wordpress_site($driver) {
|
|
118 |
}
|
119 |
|
120 |
function login($driver) {
|
|
|
121 |
$driver->get(wordpress('/wp-login.php'));
|
122 |
$driver->findElement(WebDriverBy::tagName('body'))->click();
|
123 |
$driver->findElement(WebDriverBy::name('log'))->clear()->click()->sendKeys('admin');
|
124 |
$driver->findElement(WebDriverBy::name('pwd'))->clear()->click()->sendKeys('admin');
|
125 |
$driver->findElement(WebDriverBy::tagName('form'))->submit();
|
126 |
-
|
127 |
-
|
|
|
|
|
128 |
} else {
|
129 |
var_dump($driver->getPageSource());
|
130 |
throw new UnexpectedValueException('Login failed.');
|
@@ -157,7 +164,6 @@ function reset_webservice() {
|
|
157 |
curl_setopt_array($request, array(
|
158 |
CURLOPT_URL => 'http://' . getenv('HOST_IP') .':8080/reset',
|
159 |
));
|
160 |
-
|
161 |
$response = curl_exec($request);
|
162 |
curl_close($request);
|
163 |
}
|
103 |
}
|
104 |
$driver->findElement(WebDriverBy::name('weblog_title'))->sendKeys('Wordpress test');
|
105 |
$driver->findElement(WebDriverBy::name('user_name'))->clear()->sendKeys('admin');
|
106 |
+
if (wordpress_version() > 42) {
|
107 |
+
$driver->findElement(WebDriverBy::id('pass1-text'))->clear()->sendKeys('a')->sendKeys('dmin');
|
108 |
+
} else {
|
109 |
+
$driver->findElement(WebDriverBy::name('admin_password'))->sendKeys('admin');
|
110 |
+
$driver->findElement(WebDriverBy::name('admin_password2'))->sendKeys('admin');
|
111 |
+
}
|
112 |
$driver->findElement(WebDriverBy::name('admin_email'))->sendKeys('developers@voormedia.com');
|
113 |
$driver->findElement(WebDriverBy::tagName('form'))->submit();
|
114 |
$h1s = $driver->findElements(WebDriverBy::tagName('h1'));
|
122 |
}
|
123 |
|
124 |
function login($driver) {
|
125 |
+
print "Logging in to WordPress... ";
|
126 |
$driver->get(wordpress('/wp-login.php'));
|
127 |
$driver->findElement(WebDriverBy::tagName('body'))->click();
|
128 |
$driver->findElement(WebDriverBy::name('log'))->clear()->click()->sendKeys('admin');
|
129 |
$driver->findElement(WebDriverBy::name('pwd'))->clear()->click()->sendKeys('admin');
|
130 |
$driver->findElement(WebDriverBy::tagName('form'))->submit();
|
131 |
+
|
132 |
+
$dashboardHeading = $driver->findElement(WebDriverBy::xpath("//html/body//div[@class='wrap']/*[self::h1 or self::h2]"));
|
133 |
+
if ($dashboardHeading->getText() == 'Dashboard') {
|
134 |
+
print "success!\n";
|
135 |
} else {
|
136 |
var_dump($driver->getPageSource());
|
137 |
throw new UnexpectedValueException('Login failed.');
|
164 |
curl_setopt_array($request, array(
|
165 |
CURLOPT_URL => 'http://' . getenv('HOST_IP') .':8080/reset',
|
166 |
));
|
|
|
167 |
$response = curl_exec($request);
|
168 |
curl_close($request);
|
169 |
}
|
test/helpers/wordpress.php
CHANGED
@@ -136,6 +136,10 @@ class WordPressStubs {
|
|
136 |
$this->metadata[$id][$key] = $values;
|
137 |
}
|
138 |
|
|
|
|
|
|
|
|
|
139 |
public function getCalls($method) {
|
140 |
return $this->calls[$method];
|
141 |
}
|
@@ -156,9 +160,20 @@ class WordPressStubs {
|
|
156 |
$this->stubs[$method] = $func;
|
157 |
}
|
158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
public function createImages($sizes=null, $original_size=12345, $path='14/01', $name='test') {
|
160 |
vfsStream::newDirectory(self::UPLOAD_DIR . "/$path")->at($this->vfs);
|
161 |
-
$dir = $this->vfs->getChild(self::UPLOAD_DIR . "
|
162 |
|
163 |
vfsStream::newFile("$name.png")
|
164 |
->withContent(new LargeFileContent($original_size))
|
@@ -175,8 +190,36 @@ class WordPressStubs {
|
|
175 |
}
|
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");
|
136 |
$this->metadata[$id][$key] = $values;
|
137 |
}
|
138 |
|
139 |
+
public function setMetadata($id, $values) {
|
140 |
+
$this->metadata[$id] = $values;
|
141 |
+
}
|
142 |
+
|
143 |
public function getCalls($method) {
|
144 |
return $this->calls[$method];
|
145 |
}
|
160 |
$this->stubs[$method] = $func;
|
161 |
}
|
162 |
|
163 |
+
public function createImage($file_size, $path, $name) {
|
164 |
+
if (!$this->vfs->hasChild(self::UPLOAD_DIR . "/$path")) {
|
165 |
+
vfsStream::newDirectory(self::UPLOAD_DIR . "/$path")->at($this->vfs);
|
166 |
+
}
|
167 |
+
$dir = $this->vfs->getChild(self::UPLOAD_DIR . "/$path");
|
168 |
+
|
169 |
+
vfsStream::newFile($name)
|
170 |
+
->withContent(new LargeFileContent($file_size))
|
171 |
+
->at($dir);
|
172 |
+
}
|
173 |
+
|
174 |
public function createImages($sizes=null, $original_size=12345, $path='14/01', $name='test') {
|
175 |
vfsStream::newDirectory(self::UPLOAD_DIR . "/$path")->at($this->vfs);
|
176 |
+
$dir = $this->vfs->getChild(self::UPLOAD_DIR . "/" . $path);
|
177 |
|
178 |
vfsStream::newFile("$name.png")
|
179 |
->withContent(new LargeFileContent($original_size))
|
190 |
}
|
191 |
}
|
192 |
|
193 |
+
public function createImagesFromMeta($wp_meta, $tiny_meta, $original_size = 1234567) {
|
194 |
+
$parts = explode("/", $wp_meta["file"]);
|
195 |
+
$file = array_pop($parts);
|
196 |
+
$path = implode("/", $parts);
|
197 |
+
|
198 |
+
vfsStream::newDirectory(self::UPLOAD_DIR . "/$path")->at($this->vfs);
|
199 |
+
$dir = $this->vfs->getChild(self::UPLOAD_DIR . "/" . $path);
|
200 |
+
|
201 |
+
vfsStream::newFile($file)
|
202 |
+
->withContent(new LargeFileContent($original_size))
|
203 |
+
->at($dir);
|
204 |
+
|
205 |
+
foreach ($wp_meta["sizes"] as $image_size => $values) {
|
206 |
+
if (isset($tiny_meta[Tiny_Metadata::META_KEY][$image_size])) {
|
207 |
+
$file_size = $tiny_meta[Tiny_Metadata::META_KEY][$image_size]["output"]["size"];
|
208 |
+
vfsStream::newFile($values["file"])
|
209 |
+
->withContent(new LargeFileContent($file_size))
|
210 |
+
->at($dir);
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
+
}
|
215 |
+
|
216 |
public function getTestMetadata($path='14/01', $name='test') {
|
217 |
+
$metadata = array(
|
218 |
+
'file' => "$path/$name.png",
|
219 |
+
'width' => 4000,
|
220 |
+
'height' => 3000,
|
221 |
+
'sizes' => array()
|
222 |
+
);
|
223 |
|
224 |
$regex = '#^' . preg_quote($name) .'-([^.]+)[.](png|jpe?g)$#';
|
225 |
$dir = $this->vfs->getChild(self::UPLOAD_DIR . "/$path");
|
test/integration/BulkCompressIntegrationTest.php
CHANGED
@@ -35,7 +35,7 @@ class BulkCompressIntegrationTest extends IntegrationTestCase {
|
|
35 |
$this->enable_compression_sizes(array('thumbnail', 'medium', 'large'));
|
36 |
}
|
37 |
|
38 |
-
public function
|
39 |
$this->prepare(1, 2);
|
40 |
|
41 |
self::$driver->get(wordpress('/wp-admin/upload.php?orderby=title&order=asc'));
|
@@ -55,7 +55,7 @@ class BulkCompressIntegrationTest extends IntegrationTestCase {
|
|
55 |
public function testBulkCompressShouldCompressAll() {
|
56 |
$this->prepare(1, 1);
|
57 |
|
58 |
-
self::$driver->get(wordpress('/wp-admin/
|
59 |
$elements = self::$driver->findElements(WebDriverBy::cssSelector('#tiny-bulk-compress p'));
|
60 |
$this->assertContains('2 images', $elements[1]->getText());
|
61 |
|
35 |
$this->enable_compression_sizes(array('thumbnail', 'medium', 'large'));
|
36 |
}
|
37 |
|
38 |
+
public function testBulkCompressFromMediaShouldOnlyCompressSelected() {
|
39 |
$this->prepare(1, 2);
|
40 |
|
41 |
self::$driver->get(wordpress('/wp-admin/upload.php?orderby=title&order=asc'));
|
55 |
public function testBulkCompressShouldCompressAll() {
|
56 |
$this->prepare(1, 1);
|
57 |
|
58 |
+
self::$driver->get(wordpress('/wp-admin/upload.php?page=tiny-bulk-compress.php'));
|
59 |
$elements = self::$driver->findElements(WebDriverBy::cssSelector('#tiny-bulk-compress p'));
|
60 |
$this->assertContains('2 images', $elements[1]->getText());
|
61 |
|
test/integration/CompressIntegrationTest.php
CHANGED
@@ -26,13 +26,13 @@ class CompressIntegrationTest extends IntegrationTestCase {
|
|
26 |
$this->set_api_key('1234');
|
27 |
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-example.png');
|
28 |
$this->assertContains('Latest error: Credentials are invalid',
|
29 |
-
self::$driver->findElement(WebDriverBy::cssSelector('span.
|
30 |
}
|
31 |
|
32 |
public function testShrink() {
|
33 |
$this->set_api_key('PNG123');
|
34 |
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-example.png');
|
35 |
-
$this->assertContains('
|
36 |
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
|
37 |
}
|
38 |
|
@@ -43,11 +43,13 @@ class CompressIntegrationTest extends IntegrationTestCase {
|
|
43 |
$this->enable_compression_sizes(array('medium', 'large'));
|
44 |
|
45 |
self::$driver->get(wordpress('/wp-admin/upload.php'));
|
46 |
-
$this->assertContains('
|
|
|
|
|
47 |
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
|
48 |
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images button'))->click();
|
49 |
self::$driver->wait(2)->until(WebDriverExpectedCondition::textToBePresentInElement(
|
50 |
-
WebDriverBy::cssSelector('td.tiny-compress-images'), '
|
51 |
}
|
52 |
|
53 |
public function testLimitReached() {
|
@@ -67,4 +69,68 @@ class CompressIntegrationTest extends IntegrationTestCase {
|
|
67 |
self::$driver->get(wordpress('/wp-admin/options-media.php'));
|
68 |
$this->assertEquals(0, count(self::$driver->findElements(WebDriverBy::cssSelector('div.error p'))));
|
69 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
}
|
26 |
$this->set_api_key('1234');
|
27 |
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-example.png');
|
28 |
$this->assertContains('Latest error: Credentials are invalid',
|
29 |
+
self::$driver->findElement(WebDriverBy::cssSelector('span.details'))->getText());
|
30 |
}
|
31 |
|
32 |
public function testShrink() {
|
33 |
$this->set_api_key('PNG123');
|
34 |
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-example.png');
|
35 |
+
$this->assertContains('sizes compressed',
|
36 |
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
|
37 |
}
|
38 |
|
43 |
$this->enable_compression_sizes(array('medium', 'large'));
|
44 |
|
45 |
self::$driver->get(wordpress('/wp-admin/upload.php'));
|
46 |
+
$this->assertContains('1 size compressed',
|
47 |
+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
|
48 |
+
$this->assertContains('1 size not compressed',
|
49 |
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
|
50 |
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images button'))->click();
|
51 |
self::$driver->wait(2)->until(WebDriverExpectedCondition::textToBePresentInElement(
|
52 |
+
WebDriverBy::cssSelector('td.tiny-compress-images'), '2 sizes compressed'));
|
53 |
}
|
54 |
|
55 |
public function testLimitReached() {
|
69 |
self::$driver->get(wordpress('/wp-admin/options-media.php'));
|
70 |
$this->assertEquals(0, count(self::$driver->findElements(WebDriverBy::cssSelector('div.error p'))));
|
71 |
}
|
72 |
+
|
73 |
+
public function testIncorrectJsonButton() {
|
74 |
+
$this->enable_compression_sizes(array());
|
75 |
+
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-example.png');
|
76 |
+
$this->enable_compression_sizes(array('medium', 'large'));
|
77 |
+
|
78 |
+
$this->set_api_key('JSON1234');
|
79 |
+
self::$driver->get(wordpress('/wp-admin/upload.php'));
|
80 |
+
|
81 |
+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images button'))->click();
|
82 |
+
self::$driver->wait(2)->until(WebDriverExpectedCondition::textToBePresentInElement(
|
83 |
+
WebDriverBy::cssSelector('td.tiny-compress-images'), 'JSON: Syntax error [4]'));
|
84 |
+
}
|
85 |
+
|
86 |
+
public function testResizeFit() {
|
87 |
+
$this->set_api_key('JPG123');
|
88 |
+
$this->enable_resize(300, 200);
|
89 |
+
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-large.png');
|
90 |
+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images a.thickbox'))->click();
|
91 |
+
$this->assertContains('resized to 300x200',
|
92 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.tiny-compression-details'))->getText());
|
93 |
+
$this->view_edit_image();
|
94 |
+
$this->assertContains('Dimensions: 300 × 200',
|
95 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.misc-pub-dimensions'))->getText());
|
96 |
+
}
|
97 |
+
|
98 |
+
public function testResizeScale() {
|
99 |
+
$this->set_api_key('JPG123');
|
100 |
+
$this->enable_resize(0, 200);
|
101 |
+
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-large.jpg');
|
102 |
+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images a.thickbox'))->click();
|
103 |
+
$this->assertContains('resized to 300x200', self::$driver->findElement(
|
104 |
+
WebDriverBy::cssSelector('div.tiny-compression-details'))->getText());
|
105 |
+
$this->view_edit_image();
|
106 |
+
$this->assertContains('Dimensions: 300 × 200',
|
107 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.misc-pub-dimensions'))->getText());
|
108 |
+
}
|
109 |
+
|
110 |
+
public function testResizeNotNeeded()
|
111 |
+
{
|
112 |
+
$this->set_api_key('JPG123');
|
113 |
+
$this->enable_resize(30000, 20000);
|
114 |
+
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-large.jpg');
|
115 |
+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images a.thickbox'))->click();
|
116 |
+
$this->assertNotContains('resized',
|
117 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.tiny-compression-details'))->getText());
|
118 |
+
$this->view_edit_image();
|
119 |
+
$this->assertContains('Dimensions: 1080 × 330',
|
120 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.misc-pub-dimensions'))->getText());
|
121 |
+
}
|
122 |
+
|
123 |
+
public function testResizeDisabled()
|
124 |
+
{
|
125 |
+
$this->set_api_key('JPG123');
|
126 |
+
$this->enable_resize(300, 200);
|
127 |
+
$this->disable_resize();
|
128 |
+
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-large.jpg');
|
129 |
+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images a.thickbox'))->click();
|
130 |
+
$this->assertNotContains('resized',
|
131 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.tiny-compression-details'))->getText());
|
132 |
+
$this->view_edit_image();
|
133 |
+
$this->assertContains('Dimensions: 1080 × 330',
|
134 |
+
self::$driver->findElement(WebDriverBy::cssSelector('div.misc-pub-dimensions'))->getText());
|
135 |
+
}
|
136 |
}
|
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/PluginIntegrationTest.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once(dirname(__FILE__) . "/IntegrationTestCase.php");
|
4 |
+
|
5 |
+
class PluginIntegrationTest extends IntegrationTestCase {
|
6 |
+
|
7 |
+
public function setUp() {
|
8 |
+
parent::setUp();
|
9 |
+
self::$driver->get(wordpress('/wp-admin/plugins.php'));
|
10 |
+
}
|
11 |
+
|
12 |
+
public function tearDown() {
|
13 |
+
clear_settings();
|
14 |
+
}
|
15 |
+
|
16 |
+
public function testTitlePresence()
|
17 |
+
{
|
18 |
+
$element = self::$driver->findElements(WebDriverBy::xpath('//*[@id="compress-jpeg-png-images"]//a[text()="Settings"]'));
|
19 |
+
$this->assertStringEndsWith('options-media.php#tiny-compress-images', $element[0]->getAttribute('href'));
|
20 |
+
}
|
21 |
+
}
|
test/integration/SettingsIntegrationTest.php
CHANGED
@@ -86,9 +86,73 @@ class SettingsIntegrationTest extends IntegrationTestCase {
|
|
86 |
$this->assertEquals(0, count(array_map('elementName', $elements)));
|
87 |
}
|
88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
public function testStatusPresenceOK() {
|
90 |
reset_webservice();
|
91 |
$this->set_api_key('PNG123');
|
|
|
92 |
$elements = self::$driver->findElement(WebDriverBy::id('tiny-compress-status'))->findElements(WebDriverBy::tagName('p'));
|
93 |
$statuses = array_map('innerText', $elements);
|
94 |
$this->assertContains('API connection successful', $statuses);
|
@@ -97,8 +161,28 @@ class SettingsIntegrationTest extends IntegrationTestCase {
|
|
97 |
|
98 |
public function testStatusPresenseFail() {
|
99 |
$this->set_api_key('INVALID123');
|
|
|
100 |
$elements = self::$driver->findElement(WebDriverBy::id('tiny-compress-status'))->findElements(WebDriverBy::tagName('p'));
|
101 |
$statuses = array_map('innerText', $elements);
|
102 |
-
$this->assertContains('API connection unsuccessful', $statuses);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
}
|
104 |
}
|
86 |
$this->assertEquals(0, count(array_map('elementName', $elements)));
|
87 |
}
|
88 |
|
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 at least 100 images for free each month.', $statuses);
|
93 |
+
}
|
94 |
+
|
95 |
+
public function testShouldUpdateTotalImagesInfo() {
|
96 |
+
$element = self::$driver->findElement(
|
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 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('With these settings you can compress at least 125 images for free each month.', $statuses);
|
105 |
+
}
|
106 |
+
|
107 |
+
public function testShouldShowCorrectNoImageSizesInfo() {
|
108 |
+
$elements = self::$driver->findElements(
|
109 |
+
WebDriverBy::xpath('//input[@type="checkbox" and starts-with(@name, "tinypng_sizes") and @checked="checked"]'));
|
110 |
+
foreach ($elements as $element) {
|
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 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 |
+
self::$driver->wait(1)->until(WebDriverExpectedCondition::textToBePresentInElement(
|
140 |
+
WebDriverBy::cssSelector('p.tiny-resize-unavailable'), 'Enable the compression of the original image size to configure resizing.'));
|
141 |
+
$labels = self::$driver->findElements(WebDriverBy::tagName('label'));
|
142 |
+
$texts = array_map('innerText', $labels);
|
143 |
+
$this->assertNotContains('Resize and compress orginal images to fit within:', $texts);
|
144 |
+
}
|
145 |
+
|
146 |
+
public function testShouldPersistResizingSettings() {
|
147 |
+
$this->enable_resize(123, 456);
|
148 |
+
$this->assertEquals('123', self::$driver->findElement(WebDriverBy::id('tinypng_resize_original_width'))->getAttribute('value'));
|
149 |
+
$this->assertEquals('456', self::$driver->findElement(WebDriverBy::id('tinypng_resize_original_height'))->getAttribute('value'));
|
150 |
+
}
|
151 |
+
|
152 |
public function testStatusPresenceOK() {
|
153 |
reset_webservice();
|
154 |
$this->set_api_key('PNG123');
|
155 |
+
self::$driver->wait(2)->until(WebDriverExpectedCondition::presenceOfElementLocated(WebDriverBy::cssSelector('#tiny-compress-status p')));
|
156 |
$elements = self::$driver->findElement(WebDriverBy::id('tiny-compress-status'))->findElements(WebDriverBy::tagName('p'));
|
157 |
$statuses = array_map('innerText', $elements);
|
158 |
$this->assertContains('API connection successful', $statuses);
|
161 |
|
162 |
public function testStatusPresenseFail() {
|
163 |
$this->set_api_key('INVALID123');
|
164 |
+
self::$driver->wait(2)->until(WebDriverExpectedCondition::presenceOfElementLocated(WebDriverBy::cssSelector('#tiny-compress-status p')));
|
165 |
$elements = self::$driver->findElement(WebDriverBy::id('tiny-compress-status'))->findElements(WebDriverBy::tagName('p'));
|
166 |
$statuses = array_map('innerText', $elements);
|
167 |
+
$this->assertContains('API connection unsuccessful', $statuses[0]);
|
168 |
+
}
|
169 |
+
|
170 |
+
public function testShouldShowBulkCompressionLink() {
|
171 |
+
reset_webservice();
|
172 |
+
self::$driver->wait(2)->until(WebDriverExpectedCondition::presenceOfElementLocated(WebDriverBy::cssSelector('#tiny-compress-savings p')));
|
173 |
+
$elements = self::$driver->findElement(WebDriverBy::id('tiny-compress-savings'))->findElements(WebDriverBy::tagName('p'));
|
174 |
+
$statuses = array_map('innerText', $elements);
|
175 |
+
$this->assertContains('No images compressed yet. Use Compress All Images to compress existing images.', $statuses);
|
176 |
+
}
|
177 |
+
|
178 |
+
public function testShouldShowSavings() {
|
179 |
+
reset_webservice();
|
180 |
+
$this->set_api_key('PNG123');
|
181 |
+
$this->upload_image(dirname(__FILE__) . '/../fixtures/input-example.png');
|
182 |
+
self::$driver->get(wordpress('/wp-admin/options-media.php'));
|
183 |
+
self::$driver->wait(2)->until(WebDriverExpectedCondition::presenceOfElementLocated(WebDriverBy::cssSelector('#tiny-compress-savings p')));
|
184 |
+
$elements = self::$driver->findElement(WebDriverBy::id('tiny-compress-savings'))->findElements(WebDriverBy::tagName('p'));
|
185 |
+
$statuses = array_map('innerText', $elements);
|
186 |
+
$this->assertContains('You have saved a total of 53.0 kB on images!', $statuses);
|
187 |
}
|
188 |
}
|
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 |
|
@@ -94,13 +78,18 @@ function mock_limit_reached_response() {
|
|
94 |
return json_encode($response);
|
95 |
}
|
96 |
|
97 |
-
|
98 |
-
|
99 |
-
$api_key_elements = explode(':', $basic_auth);
|
100 |
-
$api_key = $api_key_elements[1];
|
101 |
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
|
|
|
104 |
if ($api_key == 'PNG123') {
|
105 |
if (intval($_SERVER['CONTENT_LENGTH']) == 0) {
|
106 |
echo mock_empty_response();
|
@@ -113,12 +102,16 @@ if ($api_key == 'PNG123') {
|
|
113 |
} else {
|
114 |
echo mock_jpg_response();
|
115 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
} else if ($api_key == 'LIMIT123') {
|
117 |
echo mock_limit_reached_response();
|
118 |
} else {
|
119 |
echo mock_invalid_response();
|
120 |
}
|
121 |
|
122 |
-
|
123 |
-
|
124 |
-
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 |
|
78 |
return json_encode($response);
|
79 |
}
|
80 |
|
81 |
+
function mock_invalid_json_response() {
|
82 |
+
global $session;
|
|
|
|
|
83 |
|
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();
|
102 |
} else {
|
103 |
echo mock_jpg_response();
|
104 |
}
|
105 |
+
} else if ($api_key == 'JSON1234') {
|
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();
|
113 |
} else {
|
114 |
echo mock_invalid_response();
|
115 |
}
|
116 |
|
117 |
+
ob_end_flush();
|
|
|
|
test/unit/TinyMetadataTest.php
ADDED
@@ -0,0 +1,279 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once(dirname(__FILE__) . "/TinyTestCase.php");
|
4 |
+
|
5 |
+
class Tiny_Metadata_Test extends TinyTestCase {
|
6 |
+
public function setUp() {
|
7 |
+
parent::setUp();
|
8 |
+
|
9 |
+
$this->wp->addOption("tinypng_api_key", "test123");
|
10 |
+
$this->wp->addOption("tinypng_sizes[0]", "on");
|
11 |
+
|
12 |
+
$meta = array(Tiny_Metadata::META_KEY => array(
|
13 |
+
Tiny_Metadata::ORIGINAL => array(
|
14 |
+
"input" => array("size" => 146480),
|
15 |
+
"output" => array("size" => 137856)),
|
16 |
+
"thumbnail" => array(
|
17 |
+
"input" => array("size" => 46480),
|
18 |
+
"output" => array("size" => 37856)),
|
19 |
+
"medium" => array(
|
20 |
+
"input" => array("size" => 66480),
|
21 |
+
"output" => array("size" => 57856))
|
22 |
+
));
|
23 |
+
$this->wp->setMetadata(1, $meta);
|
24 |
+
$this->wp->createImagesFromMeta($this->json("wp_meta_default_sizes"), $meta, 137856);
|
25 |
+
$this->subject = new Tiny_Metadata(1, $this->json("wp_meta_default_sizes"));
|
26 |
+
}
|
27 |
+
|
28 |
+
public function testUpdateWpMetadataShouldNotUpdateWithNoResizedOriginal() {
|
29 |
+
$tiny_meta = new Tiny_Metadata(150, $this->json("wp_meta_sizes_with_same_files"));
|
30 |
+
$wp_metadata = array(
|
31 |
+
'width' => 2000,
|
32 |
+
'height' => 1000
|
33 |
+
);
|
34 |
+
$this->assertEquals(array('width' => 2000, 'height' => 1000), $tiny_meta->update_wp_metadata($wp_metadata));
|
35 |
+
}
|
36 |
+
|
37 |
+
public function testUpdateWpMetadataShouldUpdateWithResizedOriginal() {
|
38 |
+
$tiny_meta = new Tiny_Metadata(150, $this->json("wp_meta_sizes_with_same_files"));
|
39 |
+
$wp_metadata = array(
|
40 |
+
'width' => 2000,
|
41 |
+
'height' => 1000
|
42 |
+
);
|
43 |
+
$tiny_meta->add_request();
|
44 |
+
$tiny_meta->add_response(array('output' => array('width' => 200, 'height' => 100)));
|
45 |
+
$this->assertEquals(array('width' => 200, 'height' => 100), $tiny_meta->update_wp_metadata($wp_metadata));
|
46 |
+
}
|
47 |
+
|
48 |
+
public function testAddRequestShouldIncreaseProccessingCount() {
|
49 |
+
$processing_count = $this->subject->get_in_progress_count();
|
50 |
+
$this->subject->add_request("large");
|
51 |
+
$this->assertEquals($processing_count + 1, $this->subject->get_in_progress_count());
|
52 |
+
}
|
53 |
+
|
54 |
+
public function testAddRequestShouldIncreaseProccessingCountEvenIfAlreadyCompressed() {
|
55 |
+
$processing_count = $this->subject->get_in_progress_count();
|
56 |
+
$this->subject->add_request("thumbnail");
|
57 |
+
$this->assertEquals($processing_count + 1, $this->subject->get_in_progress_count());
|
58 |
+
}
|
59 |
+
|
60 |
+
public function testAddRequestShouldNotIncreaseSuccessCount() {
|
61 |
+
$success_count = $this->subject->get_success_count();
|
62 |
+
$this->subject->add_request("large");
|
63 |
+
$this->assertEquals($success_count, $this->subject->get_success_count());
|
64 |
+
}
|
65 |
+
|
66 |
+
public function testAddResponseShouldIncreaseSuccessCountForCompression() {
|
67 |
+
$success_count = $this->subject->get_success_count();
|
68 |
+
$this->subject->add_request("large");
|
69 |
+
$this->subject->add_response(array("output" => array("size" => 137857)), "large");
|
70 |
+
$this->wp->createImage(137857, "2015/09", "tinypng_gravatar-600x600.png");
|
71 |
+
$this->assertEquals($success_count + 1, $this->subject->get_success_count());
|
72 |
+
}
|
73 |
+
|
74 |
+
public function testAddResponseShouldNotIncreaseSuccessCountIfPhysicalFileIsMissing() {
|
75 |
+
$success_count = $this->subject->get_success_count();
|
76 |
+
$this->subject->add_request("large");
|
77 |
+
$this->subject->add_response(array("output" => array("size" => 137857)), "large");
|
78 |
+
$this->assertEquals($success_count, $this->subject->get_success_count());
|
79 |
+
}
|
80 |
+
|
81 |
+
public function testAddResponseShouldIncreaseCompressedCount() {
|
82 |
+
$compressed_count = count($this->subject->get_compressed_sizes());
|
83 |
+
$this->subject->add_request("large");
|
84 |
+
$this->subject->add_response(array("output" => array("size" => 137857)), "large");
|
85 |
+
$this->wp->createImage(137857, "2015/09", "tinypng_gravatar-600x600.png");
|
86 |
+
$this->assertEquals($compressed_count + 1, count($this->subject->get_compressed_sizes()));
|
87 |
+
}
|
88 |
+
|
89 |
+
public function testAddResponseShouldIncreaseCompressedCountIfPhysicalFileIsMissing() {
|
90 |
+
$compressed_count = count($this->subject->get_compressed_sizes());
|
91 |
+
$this->subject->add_request("large");
|
92 |
+
$this->subject->add_response(array("output" => array("size" => 137857)), "large");
|
93 |
+
$this->assertEquals($compressed_count + 1, count($this->subject->get_compressed_sizes()));
|
94 |
+
}
|
95 |
+
|
96 |
+
public function testAddResponseShouldNotIncreaseProcessingCount() {
|
97 |
+
$processing_count = $this->subject->get_in_progress_count();
|
98 |
+
$this->subject->add_request("large");
|
99 |
+
$this->subject->add_response(array("output" => array("size" => 137857)), "large");
|
100 |
+
$this->wp->createImage(137857, "2015/09", "tinypng_gravatar-600x600.png");
|
101 |
+
$this->assertEquals($processing_count, $this->subject->get_in_progress_count());
|
102 |
+
}
|
103 |
+
|
104 |
+
public function testAddExceptionShouldNotIncreaseSuccessCount() {
|
105 |
+
$success_count = $this->subject->get_success_count();
|
106 |
+
$this->subject->add_request("large");
|
107 |
+
$this->subject->add_exception(new Tiny_Exception('Could not download output', 'OutputError'), "large");
|
108 |
+
$this->assertEquals($success_count, $this->subject->get_success_count());
|
109 |
+
}
|
110 |
+
|
111 |
+
public function testAddExceptionShouldNotIncreaseProcessingCount() {
|
112 |
+
$processing_count = $this->subject->get_in_progress_count();
|
113 |
+
$this->subject->add_request("large");
|
114 |
+
$this->subject->add_exception(new Tiny_Exception('Could not download output', 'OutputError'), "large");
|
115 |
+
$this->assertEquals($processing_count, $this->subject->get_in_progress_count());
|
116 |
+
}
|
117 |
+
|
118 |
+
public function testIsCompressedShouldReturnTrueForOriginal() {
|
119 |
+
$this->assertTrue($this->subject->is_compressed(Tiny_Metadata::ORIGINAL));
|
120 |
+
}
|
121 |
+
|
122 |
+
public function testIsCompressedShouldReturnTrueForCompressedSize() {
|
123 |
+
$this->assertTrue($this->subject->is_compressed("thumbnail"));
|
124 |
+
}
|
125 |
+
|
126 |
+
public function testIsCompressedShouldReturnFalseForUncompressedSize() {
|
127 |
+
$this->assertFalse($this->subject->is_compressed("large"));
|
128 |
+
}
|
129 |
+
|
130 |
+
public function testIsCompressedShouldReturnFalseWhenFilesizeOnFilesystemDoesNotMatchMeta() {
|
131 |
+
$meta = array(Tiny_Metadata::META_KEY => array(
|
132 |
+
"thumbnail" => array(
|
133 |
+
"input" => array("size" => 46480),
|
134 |
+
"output" => array("size" => 37856))
|
135 |
+
));
|
136 |
+
$this->wp->setMetadata(2, $meta);
|
137 |
+
$this->wp->createImage(37857, "2015/09", "tinypng_gravatar-150x150.png");
|
138 |
+
$tiny_meta = new Tiny_Metadata(2, $this->json("wp_meta_default_sizes"));
|
139 |
+
$this->assertFalse($tiny_meta->is_compressed("thumbnail"));
|
140 |
+
}
|
141 |
+
|
142 |
+
public function testIsCompressedShouldReturnFalseWhenFileDoesNotExist() {
|
143 |
+
$meta = array(Tiny_Metadata::META_KEY => array(
|
144 |
+
"no_file" => array(
|
145 |
+
"input" => array("size" => 46480),
|
146 |
+
"output" => array("size" => 37856))
|
147 |
+
));
|
148 |
+
$this->wp->setMetadata(3, $meta);
|
149 |
+
$tiny_meta = new Tiny_Metadata(3, $this->json("wp_meta_default_sizes"));
|
150 |
+
$this->assertFalse($tiny_meta->is_compressed("no_file"));
|
151 |
+
}
|
152 |
+
|
153 |
+
public function testIsCompressedShouldReturnFalseWhenNoMetadata() {
|
154 |
+
$this->wp->createImage(37856, "2015/09", "tinypng_gravatar-150x150.png");
|
155 |
+
$tiny_meta = new Tiny_Metadata(4, $this->json("wp_meta_default_sizes"));
|
156 |
+
$this->assertFalse($tiny_meta->is_compressed("thumbnail"));
|
157 |
+
}
|
158 |
+
|
159 |
+
public function testIsCompressingShouldReturnTrue() {
|
160 |
+
$meta = array(Tiny_Metadata::META_KEY => array(
|
161 |
+
"thumbnail" => array(
|
162 |
+
"start" => 1447925134,
|
163 |
+
"input" => array("size" => 46480))
|
164 |
+
));
|
165 |
+
$this->wp->setMetadata(5, $meta);
|
166 |
+
$this->wp->createImage(46480, "2015/09", "tinypng_gravatar-150x150.png");
|
167 |
+
$tiny_meta = new Tiny_Metadata(5, $this->json("wp_meta_default_sizes"));
|
168 |
+
$this->assertTrue($tiny_meta->is_compressing("thumbnail"));
|
169 |
+
}
|
170 |
+
|
171 |
+
public function testIsCompressingShouldReturnFalse() {
|
172 |
+
$this->assertFalse($this->subject->is_compressing("thumbnail"));
|
173 |
+
}
|
174 |
+
|
175 |
+
public function testIsResizedShouldReturnTrueForResizedImage() {
|
176 |
+
$meta = array(Tiny_Metadata::META_KEY => array(
|
177 |
+
Tiny_Metadata::ORIGINAL => array(
|
178 |
+
"output" => array("size" => 46480, "resized" => true))
|
179 |
+
));
|
180 |
+
$this->wp->setMetadata(7, $meta);
|
181 |
+
$tiny_meta = new Tiny_Metadata(7, $this->json("wp_meta_default_sizes"));
|
182 |
+
$this->assertTrue($tiny_meta->is_resized());
|
183 |
+
}
|
184 |
+
|
185 |
+
public function testIsResizedShouldReturnFalseForNotResizedSize() {
|
186 |
+
$this->assertFalse($this->subject->is_resized("thumbnail"));
|
187 |
+
}
|
188 |
+
|
189 |
+
public function testGetSizes() {
|
190 |
+
$this->assertEquals(
|
191 |
+
array(Tiny_Metadata::ORIGINAL, "thumbnail", "medium", "large"),
|
192 |
+
$this->subject->get_sizes());
|
193 |
+
}
|
194 |
+
|
195 |
+
public function testGetSizesWithDuplicates() {
|
196 |
+
$tiny_meta = new Tiny_Metadata(150, $this->json("wp_meta_sizes_with_same_files"));
|
197 |
+
$this->assertEquals(
|
198 |
+
array(Tiny_Metadata::ORIGINAL, "custom-size"),
|
199 |
+
$tiny_meta->get_sizes());
|
200 |
+
}
|
201 |
+
|
202 |
+
public function testGetSuccessSizes() {
|
203 |
+
$this->assertEquals(array(0, "thumbnail", "medium"), $this->subject->get_success_sizes());
|
204 |
+
}
|
205 |
+
|
206 |
+
public function testGetSuccessSizesShouldNotIncludeSizeIfNotOnFileSystem() {
|
207 |
+
$meta = array(Tiny_Metadata::META_KEY => array(
|
208 |
+
"additional_size" => array(
|
209 |
+
"start" => 1447925134,
|
210 |
+
"end" => 1447925138,
|
211 |
+
"input" => array("size" => 46480),
|
212 |
+
"output" => array("size" => 37856))
|
213 |
+
));
|
214 |
+
$this->wp->setMetadata(6, $meta);
|
215 |
+
$tiny_meta = new Tiny_Metadata(6, $this->json("wp_meta_default_sizes"));
|
216 |
+
$this->assertEquals(array(), $tiny_meta->get_success_sizes());
|
217 |
+
}
|
218 |
+
|
219 |
+
public function testGetCompressedSizes() {
|
220 |
+
$this->assertEquals(array(0, "thumbnail", "medium"), $this->subject->get_compressed_sizes());
|
221 |
+
}
|
222 |
+
|
223 |
+
public function testGetCompressedSizesShouldIncludeSizeEvenIfNotOnFileSystem() {
|
224 |
+
$meta = array(Tiny_Metadata::META_KEY => array(
|
225 |
+
"additional_size" => array(
|
226 |
+
"start" => 1447925134,
|
227 |
+
"end" => 1447925138,
|
228 |
+
"input" => array("size" => 46480),
|
229 |
+
"output" => array("size" => 37856))
|
230 |
+
));
|
231 |
+
$this->wp->setMetadata(6, $meta);
|
232 |
+
$tiny_meta = new Tiny_Metadata(6, $this->json("wp_meta_default_sizes"));
|
233 |
+
$this->assertEquals(array("additional_size"), $tiny_meta->get_compressed_sizes());
|
234 |
+
}
|
235 |
+
|
236 |
+
public function testGetUncompressedSizes() {
|
237 |
+
$this->wp->createImage(137857, "2015/09", "tinypng_gravatar-600x600.png");
|
238 |
+
$tinify_sizes = array(Tiny_Metadata::ORIGINAL, "thumbnail", "medium", "large");
|
239 |
+
$this->assertEquals(
|
240 |
+
array_values(array("large")),
|
241 |
+
array_values($this->subject->get_uncompressed_sizes($tinify_sizes)));
|
242 |
+
}
|
243 |
+
|
244 |
+
public function testGetUncompressedSizesShouldReturnOnlyUniqueSizes() {
|
245 |
+
$this->wp->addOption("tinypng_sizes[custom-size]", "on");
|
246 |
+
$this->wp->addOption("tinypng_sizes[custom-size-2]", "on");
|
247 |
+
$this->wp->addImageSize('custom-size', array('width' => 150, 'height' => 150));
|
248 |
+
$this->wp->addImageSize('custom-size-2', array('width' => 150, 'height' => 150));
|
249 |
+
$this->wp->createImages(array("150x150" => 37856), 146480, "2015/09", "panda");
|
250 |
+
|
251 |
+
$tiny_meta = new Tiny_Metadata(155, $this->json("wp_meta_sizes_with_same_files"));
|
252 |
+
|
253 |
+
$tinify_sizes = array(Tiny_Metadata::ORIGINAL, "custom-size", "custom-size-2");
|
254 |
+
$uncompressed_sizes = array(Tiny_Metadata::ORIGINAL, "custom-size");
|
255 |
+
$this->assertEquals($uncompressed_sizes, $tiny_meta->get_uncompressed_sizes($tinify_sizes));
|
256 |
+
}
|
257 |
+
|
258 |
+
public function testGetInProgressSizesShouldReturnEmptyArray() {
|
259 |
+
$this->assertEquals(array(), $this->subject->get_in_progress_sizes());
|
260 |
+
}
|
261 |
+
|
262 |
+
public function testGetInProgressSizesShouldReturnSizeBeingCompressed() {
|
263 |
+
$meta = array(Tiny_Metadata::META_KEY => array(
|
264 |
+
"thumbnail" => array(
|
265 |
+
"start" => 1447925134,
|
266 |
+
"input" => array("size" => 46480))
|
267 |
+
));
|
268 |
+
$this->wp->setMetadata(5, $meta);
|
269 |
+
$tiny_meta = new Tiny_Metadata(5, $this->json("wp_meta_default_sizes"));
|
270 |
+
$this->assertEquals(array("thumbnail"), $tiny_meta->get_in_progress_sizes());
|
271 |
+
}
|
272 |
+
|
273 |
+
public function testGetLatestErrorShouldReturnMessage() {
|
274 |
+
$processing_count = $this->subject->get_in_progress_count();
|
275 |
+
$this->subject->add_request("large");
|
276 |
+
$this->subject->add_exception(new Tiny_Exception('Could not download output', 'OutputError'), "large");
|
277 |
+
$this->assertEquals("Could not download output", $this->subject->get_latest_error());
|
278 |
+
}
|
279 |
+
}
|
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() {
|
@@ -115,14 +128,14 @@ class Tiny_Plugin_Test extends TinyTestCase {
|
|
115 |
|
116 |
$metadata = $this->wp->getMetadata(1, 'tiny_compress_images', true);
|
117 |
foreach ($metadata as $key => $values) {
|
118 |
-
$this->
|
119 |
unset($metadata[$key]['end']);
|
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() {
|
128 |
|
129 |
$metadata = $this->wp->getMetadata(1, 'tiny_compress_images', true);
|
130 |
foreach ($metadata as $key => $values) {
|
131 |
+
$this->assertBetween(-1, +1, $values['end'] - time());
|
132 |
unset($metadata[$key]['end']);
|
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,7 +14,9 @@ class Tiny_Settings_Test extends TinyTestCase {
|
|
14 |
$this->assertEquals(array(
|
15 |
array('media', 'tinypng_api_key'),
|
16 |
array('media', 'tinypng_sizes'),
|
17 |
-
array('media', '
|
|
|
|
|
18 |
), $this->wp->getCalls('register_setting'));
|
19 |
}
|
20 |
|
@@ -28,7 +30,9 @@ 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('
|
|
|
|
|
32 |
), $this->wp->getCalls('add_settings_field'));
|
33 |
}
|
34 |
|
@@ -99,4 +103,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 |
+
array('media', 'tinypng_savings')
|
20 |
), $this->wp->getCalls('register_setting'));
|
21 |
}
|
22 |
|
30 |
$this->assertEquals(array(
|
31 |
array('tinypng_api_key', 'TinyPNG API key', array($this->subject, 'render_api_key'), 'media', 'tinypng_settings', array('label_for' => 'tinypng_api_key')),
|
32 |
array('tinypng_sizes', 'File compression', array($this->subject, 'render_sizes'), 'media', 'tinypng_settings'),
|
33 |
+
array('tinypng_resize_original', 'Resize original', array($this->subject, 'render_resize'), 'media', 'tinypng_settings'),
|
34 |
+
array('tinypng_status', 'Connection status', array($this->subject, 'render_pending_status'), 'media', 'tinypng_settings'),
|
35 |
+
array('tinypng_savings', 'Savings', array($this->subject, 'render_pending_savings'), 'media', 'tinypng_settings')
|
36 |
), $this->wp->getCalls('add_settings_field'));
|
37 |
}
|
38 |
|
103 |
array('width' => 0, 'height' => 888, 'tinify' => true),
|
104 |
$sizes["additional_size_no_width"]);
|
105 |
}
|
106 |
+
|
107 |
+
public function testShouldReturnResizeEnabled() {
|
108 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on'));
|
109 |
+
$this->assertEquals(true, $this->subject->get_resize_enabled());
|
110 |
+
}
|
111 |
+
|
112 |
+
public function testShouldReturnResizeNotEnabledWithoutConfiguration() {
|
113 |
+
$this->wp->addOption("tinypng_resize_original", array());
|
114 |
+
$this->assertEquals(false, $this->subject->get_resize_enabled());
|
115 |
+
}
|
116 |
+
|
117 |
+
public function testShouldReturnResizeOptionsWithWidthAndHeight() {
|
118 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '800', 'height' => '600'));
|
119 |
+
$this->assertEquals(array('method' => 'fit', 'width' => 800, 'height' => 600), $this->subject->get_resize_options());
|
120 |
+
}
|
121 |
+
|
122 |
+
public function testShouldReturnResizeOptionsWithoutWidth() {
|
123 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '', 'height' => '600'));
|
124 |
+
$this->assertEquals(array('method' => 'scale', 'height' => 600), $this->subject->get_resize_options());
|
125 |
+
}
|
126 |
+
|
127 |
+
public function testShouldReturnResizeOptionsWithoutHeight() {
|
128 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '800', 'height' => '',));
|
129 |
+
$this->assertEquals(array('method' => 'scale', 'width' => 800), $this->subject->get_resize_options());
|
130 |
+
}
|
131 |
+
|
132 |
+
public function testShouldReturnResizeOptionsWithInvaledWidth() {
|
133 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '-1', 'height' => '600'));
|
134 |
+
$this->assertEquals(array('method' => 'scale', 'height' => 600), $this->subject->get_resize_options());
|
135 |
+
}
|
136 |
+
|
137 |
+
public function testShouldReturnResizeOptionsWithInvaledHeight() {
|
138 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '800', 'height' => '-1'));
|
139 |
+
$this->assertEquals(array('method' => 'scale', 'width' => 800), $this->subject->get_resize_options());
|
140 |
+
}
|
141 |
+
|
142 |
+
public function testShouldNotReturnResizeOptionsWithoutWithAndHeight() {
|
143 |
+
$this->wp->addOption("tinypng_resize_original", array('enabled' => 'on', 'width' => '', 'height' => ''));
|
144 |
+
$this->assertEquals(false, $this->subject->get_resize_options());
|
145 |
+
}
|
146 |
+
|
147 |
+
public function testShouldNotReturnResizeOptionsWhenNotEnabled() {
|
148 |
+
$this->wp->addOption("tinypng_resize_original", array('width' => '800', 'height' => '600'));
|
149 |
+
$this->assertEquals(false, $this->subject->get_resize_options());
|
150 |
+
}
|
151 |
}
|
test/unit/TinyTestCase.php
CHANGED
@@ -27,4 +27,13 @@ abstract class TinyTestCase extends PHPUnit_Framework_TestCase {
|
|
27 |
|
28 |
protected function tearDown() {
|
29 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
}
|
27 |
|
28 |
protected function tearDown() {
|
29 |
}
|
30 |
+
|
31 |
+
protected function assertBetween($lower_bound, $upper_bound, $actual, $message='') {
|
32 |
+
$this->assertGreaterThanOrEqual($lower_bound, $actual, $message);
|
33 |
+
$this->assertLessThanOrEqual($upper_bound, $actual, $message);
|
34 |
+
}
|
35 |
+
|
36 |
+
protected function json($file_name) {
|
37 |
+
return json_decode(file_get_contents(dirname(__FILE__) . "/../fixtures/json/" . $file_name . ".json"), true);
|
38 |
+
}
|
39 |
}
|
tiny-compress-images.php
CHANGED
@@ -2,27 +2,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.
|
6 |
* Author: TinyPNG
|
7 |
* Author URI: https://tinypng.com
|
|
|
8 |
* License: GPLv2 or later
|
9 |
*/
|
10 |
|
11 |
-
|
12 |
-
require
|
13 |
-
require
|
14 |
-
require
|
15 |
-
require
|
16 |
-
require
|
17 |
-
require
|
18 |
-
require
|
19 |
-
require
|
20 |
-
require
|
21 |
-
require
|
22 |
-
require (dirname(__FILE__) . '/src/class-tiny-notices.php');
|
23 |
|
24 |
$tiny_plugin = new Tiny_Plugin();
|
25 |
|
26 |
-
if (!defined('TINY_DEBUG')) {
|
27 |
-
define('TINY_DEBUG', null);
|
28 |
-
}
|
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.0
|
6 |
* Author: TinyPNG
|
7 |
* Author URI: https://tinypng.com
|
8 |
+
* Text Domain: tiny-compress-images
|
9 |
* License: GPLv2 or later
|
10 |
*/
|
11 |
|
12 |
+
require dirname(__FILE__) . '/src/config/tiny-config.php';
|
13 |
+
require dirname(__FILE__) . '/src/class-tiny-php.php';
|
14 |
+
require dirname(__FILE__) . '/src/class-tiny-wp-base.php';
|
15 |
+
require dirname(__FILE__) . '/src/class-tiny-exception.php';
|
16 |
+
require dirname(__FILE__) . '/src/class-tiny-compress.php';
|
17 |
+
require dirname(__FILE__) . '/src/class-tiny-compress-curl.php';
|
18 |
+
require dirname(__FILE__) . '/src/class-tiny-compress-fopen.php';
|
19 |
+
require dirname(__FILE__) . '/src/class-tiny-metadata.php';
|
20 |
+
require dirname(__FILE__) . '/src/class-tiny-settings.php';
|
21 |
+
require dirname(__FILE__) . '/src/class-tiny-plugin.php';
|
22 |
+
require dirname(__FILE__) . '/src/class-tiny-notices.php';
|
|
|
23 |
|
24 |
$tiny_plugin = new Tiny_Plugin();
|
25 |
|
26 |
+
if ( !defined( 'TINY_DEBUG' ) ) {
|
27 |
+
define( 'TINY_DEBUG', null );
|
28 |
+
}
|
trunk/tmp/.gitkeep
DELETED
File without changes
|