├── .gitignore ├── README.md ├── class-imagify.php ├── composer.json ├── composer.lock └── example ├── bear.jpg └── index.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # imagify-php 2 | > Imagify API client library for PHP 3 | 4 | ## Installation 5 | 6 | ```bash 7 | $ composer require wp-media/imagify-php 8 | ``` 9 | 10 | ## Documentation 11 | 12 | [https://imagify.io/docs/api/](https://imagify.io/docs/api/) 13 | 14 | ## Contributors 15 | - Thomas Deneulin - [GitHub](https://github.com/Gmulti) 16 | - Jérôme Tamarelle - [GitHub](https://github.com/GromNaN) 17 | - Clément JOBEILI - [GitHub](https://github.com/cjobeili) 18 | 19 | ## Copyright and license 20 | 21 | Copyright 2015-2017 WP Media. Released under [MIT](http://opensource.org/licenses/MIT). 22 | 23 | **The MIT License (MIT)** 24 | 25 | Copyright (c) 2017 26 | 27 | Permission is hereby granted, free of charge, to any person obtaining a copy 28 | of this software and associated documentation files (the "Software"), to deal 29 | in the Software without restriction, including without limitation the rights 30 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 31 | copies of the Software, and to permit persons to whom the Software is 32 | furnished to do so, subject to the following conditions: 33 | 34 | The above copyright notice and this permission notice shall be included in all 35 | copies or substantial portions of the Software. 36 | 37 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 40 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 41 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 42 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 43 | SOFTWARE. -------------------------------------------------------------------------------- /class-imagify.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in all 16 | * copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | * SOFTWARE. 25 | */ 26 | 27 | namespace Imagify; 28 | 29 | class Optimizer { 30 | /** 31 | * The Imagify API endpoint 32 | */ 33 | const API_ENDPOINT = 'https://app.imagify.io/api'; 34 | 35 | /** 36 | * The Imagify API key 37 | */ 38 | private $api_key = ''; 39 | 40 | /** 41 | * HTTP headers 42 | */ 43 | private $headers = array(); 44 | 45 | /** 46 | * The constructor 47 | * 48 | * @return void 49 | */ 50 | public function __construct( $api_key = '' ) { 51 | if ( ! empty( $api_key ) ) { 52 | $this->api_key = $api_key; 53 | } 54 | 55 | // Check if php-curl is enabled 56 | if ( ! function_exists( 'curl_init' ) || ! function_exists( 'curl_exec' ) ) { 57 | die('cURL isn\'t installed on the server.'); 58 | } 59 | 60 | $this->headers['Authorization'] = 'Authorization: token ' . $this->api_key; 61 | } 62 | 63 | /** 64 | * Optimize an image from its binary content. 65 | * 66 | * @param string $image Image path 67 | * @param array $options (optional) Optimization options 68 | * array( 69 | * 'level' => string ('normal' | 'aggressive' (default) | 'ultra'), 70 | * 'resize' => array( 71 | * 'width' => int, 72 | * 'height' => int, 73 | * 'percent' => int 74 | * ), 75 | * 'keep_exif' => bool (default: false) 76 | * ) 77 | * @return array 78 | */ 79 | public function optimize( $image, $options = array() ) { 80 | if ( !is_string($image) || !is_file($image) ) { 81 | return (object) array('success' => false, 'message' => 'Image incorrect!'); 82 | } else if ( !is_readable($image) ) { 83 | return (object) array('success' => false, 'message' => 'Image not readable!'); 84 | } 85 | 86 | $default = array( 87 | 'level' => 'aggressive', 88 | 'resize' => array(), 89 | 'keep_exif' => false, 90 | 'timeout' => 45 91 | ); 92 | 93 | $options = array_merge( $default, $options ); 94 | 95 | $data = array( 96 | 'image' => curl_file_create( $image ), 97 | 'data' => json_encode( 98 | array( 99 | 'aggressive' => ( 'aggressive' === $options['level'] ) ? true : false, 100 | 'ultra' => ( 'ultra' === $options['level'] ) ? true : false, 101 | 'resize' => $options['resize'], 102 | 'keep_exif' => $options['keep_exif'], 103 | ) 104 | ) 105 | ); 106 | 107 | return $this->request( '/upload/', array( 108 | 'post_data' => $data, 109 | 'timeout' => $options["timeout"] 110 | ) 111 | ); 112 | } 113 | 114 | /** 115 | * Make an HTTP call using curl. 116 | * 117 | * @param string $url The URL to call 118 | * @param array $options Optional request options 119 | * @return object 120 | */ 121 | private function request( $url, $options = array() ) { 122 | $default = array( 123 | 'method' => 'POST', 124 | 'post_data' => null 125 | ); 126 | $options = array_merge( $default, $options ); 127 | 128 | try { 129 | $ch = curl_init(); 130 | $is_ssl = ( isset( $_SERVER['HTTPS'] ) && ( 'on' == strtolower( $_SERVER['HTTPS'] ) || '1' == $_SERVER['HTTPS'] ) ) || ( isset( $_SERVER['SERVER_PORT'] ) && ( '443' == $_SERVER['SERVER_PORT'] ) ); 131 | 132 | if ( 'POST' === $options['method'] ) { 133 | curl_setopt( $ch, CURLOPT_POST, true ); 134 | curl_setopt( $ch, CURLOPT_POSTFIELDS, $options['post_data'] ); 135 | } 136 | 137 | curl_setopt( $ch, CURLOPT_URL, self::API_ENDPOINT . $url ); 138 | curl_setopt( $ch, CURLOPT_USERAGENT, 'Imagify PHP Class'); 139 | curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); 140 | curl_setopt( $ch, CURLOPT_HTTPHEADER, $this->headers ); 141 | curl_setopt( $ch, CURLOPT_TIMEOUT, $options['timeout'] ); 142 | @curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); 143 | curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $is_ssl ); 144 | 145 | $response = json_decode( curl_exec( $ch ) ); 146 | $error = curl_error( $ch ); 147 | $http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); 148 | 149 | curl_close( $ch ); 150 | 151 | } catch( \Exception $e ) { 152 | return (object) array('success' => false, 'message' => 'Unknown error occurred'); 153 | } 154 | 155 | if ( 200 !== $http_code && isset( $response->code, $response->detail ) ) { 156 | return $response; 157 | } elseif ( 200 !== $http_code ) { 158 | return (object) array('success' => false, 'message' => 'Unknown error occurred'); 159 | } 160 | 161 | return $response; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wp-media/imagify-php", 3 | "description": "Imagify API client library for PHP", 4 | "version": "1.1.0", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "WP Media", 9 | "email": "contact@wp-media.me", 10 | "role": "Developer" 11 | }, 12 | { 13 | "name": "Clément JOBEILI", 14 | "email": "contact@yurplan.com", 15 | "role": "Contributor" 16 | } 17 | ], 18 | "config": { 19 | "platform": { 20 | "php": "5.5" 21 | } 22 | }, 23 | "require": { 24 | "php": ">=5.5", 25 | "ext-curl": "*" 26 | }, 27 | "autoload": { 28 | "classmap": ["class-imagify.php"] 29 | } 30 | } -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "82c1bca580cb317d6a97fb321f614d13", 8 | "content-hash": "34082195b3be8669c3a7a5ecf6d30134", 9 | "packages": [], 10 | "packages-dev": [], 11 | "aliases": [], 12 | "minimum-stability": "stable", 13 | "stability-flags": [], 14 | "prefer-stable": false, 15 | "prefer-lowest": false, 16 | "platform": { 17 | "php": ">=5.5", 18 | "ext-curl": "*" 19 | }, 20 | "platform-dev": [], 21 | "platform-overrides": { 22 | "php": "5.5" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example/bear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-media/imagify-php/b0c8f3ffe33e12931bad3ec9332693d563b6f0ab/example/bear.jpg -------------------------------------------------------------------------------- /example/index.php: -------------------------------------------------------------------------------- 1 | optimize( 'bear.jpg', array('keep_exif' => true) ); 8 | 9 | if ( true === $handle->success ) { 10 | 11 | $image_data = file_get_contents( $handle->image ); 12 | 13 | file_put_contents( 'bear_optimized.jpg', $image_data ); 14 | 15 | echo '