diff --git a/lib/Tinify.php b/lib/Tinify.php index 80f533f..fe1ceef 100644 --- a/lib/Tinify.php +++ b/lib/Tinify.php @@ -5,36 +5,89 @@ const VERSION = "1.6.4"; class Tinify { + /** + * @var string|null API key. + */ private static $key = NULL; + + /** + * @var string|null Identifier used for requests. + */ private static $appIdentifier = NULL; + + /** + * @var string|null URL to the compression API. + */ private static $proxy = NULL; + /** + * @var int|null The number of compressions. + */ private static $compressionCount = NULL; + + /** + * @var Client|null Tinify client. + */ private static $client = NULL; + /** + * Sets the key and resets the client. + * + * @param string $key The API key. + * @return void + */ public static function setKey($key) { self::$key = $key; self::$client = NULL; } + /** + * Sets the app identifier and resets the client. + * + * @param string $appIdentifier The app identifier. + * @return void + */ public static function setAppIdentifier($appIdentifier) { self::$appIdentifier = $appIdentifier; self::$client = NULL; } + /** + * Sets the proxy and resets the client. + * + * @param string $proxy URL to the proxy server. + * @return void + */ public static function setProxy($proxy) { self::$proxy = $proxy; self::$client = NULL; } + /** + * Retrieves the compression count. + * + * @return int|null + */ public static function getCompressionCount() { return self::$compressionCount; } + /** + * Sets the compression count + * + * @param int $compressionCount + * @return void + */ public static function setCompressionCount($compressionCount) { self::$compressionCount = $compressionCount; } + /** + * Retrieves the tinify client. + * Will initiate a new client with the current key, identifier and proxy. + * + * @return Client + */ public static function getClient() { if (!self::$key) { throw new AccountException("Provide an API key with Tinify\setKey(...)"); @@ -47,6 +100,12 @@ public static function getClient() { return self::$client; } + /** + * Sets a new client + * + * @param Client $client + * @return void + */ public static function setClient($client) { self::$client = $client; } diff --git a/lib/Tinify/Client.php b/lib/Tinify/Client.php index 0d8ed0c..e0afd49 100644 --- a/lib/Tinify/Client.php +++ b/lib/Tinify/Client.php @@ -3,22 +3,54 @@ namespace Tinify; class Client { + /** + * The default endpoint + */ const API_ENDPOINT = "https://api.tinify.com"; + /** + * Number of retries on failure + */ const RETRY_COUNT = 1; + + /** + * The time between retrieves + */ const RETRY_DELAY = 500; private $options; + /** + * Retrieves the user agent identifier + * contains client version, php version and curl version + * + * @return string + */ public static function userAgent() { $curl = curl_version(); return "Tinify/" . VERSION . " PHP/" . PHP_VERSION . " curl/" . $curl["version"]; } + /** + * Path the the certificates + * + * @return string + */ private static function caBundle() { return __DIR__ . "/../data/cacert.pem"; } + /** + * Constructor for client + * validates if curl meets requirements, + * + * @param string $key api key + * @param string|null $app_identifier identifier for the client + * @param string|null $proxy an optional proxy url to go to first + * @return void + * + * @throws ClientException when curl version is not supported + */ function __construct($key, $app_identifier = NULL, $proxy = NULL) { $curl = curl_version(); @@ -70,6 +102,17 @@ function __construct($key, $app_identifier = NULL, $proxy = NULL) { } } + /** + * Makes an HTTP request to the API. + * + * @param string $method The HTTP method (GET, POST, etc.). + * @param string $url The endpoint path. + * @param array|string|null $body Optional. The request body. Default null. + * @return object An object with 'body' and 'headers' properties. + * + * @throws ConnectionException If the connection fails. + * @throws Exception If the API returns an error response. + */ function request($method, $url, $body = NULL) { $header = array(); if (is_array($body)) { @@ -155,6 +198,12 @@ function request($method, $url, $body = NULL) { } } + /** + * Parses HTTP headers + * + * @param array|string $headers The request headers + * @return array lowercased headers + */ protected static function parseHeaders($headers) { if (!is_array($headers)) { $headers = explode("\r\n", $headers); diff --git a/lib/Tinify/Result.php b/lib/Tinify/Result.php index 86ce892..1088d93 100644 --- a/lib/Tinify/Result.php +++ b/lib/Tinify/Result.php @@ -2,34 +2,88 @@ namespace Tinify; +/** + * Represents a compressed image result from the Tinify API. + * Contains the compressed image data and metadata such as content type and size. + * + * @see ResultMeta + */ class Result extends ResultMeta { + /** + * The compressed image data. + * + * @var string $data + */ protected $data; + /** + * Constructs a Result with metadata and image data. + * + * @param array $meta The response headers containing metadata. + * @param string $data The compressed image data. + * @return void + */ public function __construct($meta, $data) { $this->meta = $meta; $this->data = $data; } + /** + * Retrieves the compressed image data. + * + * @return string The compressed image data. + */ public function data() { return $this->data; } + /** + * Retrieves the compressed image as a buffer. + * + * Alias for data() + * @see data() + * + * @return string The compressed image data. + */ public function toBuffer() { return $this->data; } + /** + * Writes the compressed image to a file. + * + * @param string $path The file path where the image should be written. + * @return int|false The bytes written, or false on failure. + */ public function toFile($path) { return file_put_contents($path, $this->toBuffer()); } + /** + * Retrieves the size of the compressed image in bytes. + * @return int The size of the compressed image. + */ public function size() { return intval($this->meta["content-length"]); } + /** + * Retrieves the media type of the compressed image. + * + * @return string The media type eg 'image/png' or 'image/jpeg'. + */ public function mediaType() { return $this->meta["content-type"]; } + /** + * Retrieves the content type of the compressed image. + * + * Alias for mediaType() + * @see mediaType() + * + * @return string The content type e.g. 'image/png' or 'image/jpeg'. + */ public function contentType() { return $this->mediaType(); } diff --git a/lib/Tinify/ResultMeta.php b/lib/Tinify/ResultMeta.php index 27aba0e..988c7dc 100644 --- a/lib/Tinify/ResultMeta.php +++ b/lib/Tinify/ResultMeta.php @@ -2,25 +2,55 @@ namespace Tinify; +/** + * Class containing compressed image meta data + */ class ResultMeta { + /** + * The response headers containing image metadata. + * + * @var array $meta + */ protected $meta; + /** + * Constructs a ResultMeta with response metadata. + * + * @param array $meta The response headers containing image metadata. + */ public function __construct($meta) { $this->meta = $meta; } + /** + * Width of the image in pixels. + * @return int The image width. + */ public function width() { return intval($this->meta["image-width"]); } + /** + * Height of the image in pixels. + * @return int The image height. + */ public function height() { return intval($this->meta["image-height"]); } + /** + * Location of the compressed image. + * @return string|null The URL to the compressed image, or null if not available. + */ public function location() { return isset($this->meta["location"]) ? $this->meta["location"] : null; } + /** + * Retrieves the file extension of the image. + * Extracts the extension from the content-type header. + * @return string|null The file extension or null if not available. + */ public function extension() { if (isset($this->meta["content-type"])) { $parts = explode("/", $this->meta["content-type"]); diff --git a/lib/Tinify/Source.php b/lib/Tinify/Source.php index ef7c6a1..96fde9a 100644 --- a/lib/Tinify/Source.php +++ b/lib/Tinify/Source.php @@ -2,56 +2,132 @@ namespace Tinify; +/** + * Represents a compressed image source. + */ class Source { private $url, $commands; + /** + * Shrinks the file at the given path + * - reads the file from disk + * - uses fromBuffer to make the API request + * + * @param string $path The path to the file + * @return Source + */ public static function fromFile($path) { return self::fromBuffer(file_get_contents($path)); } + /** + * Shrinks the given string. + * Will upload and compress the image to Tinify + * + * + * @param string $string the raw body + * @return Source + */ public static function fromBuffer($string) { $response = Tinify::getClient()->request("post", "/shrink", $string); return new self($response->headers["location"]); } + /** + * Shrinks the image on the given url + * + * @param string $url url to the subject to shrink + * @return Source + */ public static function fromUrl($url) { $body = array("source" => array("url" => $url)); $response = Tinify::getClient()->request("post", "/shrink", $body); return new self($response->headers["location"]); } + /** + * Constructor for the image source that has been compressed. + * + * @param string $url url to the compressed image + * @param array $commands Array of actions to apply on the compressed image. + * @return void + */ public function __construct($url, $commands = array()) { $this->url = $url; $this->commands = $commands; } + /** + * Will add preserve command. This will keep meta data on the compressed image. + * https://tinypng.com/developers/reference#preserving-metadata + * + * @return Source + */ public function preserve() { $options = $this->flatten(func_get_args()); $commands = array_merge($this->commands, array("preserve" => $options)); return new self($this->url, $commands); } + /** + * Will add resize command to the compressed image. + * https://tinypng.com/developers/reference#resizing-images + * + * @param array $options resize options + * @return Source + */ public function resize($options) { $commands = array_merge($this->commands, array("resize" => $options)); return new self($this->url, $commands); } + /** + * Will save the image to cloud storage + * https://tinypng.com/developers/reference#saving-to-amazon-s3 + * Supports GCP, S3 and any other S3 API compatible storage. + * + * @param array $options store options + * @return Result The stored image + */ public function store($options) { $response = Tinify::getClient()->request("post", $this->url, array_merge($this->commands, array("store" => $options))); return new Result($response->headers, $response->body); } + /** + * Will add convert command to the image + * https://tinypng.com/developers/reference#converting-images + * + * @param array $options conversion options + * @return Source + */ public function convert($options) { $commands = array_merge($this->commands, array("convert" => $options)); return new self($this->url, $commands); } + /** + * Will add transform commands to the image + * https://tinypng.com/developers/reference#converting-images + * The transform object specifies the stylistic transformations that will be applied to your image. + * + * @param array $options + * @return Source + */ public function transform($options) { $commands = array_merge($this->commands, array("transform" => $options)); return new self($this->url, $commands); } + /** + * Retrieves the compressed image as a Result object. + * + * Sends a GET request if no commands have been applied, + * or a POST request if commands are present. + * + * @return Result The compressed image with metadata. + */ public function result() { $has_commands = !empty($this->commands); $method = $has_commands ? "post" : "get"; @@ -60,14 +136,32 @@ public function result() { return new Result($response->headers, $response->body); } + /** + * Retrieves the compressed image and stores it on the given path + * + * + * @param string $path Local file path + * @return int|false Returns positive int if successful + */ public function toFile($path) { return $this->result()->toFile($path); } + /** + * Retrieves the raw image data + * + * @return string Raw result body + */ public function toBuffer() { return $this->result()->toBuffer(); } + /** + * Flattens an array of options. + * + * @param array $options An array that may contain mixed values and nested arrays. + * @return array A flattened array with all nested arrays merged. + */ private static function flatten($options) { $flattened = array(); foreach ($options as $option) {