Merge branch '0.7.x' of github.com:appwrite/appwrite into dev
|
@ -162,8 +162,6 @@ Appwrite's current structure is a combination of both [Monolithic](https://en.wi
|
|||
│ ├── Extend
|
||||
│ ├── Network
|
||||
│ ├── OpenSSL
|
||||
│ ├── Resize
|
||||
│ ├── Storage
|
||||
│ ├── Task
|
||||
│ ├── Template
|
||||
│ ├── URL
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
<?php
|
||||
|
||||
use Utopia\App;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\Cache\Adapter\Filesystem;
|
||||
use Appwrite\Resize\Resize;
|
||||
use Appwrite\URL\URL as URLParse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Validator\HexColor;
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use chillerlan\QRCode\QROptions;
|
||||
use Utopia\App;
|
||||
use Utopia\Cache\Adapter\Filesystem;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Image\Image;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\HexColor;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
$avatarCallback = function ($type, $code, $width, $height, $quality, $response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$code = \strtolower($code);
|
||||
$type = \strtolower($type);
|
||||
$set = Config::getParam('avatar-'.$type, []);
|
||||
$set = Config::getParam('avatar-' . $type, []);
|
||||
|
||||
if (empty($set)) {
|
||||
throw new Exception('Avatar set not found', 404);
|
||||
|
@ -37,17 +37,17 @@ $avatarCallback = function ($type, $code, $width, $height, $quality, $response)
|
|||
}
|
||||
|
||||
$output = 'png';
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
|
||||
$key = \md5('/v1/avatars/:type/:code-'.$code.$width.$height.$quality.$output);
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT'; // 45 days cache
|
||||
$key = \md5('/v1/avatars/:type/:code-' . $code . $width . $height . $quality . $output);
|
||||
$path = $set[$code];
|
||||
$type = 'png';
|
||||
|
||||
if (!\is_readable($path)) {
|
||||
throw new Exception('File not readable in '.$path, 500);
|
||||
throw new Exception('File not readable in ' . $path, 500);
|
||||
}
|
||||
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3/* 3 months */);
|
||||
|
||||
if ($data) {
|
||||
//$output = (empty($output)) ? $type : $output;
|
||||
|
@ -60,24 +60,23 @@ $avatarCallback = function ($type, $code, $width, $height, $quality, $response)
|
|||
;
|
||||
}
|
||||
|
||||
$resize = new Resize(\file_get_contents($path));
|
||||
$image = new Image(\file_get_contents($path));
|
||||
|
||||
$resize->crop((int) $width, (int) $height);
|
||||
$image->crop((int) $width, (int) $height);
|
||||
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$data = $resize->output($output, $quality);
|
||||
|
||||
$data = $image->output($output, $quality);
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
|
||||
$response
|
||||
->setContentType('image/png')
|
||||
->addHeader('Expires', $date)
|
||||
->addHeader('X-Appwrite-Cache', 'miss')
|
||||
->send($data, null);
|
||||
;
|
||||
|
||||
unset($resize);
|
||||
unset($image);
|
||||
};
|
||||
|
||||
App::get('/v1/avatars/credit-cards/:code')
|
||||
|
@ -91,7 +90,7 @@ App::get('/v1/avatars/credit-cards/:code')
|
|||
->label('sdk.description', '/docs/references/avatars/get-credit-card.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_IMAGE_PNG)
|
||||
->param('code', '', new WhiteList(\array_keys(Config::getParam('avatar-credit-cards'))), 'Credit Card Code. Possible values: '.\implode(', ', \array_keys(Config::getParam('avatar-credit-cards'))).'.')
|
||||
->param('code', '', new WhiteList(\array_keys(Config::getParam('avatar-credit-cards'))), 'Credit Card Code. Possible values: ' . \implode(', ', \array_keys(Config::getParam('avatar-credit-cards'))) . '.')
|
||||
->param('width', 100, new Range(0, 2000), 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
|
||||
->param('height', 100, new Range(0, 2000), 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
|
||||
->param('quality', 100, new Range(0, 100), 'Image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
|
||||
|
@ -160,11 +159,11 @@ App::get('/v1/avatars/image')
|
|||
|
||||
$quality = 80;
|
||||
$output = 'png';
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
|
||||
$key = \md5('/v2/avatars/images-'.$url.'-'.$width.'/'.$height.'/'.$quality);
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT'; // 45 days cache
|
||||
$key = \md5('/v2/avatars/images-' . $url . '-' . $width . '/' . $height . '/' . $quality);
|
||||
$type = 'png';
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 7 /* 1 week */);
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 7/* 1 week */);
|
||||
|
||||
if ($data) {
|
||||
return $response
|
||||
|
@ -186,17 +185,17 @@ App::get('/v1/avatars/image')
|
|||
}
|
||||
|
||||
try {
|
||||
$resize = new Resize($fetch);
|
||||
} catch (\Exception $exception) {
|
||||
$image = new Image($fetch);
|
||||
} catch (\Exception$exception) {
|
||||
throw new Exception('Unable to parse image', 500);
|
||||
}
|
||||
|
||||
$resize->crop((int) $width, (int) $height);
|
||||
$image->crop((int) $width, (int) $height);
|
||||
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$data = $resize->output($output, $quality);
|
||||
|
||||
|
||||
$data = $image->output($output, $quality);
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
$response
|
||||
|
@ -206,7 +205,7 @@ App::get('/v1/avatars/image')
|
|||
->send($data);
|
||||
;
|
||||
|
||||
unset($resize);
|
||||
unset($image);
|
||||
});
|
||||
|
||||
App::get('/v1/avatars/favicon')
|
||||
|
@ -229,11 +228,11 @@ App::get('/v1/avatars/favicon')
|
|||
$height = 56;
|
||||
$quality = 80;
|
||||
$output = 'png';
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
|
||||
$key = \md5('/v2/avatars/favicon-'.$url);
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT'; // 45 days cache
|
||||
$key = \md5('/v2/avatars/favicon-' . $url);
|
||||
$type = 'png';
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3/* 3 months */);
|
||||
|
||||
if ($data) {
|
||||
return $response
|
||||
|
@ -316,7 +315,7 @@ App::get('/v1/avatars/favicon')
|
|||
if (empty($outputHref) || empty($outputExt)) {
|
||||
$default = \parse_url($url);
|
||||
|
||||
$outputHref = $default['scheme'].'://'.$default['host'].'/favicon.ico';
|
||||
$outputHref = $default['scheme'] . '://' . $default['host'] . '/favicon.ico';
|
||||
$outputExt = 'ico';
|
||||
}
|
||||
|
||||
|
@ -343,13 +342,13 @@ App::get('/v1/avatars/favicon')
|
|||
throw new Exception('Icon not found', 404);
|
||||
}
|
||||
|
||||
$resize = new Resize($fetch);
|
||||
$image = new Image($fetch);
|
||||
|
||||
$resize->crop((int) $width, (int) $height);
|
||||
$image->crop((int) $width, (int) $height);
|
||||
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$data = $resize->output($output, $quality);
|
||||
$data = $image->output($output, $quality);
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
|
@ -359,7 +358,7 @@ App::get('/v1/avatars/favicon')
|
|||
->addHeader('X-Appwrite-Cache', 'miss')
|
||||
->send($data);
|
||||
|
||||
unset($resize);
|
||||
unset($image);
|
||||
});
|
||||
|
||||
App::get('/v1/avatars/qr')
|
||||
|
@ -394,14 +393,14 @@ App::get('/v1/avatars/qr')
|
|||
$response->addHeader('Content-Disposition', 'attachment; filename="qr.png"');
|
||||
}
|
||||
|
||||
$resize = new Resize($qrcode->render($text));
|
||||
$image = new Image($qrcode->render($text));
|
||||
|
||||
$resize->crop((int) $size, (int) $size);
|
||||
$image->crop((int) $size, (int) $size);
|
||||
|
||||
$response
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache
|
||||
->setContentType('image/png')
|
||||
->send($resize->output('png', 9))
|
||||
->send($image->output('png', 9))
|
||||
;
|
||||
});
|
||||
|
||||
|
@ -437,10 +436,10 @@ App::get('/v1/avatars/initials')
|
|||
['color' => '#610038', 'background' => '#f5d1e6'], // PINK
|
||||
['color' => '#386100', 'background' => '#dcf1bd'], // LIME
|
||||
['color' => '#615800', 'background' => '#f1ecba'], // YELLOW
|
||||
['color' => '#610008', 'background' => '#f6d2d5'] // RED
|
||||
['color' => '#610008', 'background' => '#f6d2d5'], // RED
|
||||
];
|
||||
|
||||
$rand = \rand(0, \count($themes)-1);
|
||||
$rand = \rand(0, \count($themes) - 1);
|
||||
|
||||
$name = (!empty($name)) ? $name : $user->getAttribute('name', $user->getAttribute('email', ''));
|
||||
$words = \explode(' ', \strtoupper($name));
|
||||
|
@ -457,23 +456,23 @@ App::get('/v1/avatars/initials')
|
|||
}
|
||||
|
||||
$length = \count($words);
|
||||
$rand = \substr($code,-1);
|
||||
$background = (!empty($background)) ? '#'.$background : $themes[$rand]['background'];
|
||||
$color = (!empty($color)) ? '#'.$color : $themes[$rand]['color'];
|
||||
$rand = \substr($code, -1);
|
||||
$background = (!empty($background)) ? '#' . $background : $themes[$rand]['background'];
|
||||
$color = (!empty($color)) ? '#' . $color : $themes[$rand]['color'];
|
||||
|
||||
$image = new \Imagick();
|
||||
$draw = new \ImagickDraw();
|
||||
$fontSize = \min($width, $height) / 2;
|
||||
|
||||
$draw->setFont(__DIR__."/../../../public/fonts/poppins-v9-latin-500.ttf");
|
||||
$image->setFont(__DIR__."/../../../public/fonts/poppins-v9-latin-500.ttf");
|
||||
|
||||
$draw->setFont(__DIR__ . "/../../../public/fonts/poppins-v9-latin-500.ttf");
|
||||
$image->setFont(__DIR__ . "/../../../public/fonts/poppins-v9-latin-500.ttf");
|
||||
|
||||
$draw->setFillColor(new \ImagickPixel($color));
|
||||
$draw->setFontSize($fontSize);
|
||||
|
||||
|
||||
$draw->setTextAlignment(\Imagick::ALIGN_CENTER);
|
||||
$draw->annotation($width / 1.97, ($height / 2) + ($fontSize / 3), $initials);
|
||||
|
||||
|
||||
$image->newImage($width, $height, $background);
|
||||
$image->setImageFormat("png");
|
||||
$image->drawImage($draw);
|
||||
|
@ -481,7 +480,7 @@ App::get('/v1/avatars/initials')
|
|||
//$image->setImageCompressionQuality(9 - round(($quality / 100) * 9));
|
||||
|
||||
$response
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache
|
||||
->setContentType('image/png')
|
||||
->send($image->getImageBlob())
|
||||
;
|
||||
|
|
|
@ -18,7 +18,7 @@ use Utopia\Storage\Validator\File;
|
|||
use Utopia\Storage\Validator\FileSize;
|
||||
use Utopia\Storage\Validator\Upload;
|
||||
use Utopia\Storage\Compression\Algorithms\GZIP;
|
||||
use Appwrite\Resize\Resize;
|
||||
use Utopia\Image\Image;
|
||||
use Appwrite\OpenSSL\OpenSSL;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
|
@ -332,17 +332,17 @@ App::get('/v1/storage/files/:fileId/preview')
|
|||
$source = $compressor->decompress($source);
|
||||
}
|
||||
|
||||
$resize = new Resize($source);
|
||||
$image = new Image($source);
|
||||
|
||||
$resize->crop((int) $width, (int) $height);
|
||||
$image->crop((int) $width, (int) $height);
|
||||
|
||||
if (!empty($background)) {
|
||||
$resize->setBackground('#'.$background);
|
||||
$image->setBackground('#'.$background);
|
||||
}
|
||||
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$data = $resize->output($output, $quality);
|
||||
$data = $image->output($output, $quality);
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
|
@ -353,7 +353,7 @@ App::get('/v1/storage/files/:fileId/preview')
|
|||
->send($data)
|
||||
;
|
||||
|
||||
unset($resize);
|
||||
unset($image);
|
||||
});
|
||||
|
||||
App::get('/v1/storage/files/:fileId/download')
|
||||
|
|
|
@ -47,7 +47,8 @@
|
|||
"utopia-php/domains": "0.2.*",
|
||||
"utopia-php/swoole": "0.2.*",
|
||||
"utopia-php/system": "0.4.*",
|
||||
"utopia-php/storage": "0.2.*",
|
||||
"utopia-php/storage": "0.4.*",
|
||||
"utopia-php/image": "0.1.*",
|
||||
|
||||
"resque/php-resque": "1.3.6",
|
||||
"matomo/device-detector": "4.1.0",
|
||||
|
|
235
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "01173c3bd9d5d01922432165ebcf1ce2",
|
||||
"content-hash": "4f58de92fb64af44d915387895472881",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
@ -1691,6 +1691,59 @@
|
|||
},
|
||||
"time": "2020-12-26T12:02:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
"version": "0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/image.git",
|
||||
"reference": "66e38db211b1d6fe93de09d82606641e0f996e42"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/66e38db211b1d6fe93de09d82606641e0f996e42",
|
||||
"reference": "66e38db211b1d6fe93de09d82606641e0f996e42",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"chillerlan/php-qrcode": "4.3.0",
|
||||
"ext-imagick": "*",
|
||||
"php": ">=7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"vimeo/psalm": "4.0.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Utopia\\Image\\": "src/Image"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Eldad Fux",
|
||||
"email": "eldad@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "A simple Image manipulation library",
|
||||
"keywords": [
|
||||
"framework",
|
||||
"image",
|
||||
"php",
|
||||
"upf",
|
||||
"utopia"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/image/issues",
|
||||
"source": "https://github.com/utopia-php/image/tree/0.1.0"
|
||||
},
|
||||
"time": "2021-02-19T05:09:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/locale",
|
||||
"version": "0.3.3",
|
||||
|
@ -1849,16 +1902,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/storage",
|
||||
"version": "0.2.0",
|
||||
"version": "0.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/storage.git",
|
||||
"reference": "27bfd663c9b2a17ac0911522a87f42bee834df95"
|
||||
"reference": "86f749f2d79268528732e560f77dde0155e162ca"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/27bfd663c9b2a17ac0911522a87f42bee834df95",
|
||||
"reference": "27bfd663c9b2a17ac0911522a87f42bee834df95",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/86f749f2d79268528732e560f77dde0155e162ca",
|
||||
"reference": "86f749f2d79268528732e560f77dde0155e162ca",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1895,9 +1948,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/storage/issues",
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.2.0"
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.4.1"
|
||||
},
|
||||
"time": "2021-01-27T12:21:27+00:00"
|
||||
"time": "2021-02-19T05:04:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/swoole",
|
||||
|
@ -2653,12 +2706,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/felixfbecker/php-language-server-protocol.git",
|
||||
"reference": "85e83cacd2ed573238678c6875f8f0d7ec699541"
|
||||
"reference": "9d846d1f5cf101deee7a61c8ba7caa0a975cd730"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/85e83cacd2ed573238678c6875f8f0d7ec699541",
|
||||
"reference": "85e83cacd2ed573238678c6875f8f0d7ec699541",
|
||||
"url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/9d846d1f5cf101deee7a61c8ba7caa0a975cd730",
|
||||
"reference": "9d846d1f5cf101deee7a61c8ba7caa0a975cd730",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2700,9 +2753,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/felixfbecker/php-language-server-protocol/issues",
|
||||
"source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.0"
|
||||
"source": "https://github.com/felixfbecker/php-language-server-protocol/tree/1.5.1"
|
||||
},
|
||||
"time": "2020-10-23T13:55:30+00:00"
|
||||
"time": "2021-02-22T14:02:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
|
@ -3117,16 +3170,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phar-io/version",
|
||||
"version": "3.0.4",
|
||||
"version": "3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phar-io/version.git",
|
||||
"reference": "e4782611070e50613683d2b9a57730e9a3ba5451"
|
||||
"reference": "bae7c545bef187884426f042434e561ab1ddb182"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phar-io/version/zipball/e4782611070e50613683d2b9a57730e9a3ba5451",
|
||||
"reference": "e4782611070e50613683d2b9a57730e9a3ba5451",
|
||||
"url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182",
|
||||
"reference": "bae7c545bef187884426f042434e561ab1ddb182",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3162,9 +3215,9 @@
|
|||
"description": "Library for handling version information and constraints",
|
||||
"support": {
|
||||
"issues": "https://github.com/phar-io/version/issues",
|
||||
"source": "https://github.com/phar-io/version/tree/3.0.4"
|
||||
"source": "https://github.com/phar-io/version/tree/3.1.0"
|
||||
},
|
||||
"time": "2020-12-13T23:18:30+00:00"
|
||||
"time": "2021-02-23T14:00:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-common",
|
||||
|
@ -3477,12 +3530,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
||||
"reference": "499be26d3f45b1d12b4903a772ea22f858a48eb3"
|
||||
"reference": "dae425925709122f7584cadeeb838edcaa491bb1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/499be26d3f45b1d12b4903a772ea22f858a48eb3",
|
||||
"reference": "499be26d3f45b1d12b4903a772ea22f858a48eb3",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/dae425925709122f7584cadeeb838edcaa491bb1",
|
||||
"reference": "dae425925709122f7584cadeeb838edcaa491bb1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3530,7 +3583,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:39:05+00:00"
|
||||
"time": "2021-02-23T15:48:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-invoker",
|
||||
|
@ -3538,12 +3591,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-invoker.git",
|
||||
"reference": "e17a1cc6f8ab1ba4f4ff654019b9d7d9f017267c"
|
||||
"reference": "5ad9e5f5d6ee1a837e1d50bab1017e0daf423b40"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/e17a1cc6f8ab1ba4f4ff654019b9d7d9f017267c",
|
||||
"reference": "e17a1cc6f8ab1ba4f4ff654019b9d7d9f017267c",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5ad9e5f5d6ee1a837e1d50bab1017e0daf423b40",
|
||||
"reference": "5ad9e5f5d6ee1a837e1d50bab1017e0daf423b40",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3594,7 +3647,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:39:14+00:00"
|
||||
"time": "2021-02-23T15:48:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-text-template",
|
||||
|
@ -3602,12 +3655,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-text-template.git",
|
||||
"reference": "8de0286bd8c4988bc20fbd7c246d1662e5c2efe2"
|
||||
"reference": "4ec5a2ac79a19b35d0cf83cce30604f77743067a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/8de0286bd8c4988bc20fbd7c246d1662e5c2efe2",
|
||||
"reference": "8de0286bd8c4988bc20fbd7c246d1662e5c2efe2",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/4ec5a2ac79a19b35d0cf83cce30604f77743067a",
|
||||
"reference": "4ec5a2ac79a19b35d0cf83cce30604f77743067a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3654,7 +3707,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:39:47+00:00"
|
||||
"time": "2021-02-23T15:49:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-timer",
|
||||
|
@ -3662,12 +3715,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
||||
"reference": "bb859edc295be92317a9161ddb0d5cae03c4e164"
|
||||
"reference": "705821b0927b5e69e9e016c84de68dc6195c71b9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/bb859edc295be92317a9161ddb0d5cae03c4e164",
|
||||
"reference": "bb859edc295be92317a9161ddb0d5cae03c4e164",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/705821b0927b5e69e9e016c84de68dc6195c71b9",
|
||||
"reference": "705821b0927b5e69e9e016c84de68dc6195c71b9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3714,7 +3767,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:39:22+00:00"
|
||||
"time": "2021-02-23T15:48:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
|
@ -3879,12 +3932,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/cli-parser.git",
|
||||
"reference": "83a4f03a3fce4f613fa2662aa7357246c7bb6860"
|
||||
"reference": "3a42d843af4d27ca1155e1d926881af162733655"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/83a4f03a3fce4f613fa2662aa7357246c7bb6860",
|
||||
"reference": "83a4f03a3fce4f613fa2662aa7357246c7bb6860",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/3a42d843af4d27ca1155e1d926881af162733655",
|
||||
"reference": "3a42d843af4d27ca1155e1d926881af162733655",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3928,7 +3981,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:40:12+00:00"
|
||||
"time": "2021-02-23T15:49:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit",
|
||||
|
@ -3992,12 +4045,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
|
||||
"reference": "b0e1cc9a057295d75ec7c03e6e89094fa0787ca4"
|
||||
"reference": "5f5db0b35f586eb5bca0581a10bb42dd56575986"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/b0e1cc9a057295d75ec7c03e6e89094fa0787ca4",
|
||||
"reference": "b0e1cc9a057295d75ec7c03e6e89094fa0787ca4",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5f5db0b35f586eb5bca0581a10bb42dd56575986",
|
||||
"reference": "5f5db0b35f586eb5bca0581a10bb42dd56575986",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4040,7 +4093,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:37:59+00:00"
|
||||
"time": "2021-02-23T15:47:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/comparator",
|
||||
|
@ -4048,12 +4101,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/comparator.git",
|
||||
"reference": "56f15c16d786947d3fbb9df2788ae14049d34286"
|
||||
"reference": "dbc5fb421f242a5749845dc8dd0dc8cde2979dd9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/56f15c16d786947d3fbb9df2788ae14049d34286",
|
||||
"reference": "56f15c16d786947d3fbb9df2788ae14049d34286",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dbc5fb421f242a5749845dc8dd0dc8cde2979dd9",
|
||||
"reference": "dbc5fb421f242a5749845dc8dd0dc8cde2979dd9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4115,7 +4168,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:38:07+00:00"
|
||||
"time": "2021-02-23T15:47:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/complexity",
|
||||
|
@ -4180,12 +4233,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/diff.git",
|
||||
"reference": "33d65ae1c50be986bfbddd876d23ea3042bc2b5f"
|
||||
"reference": "93e6aa13f3dc5f8327e7fb9756e9655fc4c23e90"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/33d65ae1c50be986bfbddd876d23ea3042bc2b5f",
|
||||
"reference": "33d65ae1c50be986bfbddd876d23ea3042bc2b5f",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/93e6aa13f3dc5f8327e7fb9756e9655fc4c23e90",
|
||||
"reference": "93e6aa13f3dc5f8327e7fb9756e9655fc4c23e90",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4239,7 +4292,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:38:16+00:00"
|
||||
"time": "2021-02-23T15:47:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
|
@ -4247,12 +4300,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/environment.git",
|
||||
"reference": "d5a0fb77ea34154ab24cc9ada037e9f2b5715842"
|
||||
"reference": "6e1743b808be9cfd33a716583ccb94b7d4d32e94"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d5a0fb77ea34154ab24cc9ada037e9f2b5715842",
|
||||
"reference": "d5a0fb77ea34154ab24cc9ada037e9f2b5715842",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e1743b808be9cfd33a716583ccb94b7d4d32e94",
|
||||
"reference": "6e1743b808be9cfd33a716583ccb94b7d4d32e94",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4303,7 +4356,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:38:24+00:00"
|
||||
"time": "2021-02-23T15:48:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
|
@ -4311,12 +4364,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/exporter.git",
|
||||
"reference": "36878bc8e65b75bdd37fe65ed6939e6374164b06"
|
||||
"reference": "eca7281ab29075df68b113a37a83be616b629b12"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/36878bc8e65b75bdd37fe65ed6939e6374164b06",
|
||||
"reference": "36878bc8e65b75bdd37fe65ed6939e6374164b06",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/eca7281ab29075df68b113a37a83be616b629b12",
|
||||
"reference": "eca7281ab29075df68b113a37a83be616b629b12",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4381,7 +4434,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:38:32+00:00"
|
||||
"time": "2021-02-23T15:48:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/global-state",
|
||||
|
@ -4389,12 +4442,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/global-state.git",
|
||||
"reference": "48eacca30bf0ee1f7b4ba27ddbf5a448d5eae9b9"
|
||||
"reference": "0ac702e6d13725242edb9b294c5d20b92fcfb8b4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/48eacca30bf0ee1f7b4ba27ddbf5a448d5eae9b9",
|
||||
"reference": "48eacca30bf0ee1f7b4ba27ddbf5a448d5eae9b9",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ac702e6d13725242edb9b294c5d20b92fcfb8b4",
|
||||
"reference": "0ac702e6d13725242edb9b294c5d20b92fcfb8b4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4446,7 +4499,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:38:40+00:00"
|
||||
"time": "2021-02-23T15:48:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/lines-of-code",
|
||||
|
@ -4511,12 +4564,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
|
||||
"reference": "00ebe4f5fb5fbc4e7ab57545f70c0ef61392f527"
|
||||
"reference": "8cc80b4bda00a4c5997c3fc597a34872f3a1007d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/00ebe4f5fb5fbc4e7ab57545f70c0ef61392f527",
|
||||
"reference": "00ebe4f5fb5fbc4e7ab57545f70c0ef61392f527",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/8cc80b4bda00a4c5997c3fc597a34872f3a1007d",
|
||||
"reference": "8cc80b4bda00a4c5997c3fc597a34872f3a1007d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4561,7 +4614,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:38:48+00:00"
|
||||
"time": "2021-02-23T15:48:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/object-reflector",
|
||||
|
@ -4569,12 +4622,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/object-reflector.git",
|
||||
"reference": "13af24fcef1a0857804d8f1896e95af4f01c37f0"
|
||||
"reference": "1d33587c2c3e636936f895e103a9e82dd8102a8e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/13af24fcef1a0857804d8f1896e95af4f01c37f0",
|
||||
"reference": "13af24fcef1a0857804d8f1896e95af4f01c37f0",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/1d33587c2c3e636936f895e103a9e82dd8102a8e",
|
||||
"reference": "1d33587c2c3e636936f895e103a9e82dd8102a8e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4617,7 +4670,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:38:56+00:00"
|
||||
"time": "2021-02-23T15:48:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/recursion-context",
|
||||
|
@ -4625,12 +4678,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
||||
"reference": "43746c15374dba48c7c81f8e993b21888c943a83"
|
||||
"reference": "43f58a51e8f853aadb228ba818d2be388af7237b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/43746c15374dba48c7c81f8e993b21888c943a83",
|
||||
"reference": "43746c15374dba48c7c81f8e993b21888c943a83",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/43f58a51e8f853aadb228ba818d2be388af7237b",
|
||||
"reference": "43f58a51e8f853aadb228ba818d2be388af7237b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4681,7 +4734,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:39:30+00:00"
|
||||
"time": "2021-02-23T15:49:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/resource-operations",
|
||||
|
@ -4745,12 +4798,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/type.git",
|
||||
"reference": "819c8e7fba19e9c2137b238040b906f1586cc7cc"
|
||||
"reference": "557863473c1de00e165a288d5b547f1f83652e7e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/819c8e7fba19e9c2137b238040b906f1586cc7cc",
|
||||
"reference": "819c8e7fba19e9c2137b238040b906f1586cc7cc",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/557863473c1de00e165a288d5b547f1f83652e7e",
|
||||
"reference": "557863473c1de00e165a288d5b547f1f83652e7e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4794,7 +4847,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-21T06:39:38+00:00"
|
||||
"time": "2021-02-23T15:49:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/version",
|
||||
|
@ -4893,12 +4946,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "539148499aaafa5058d534582f61ce2a66480987"
|
||||
"reference": "c08d7d0d458eceb62996d81d3be8d9fbf5564ec4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/539148499aaafa5058d534582f61ce2a66480987",
|
||||
"reference": "539148499aaafa5058d534582f61ce2a66480987",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/c08d7d0d458eceb62996d81d3be8d9fbf5564ec4",
|
||||
"reference": "c08d7d0d458eceb62996d81d3be8d9fbf5564ec4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4983,7 +5036,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-18T11:02:40+00:00"
|
||||
"time": "2021-02-23T10:10:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-grapheme",
|
||||
|
@ -5403,12 +5456,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/service-contracts.git",
|
||||
"reference": "bf99754c6182a126968b1c2709d18548489f27eb"
|
||||
"reference": "e830e6ceebd6377b019e4c9a523d6f2c27007e4a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/bf99754c6182a126968b1c2709d18548489f27eb",
|
||||
"reference": "bf99754c6182a126968b1c2709d18548489f27eb",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/e830e6ceebd6377b019e4c9a523d6f2c27007e4a",
|
||||
"reference": "e830e6ceebd6377b019e4c9a523d6f2c27007e4a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -5422,7 +5475,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.3-dev"
|
||||
"dev-main": "2.4-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
|
@ -5475,7 +5528,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-01-27T16:27:53+00:00"
|
||||
"time": "2021-02-25T16:38:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
|
@ -5617,12 +5670,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "429f90a02d3bd4a06787ac9bc48c56c4320b58a0"
|
||||
"reference": "728c611e8643a5dd44839ffa791e21763b04a694"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/429f90a02d3bd4a06787ac9bc48c56c4320b58a0",
|
||||
"reference": "429f90a02d3bd4a06787ac9bc48c56c4320b58a0",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/728c611e8643a5dd44839ffa791e21763b04a694",
|
||||
"reference": "728c611e8643a5dd44839ffa791e21763b04a694",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -5688,7 +5741,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-08T09:50:07+00:00"
|
||||
"time": "2021-02-22T11:56:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vimeo/psalm",
|
||||
|
|
|
@ -1,220 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Resize;
|
||||
|
||||
use Exception;
|
||||
use Imagick;
|
||||
|
||||
class Resize
|
||||
{
|
||||
private $image;
|
||||
|
||||
private $width;
|
||||
|
||||
private $height;
|
||||
|
||||
/**
|
||||
* @param string $data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->image = new Imagick();
|
||||
|
||||
$this->image->readImageBlob($data);
|
||||
|
||||
$this->width = $this->image->getImageWidth();
|
||||
$this->height = $this->image->getImageHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
*
|
||||
* @return Resize
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function crop(int $width, int $height)
|
||||
{
|
||||
$originalAspect = $this->width / $this->height;
|
||||
|
||||
if (empty($width)) {
|
||||
$width = $height * $originalAspect;
|
||||
}
|
||||
|
||||
if (empty($height)) {
|
||||
$height = $width / $originalAspect;
|
||||
}
|
||||
|
||||
if (empty($height) && empty($width)) {
|
||||
$height = $this->height;
|
||||
$width = $this->width;
|
||||
}
|
||||
|
||||
if ($this->image->getImageFormat() == 'GIF') {
|
||||
$this->image = $this->image->coalesceImages();
|
||||
|
||||
foreach ($this->image as $frame) {
|
||||
$frame->cropThumbnailImage($width, $height);
|
||||
}
|
||||
|
||||
$this->image->deconstructImages();
|
||||
} else {
|
||||
$this->image->cropThumbnailImage($width, $height);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $color
|
||||
*
|
||||
* @return Resize
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function setBackground($color)
|
||||
{
|
||||
$this->image->setImageBackgroundColor($color);
|
||||
$this->image = $this->image->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output.
|
||||
*
|
||||
* Prints manipulated image.
|
||||
*
|
||||
* @param string $type
|
||||
* @param int $quality
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function output(string $type, int $quality = 75)
|
||||
{
|
||||
return $this->save(null, $type, $quality);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param $type
|
||||
* @param int $quality
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function save(string $path = null, string $type = '', int $quality = 75)
|
||||
{
|
||||
// Create directory with write permissions
|
||||
if (null !== $path && !\file_exists(\dirname($path))) {
|
||||
if (!@\mkdir(\dirname($path), 0755, true)) {
|
||||
throw new Exception('Can\'t create directory '.\dirname($path));
|
||||
}
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'jpg':
|
||||
case 'jpeg':
|
||||
$this->image->setImageCompressionQuality($quality);
|
||||
|
||||
$this->image->setImageFormat('jpg');
|
||||
break;
|
||||
|
||||
case 'gif':
|
||||
$this->image->setImageFormat('gif');
|
||||
break;
|
||||
|
||||
case 'webp':
|
||||
try {
|
||||
$this->image->setImageFormat('webp');
|
||||
} catch (\Throwable $th) {
|
||||
$signature = $this->image->getImageSignature();
|
||||
$temp = '/tmp/temp-'.$signature.'.'.\strtolower($this->image->getImageFormat());
|
||||
$output = '/tmp/output-'.$signature.'.webp';
|
||||
|
||||
// save temp
|
||||
$this->image->writeImages($temp, true);
|
||||
|
||||
// convert temp
|
||||
\exec("cwebp -quiet -metadata none -q $quality $temp -o $output");
|
||||
|
||||
$data = \file_get_contents($output);
|
||||
|
||||
//load webp
|
||||
if (empty($path)) {
|
||||
return $data;
|
||||
} else {
|
||||
\file_put_contents($path, $data, LOCK_EX);
|
||||
}
|
||||
|
||||
$this->image->clear();
|
||||
$this->image->destroy();
|
||||
|
||||
//delete webp
|
||||
\unlink($output);
|
||||
\unlink($temp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
/* Scale quality from 0-100 to 0-9 */
|
||||
$scaleQuality = \round(($quality / 100) * 9);
|
||||
|
||||
/* Invert quality setting as 0 is best, not 9 */
|
||||
$invertScaleQuality = 9 - $scaleQuality;
|
||||
|
||||
$this->image->setImageCompressionQuality($invertScaleQuality);
|
||||
|
||||
$this->image->setImageFormat('png');
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception('Invalid output type given');
|
||||
break;
|
||||
}
|
||||
|
||||
if (empty($path)) {
|
||||
return $this->image->getImagesBlob();
|
||||
} else {
|
||||
$this->image->writeImages($path, true);
|
||||
}
|
||||
|
||||
$this->image->clear();
|
||||
$this->image->destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $newHeight
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getSizeByFixedHeight(int $newHeight):int
|
||||
{
|
||||
$ratio = $this->width / $this->height;
|
||||
$newWidth = $newHeight * $ratio;
|
||||
|
||||
return $newWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $newWidth
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getSizeByFixedWidth(int $newWidth):int
|
||||
{
|
||||
$ratio = $this->height / $this->width;
|
||||
$newHeight = $newWidth * $ratio;
|
||||
|
||||
return $newHeight;
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 799 B |
Before Width: | Height: | Size: 596 KiB |
Before Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 23 KiB |
|
@ -1,170 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Appwrite\Resize\Resize;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ResizeTest extends TestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function testCrop100x100()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/100x100.jpg';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$resize->save($target, 'jpg', 100);
|
||||
|
||||
$this->assertEquals(\is_readable($target), true);
|
||||
$this->assertNotEmpty(\md5(\file_get_contents($target)));
|
||||
|
||||
$image = new \Imagick($target);
|
||||
$this->assertEquals(100, $image->getImageWidth());
|
||||
$this->assertEquals(100, $image->getImageHeight());
|
||||
$this->assertEquals('JPEG', $image->getImageFormat());
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x400()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/100x400.jpg';
|
||||
|
||||
$resize->crop(100, 400);
|
||||
|
||||
$resize->save($target, 'jpg', 100);
|
||||
|
||||
$this->assertEquals(\is_readable($target), true);
|
||||
$this->assertNotEmpty(\md5(\file_get_contents($target)));
|
||||
|
||||
$image = new \Imagick($target);
|
||||
$this->assertEquals(100, $image->getImageWidth());
|
||||
$this->assertEquals(400, $image->getImageHeight());
|
||||
$this->assertEquals('JPEG', $image->getImageFormat());
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop400x100()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/400x100.jpg';
|
||||
|
||||
$resize->crop(400, 100);
|
||||
|
||||
$resize->save($target, 'jpg', 100);
|
||||
|
||||
$this->assertEquals(\is_readable($target), true);
|
||||
$this->assertNotEmpty(\md5(\file_get_contents($target)));
|
||||
|
||||
$image = new \Imagick($target);
|
||||
$this->assertEquals(400, $image->getImageWidth());
|
||||
$this->assertEquals(100, $image->getImageHeight());
|
||||
$this->assertEquals('JPEG', $image->getImageFormat());
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x100WEBP()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/100x100.webp';
|
||||
$original = __DIR__.'/../../resources/resize/100x100.webp';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$resize->save($target, 'webp', 100);
|
||||
|
||||
$this->assertEquals(\is_readable($target), true);
|
||||
$this->assertNotEmpty(\md5(\file_get_contents($target)));
|
||||
|
||||
$image = new \Imagick($target);
|
||||
|
||||
$this->assertEquals(100, $image->getImageWidth());
|
||||
$this->assertEquals(100, $image->getImageHeight());
|
||||
$this->assertTrue(in_array($image->getImageFormat(), ['PAM', 'WEBP']));
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x100PNG()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/100x100.png';
|
||||
$original = __DIR__.'/../../resources/resize/100x100.png';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$resize->save($target, 'png', 100);
|
||||
|
||||
$this->assertEquals(\is_readable($target), true);
|
||||
$this->assertGreaterThan(15000, \filesize($target));
|
||||
$this->assertLessThan(30000, \filesize($target));
|
||||
$this->assertEquals(\mime_content_type($target), \mime_content_type($original));
|
||||
$this->assertNotEmpty(\md5(\file_get_contents($target)));
|
||||
|
||||
$image = new \Imagick($target);
|
||||
$this->assertEquals(100, $image->getImageWidth());
|
||||
$this->assertEquals(100, $image->getImageHeight());
|
||||
$this->assertEquals('PNG', $image->getImageFormat());
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x100PNGQuality30()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/100x100-q30.jpg';
|
||||
$original = __DIR__.'/../../resources/resize/100x100-q30.jpg';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$resize->save($target, 'jpg', 10);
|
||||
|
||||
$this->assertEquals(\is_readable($target), true);
|
||||
$this->assertGreaterThan(500, \filesize($target));
|
||||
$this->assertLessThan(2000, \filesize($target));
|
||||
$this->assertEquals(\mime_content_type($target), \mime_content_type($original));
|
||||
$this->assertNotEmpty(\md5(\file_get_contents($target)));
|
||||
|
||||
$image = new \Imagick($target);
|
||||
$this->assertEquals(100, $image->getImageWidth());
|
||||
$this->assertEquals(100, $image->getImageHeight());
|
||||
$this->assertEquals('JPEG', $image->getImageFormat());
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x100GIF()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-3.gif'));
|
||||
$target = __DIR__.'/100x100.gif';
|
||||
$original = __DIR__.'/../../resources/resize/100x100.gif';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$resize->save($target, 'gif', 100);
|
||||
|
||||
$this->assertEquals(\is_readable($target), true);
|
||||
$this->assertGreaterThan(400000, \filesize($target));
|
||||
$this->assertLessThan(800000, \filesize($target));
|
||||
$this->assertEquals(\mime_content_type($target), \mime_content_type($original));
|
||||
$this->assertNotEmpty(\md5(\file_get_contents($target)));
|
||||
|
||||
$image = new \Imagick($target);
|
||||
$this->assertEquals(100, $image->getImageWidth());
|
||||
$this->assertEquals(100, $image->getImageHeight());
|
||||
$this->assertEquals('GIF', $image->getImageFormat());
|
||||
\unlink($target);
|
||||
}
|
||||
}
|