├── .gitignore
├── .scrutinizer.yml
├── CHANGELOG.md
├── README.md
├── composer.json
├── composer.lock
├── phpunit.xml
├── src
└── Brendt
│ └── Image
│ ├── Config
│ ├── DefaultConfigurator.php
│ └── ResponsiveFactoryConfigurator.php
│ ├── Exception
│ ├── FileNotFoundException.php
│ └── InvalidConfigurationException.php
│ ├── ResponsiveFactory.php
│ ├── ResponsiveImage.php
│ └── Scaler
│ ├── AbstractScaler.php
│ ├── FileSizeScaler.php
│ ├── Scaler.php
│ ├── SizesScaler.php
│ └── WidthScaler.php
└── tests
├── Brendt
└── Image
│ ├── ResponsiveFactoryTest.php
│ ├── ResponsiveImageTest.php
│ ├── Scaler
│ ├── FileSizeScalerTest.php
│ ├── SizesScalerTest.php
│ └── WidthScalerTest.php
│ └── config
│ └── DefaultConfiguratorTest.php
└── img
└── image.jpeg
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | .idea
3 | /tests/compile
4 | .DS_Store
5 |
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | build:
2 | environment:
3 | php:
4 | version: 7.0.8
5 | tests:
6 | override:
7 | -
8 | command: 'vendor/bin/phpunit'
9 | checks:
10 | php:
11 | code_rating: true
12 | duplication: true
13 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 1.9.1
4 |
5 | - Support PHP 7.0
6 |
7 | ## 1.9.0
8 |
9 | - Refactor code directories.
10 |
11 | ## 1.8.2
12 |
13 | - Cleanup Responsive Factory code.
14 | - Add caching test.
15 |
16 | ## 1.8.1
17 |
18 | - Bugfix for extension of cached files not correctly loading.
19 |
20 | ## 1.8.0
21 |
22 | - Add `includeSource` parameter.
23 |
24 | ## 1.7.3
25 |
26 | - Bugfix for invalid cache path when rebase was enabled.
27 |
28 | ## 1.7.2
29 |
30 | - Bugfix for wrong composer sources.
31 |
32 | ## 1.7.1
33 |
34 | - Bugfix for srcset not correctly rendering.
35 |
36 | ## 1.7.0
37 |
38 | - Add `sizes` scaler. This scaler can be configured to generate a fixed set of images based on pre-defined widths,
39 | provided via the `sizes` parameter. See the README for more information.
40 |
41 | ## 1.6.0
42 |
43 | - Add `rebase` parameter.
44 | - Add `maxFileSize` parameter.
45 | - Add `maxWidth` parameter.
46 |
47 | ## 1.5.1
48 |
49 | - Fix a bug so that unkown file exceptions are correctly thrown.
50 |
51 | ## 1.5.0
52 |
53 | - Removed AMP dependencies.
54 |
55 | ## 1.4.1
56 |
57 | - Temporary remove Amp because of BC breaking changes with each update.
58 |
59 | ## 1.4.0
60 |
61 | - Add optimizer options support
62 |
63 | ## 1.3.2
64 |
65 | - Add fixed amphp versions because of BC breaking changes in their library.
66 |
67 | ## 1.3.1
68 |
69 | - Several bug fixes and optimizations when running enabling the `async` option.
70 |
71 | ## 1.3.0
72 |
73 | - Add `async` option to downscale images in separate processes. PHP's `pcntl` extension is required for this to work.
74 |
75 | ## 1.2.2
76 |
77 | - Add simple construct for the ResponsiveFactory.
78 |
79 | ## 1.2.1
80 |
81 | - Fixed bug with the cache not being searched in the public path.
82 |
83 | ## 1.2.0
84 |
85 | - Update minimum requirements to PHP 7.1.
86 | - Refactor scalers to only calculate file sizes and not handle image saving.
87 | - Add `optimize` parameter to run image optimizers. Defaults to `false`.
88 |
89 | ## 1.1.2
90 |
91 | - Improve caching, scalers are now not used when images are already cached.
92 | - Set default `minFileSize` to 5 KB.
93 |
94 | ## 1.1.0
95 |
96 | - Add Scaler support
97 | - Add FileSize scaler as default.
98 |
99 | To use the old scaler:
100 |
101 | ```php
102 | $factory = new ResponsiveFactory(new DefaultConfigurator([
103 | 'scaler' => 'width',
104 | ]));
105 | ```
106 |
107 | The new Scaler is called `filesize` and set by default, this scaler differs from the width scaler because it scales down
108 | based on file size instead of the width of an image.
109 |
110 | ```php
111 | $factory = new ResponsiveFactory(new DefaultConfigurator([
112 | 'scaler' => 'filesize',
113 | ]));
114 | ```
115 |
116 | **Note**: the `stepModifier` parameter is now used different, the higher this modifier, the more images will be generated.
117 |
118 | ## 1.0.0
119 |
120 | - Use PSR naming standards.
121 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://scrutinizer-ci.com/g/brendt/responsive-images/build-status/master) [](https://scrutinizer-ci.com/g/brendt/responsive-images/?branch=master)
2 |
3 | # Responsive Images
4 |
5 | Automatically generate responsive images to work with the `srcset` and `sizes` spec. ([http://responsiveimages.org/](http://responsiveimages.org/))
6 |
7 | ```sh
8 | composer require brendt/responsive-images
9 | ```
10 |
11 | ## Usage
12 |
13 | ```php
14 | use Brendt\Image\ResponsiveFactory;
15 |
16 | $factory = new ResponsiveFactory();
17 | $image = $factory->create('img/image.jpeg');
18 | ```
19 |
20 | ```html
21 |
23 | ```
24 |
25 | This sample would generate something like:
26 |
27 | ```hmtl
28 |
34 | ```
35 |
36 | ## Configuration
37 |
38 | The `ResponsiveFactory` can take a `ResponsiveFactoryConfigurator` object which will set the needed parameters.
39 | A default configurator `DefaultConfigurator` is provider out of the box, and uses the following parameters:
40 |
41 | ```php
42 | [
43 | 'driver' => 'gd',
44 | 'includeSource' => true,
45 | 'publicPath' => './',
46 | 'sourcePath' => './',
47 | 'rebase' => false,
48 | 'enableCache' => false,
49 | 'optimize' => false,
50 | 'scaler' => 'filesize',
51 | 'stepModifier' => 0.5,
52 | 'minFileSize' => 5000,
53 | 'maxFileSize' => null,
54 | 'minWidth' => 300,
55 | 'maxWidth' => null,
56 | 'sizes' => [ 1920, 840, 300 ],
57 | 'optimizerOptions' => [],
58 | ]
59 | ```
60 |
61 | You can override these parameters by providing and array to the `DefaultConfigurator`,
62 | or create a whole new configurator which implements `ResponsiveFactoryConfigurator`.
63 |
64 | ```php
65 | $factory = new ResponsiveFactory(new DefaultConfigurator([
66 | 'driver' => 'imagick',
67 | 'sourcePath' => './src',
68 | 'publicPath' => './public',
69 | 'enableCache' => true,
70 | ]));
71 | ```
72 |
73 | ### All configuration options
74 |
75 | - `driver`: the image driver to use. Defaults to `gd`. Possible options are `gd` or `imagick`.
76 | - `includeSource`: whether to include the source image in the `srcset`. Defaults to `true`.
77 | - `sourcePath`: the path to load image source files. Defaults to `./`.
78 | - `publicPath`: the path to render image files. Defaults to `./`.
79 | - `rebase`: ignore the path of the requested image when searching in the source directory. Defaults to `false`.
80 | - `enableCache`: enable or disable image caching. Enabling the cache wont' override existing images. Defaults to `false`.
81 | - `optimize`: enable or disable the use of different optimizers (if installed on the system). Defaults to `false`.
82 | - `scaler`: which scaler algorithm to use. Defaults to `filesize`. Possible options are `filesize`, `width` or `sizes`.
83 | - `stepModifier`: a percentage (between 0 and 1) which is used to create different image sizes. The higher this modifier, the more image variations will be rendered. Defaults to `0.5`.
84 | - `minFileSize`: the minimum image filesize in bytes. Defaults to `5000`B (5KB).
85 | - `maxFileSize`: the maximum image filesize in bytes. Defaults to `null`.
86 | - `minWidth`: the minimum image size in pixels. No images with size smaller than this number will be rendered. Defaults to `300` pixels.
87 | - `maxWidth`: the maximum image size in pixels. No images with size smaller than this number will be rendered. Defaults to `null`.
88 | - `sizes`: this parameter is used when the `sizes` scaler is enabled. This scaler will generate a fixed set of sizes, based on this array.
89 | The expected values are the widths of the generated images. Defaults to `[]` (empty array).
90 | - `optimizerOptions`: options to pass to the image optimizer library. See [https://github.com/psliwa/image-optimizer](https://github.com/psliwa/image-optimizer) for more information.
91 |
92 | ### Paths
93 |
94 | The `sourcePath` parameter is used to define where image source files are located.
95 | In case of the first example and above configuration, the image file should be saved in `./src/img/image.jpeg`.
96 |
97 | The `publicPath` parameter is used to save rendered images into. This path should be the public directory of your website.
98 | The above example would render images into `./public/img/image.jpeg`.
99 |
100 | #### Path rebasing
101 |
102 | When the `rebase` option is enabled, source file lookup will differ: only the filename is used to search the file in the
103 | source directory. An example would be the following.
104 |
105 | ```php
106 | // Without rebase
107 |
108 | $options = [
109 | 'sourcePath' => './src/images',
110 | 'publicPath' => './public',
111 | ];
112 |
113 | $image = $factory->create('/img/responsive/image.jpeg');
114 |
115 | // Source file is searched in './src/images/img/responsive/image.jpeg'
116 | // Public files are saved in './public/img/responsive/image-x.jpg'
117 | ```
118 |
119 | ```php
120 | // With rebase
121 |
122 | $options = [
123 | 'sourcePath' => './src/images',
124 | 'publicPath' => './public',
125 | 'rebase' => true,
126 | ];
127 |
128 | $image = $factory->create('/img/responsive/image.jpeg');
129 |
130 | // Source file is searched in './src/images/image.jpeg'
131 | // Public files are saved in './public/img/responsive/image-x.jpg'
132 | ```
133 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "brendt/responsive-images",
3 | "description" : "Create responsive images with PHP, using the srcset and sizes spec.",
4 | "license" : "MIT",
5 | "authors" : [
6 | {
7 | "name" : "Brent",
8 | "email" : "brent@pageon.be"
9 | }
10 | ],
11 | "prefer-stable": true,
12 | "require" : {
13 | "PHP" : ">=7.0",
14 | "symfony/finder" : "^3.1",
15 | "symfony/filesystem" : "^3.1",
16 | "intervention/image": "^2.3",
17 | "ps/image-optimizer": "^1.0"
18 | },
19 | "require-dev" : {
20 | "larapack/dd" : "^1.0",
21 | "phpunit/phpunit" : "^5.0"
22 | },
23 | "autoload" : {
24 | "psr-4" : {
25 | "Brendt\\Image\\" : "src/Brendt/Image"
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/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": "fa3f6a1672cb53a286b4a1e1ed2e993d",
8 | "content-hash": "cd2518b0f1f6246ade16b3a09fd7da1a",
9 | "packages": [
10 | {
11 | "name": "guzzlehttp/psr7",
12 | "version": "1.4.2",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/guzzle/psr7.git",
16 | "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
21 | "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "php": ">=5.4.0",
26 | "psr/http-message": "~1.0"
27 | },
28 | "provide": {
29 | "psr/http-message-implementation": "1.0"
30 | },
31 | "require-dev": {
32 | "phpunit/phpunit": "~4.0"
33 | },
34 | "type": "library",
35 | "extra": {
36 | "branch-alias": {
37 | "dev-master": "1.4-dev"
38 | }
39 | },
40 | "autoload": {
41 | "psr-4": {
42 | "GuzzleHttp\\Psr7\\": "src/"
43 | },
44 | "files": [
45 | "src/functions_include.php"
46 | ]
47 | },
48 | "notification-url": "https://packagist.org/downloads/",
49 | "license": [
50 | "MIT"
51 | ],
52 | "authors": [
53 | {
54 | "name": "Michael Dowling",
55 | "email": "mtdowling@gmail.com",
56 | "homepage": "https://github.com/mtdowling"
57 | },
58 | {
59 | "name": "Tobias Schultze",
60 | "homepage": "https://github.com/Tobion"
61 | }
62 | ],
63 | "description": "PSR-7 message implementation that also provides common utility methods",
64 | "keywords": [
65 | "http",
66 | "message",
67 | "request",
68 | "response",
69 | "stream",
70 | "uri",
71 | "url"
72 | ],
73 | "time": "2017-03-20 17:10:46"
74 | },
75 | {
76 | "name": "intervention/image",
77 | "version": "2.3.12",
78 | "source": {
79 | "type": "git",
80 | "url": "https://github.com/Intervention/image.git",
81 | "reference": "5c92ea4503ccb000ce6a922efbf272638c64a68c"
82 | },
83 | "dist": {
84 | "type": "zip",
85 | "url": "https://api.github.com/repos/Intervention/image/zipball/5c92ea4503ccb000ce6a922efbf272638c64a68c",
86 | "reference": "5c92ea4503ccb000ce6a922efbf272638c64a68c",
87 | "shasum": ""
88 | },
89 | "require": {
90 | "ext-fileinfo": "*",
91 | "guzzlehttp/psr7": "~1.1",
92 | "php": ">=5.4.0"
93 | },
94 | "require-dev": {
95 | "mockery/mockery": "~0.9.2",
96 | "phpunit/phpunit": "3.*"
97 | },
98 | "suggest": {
99 | "ext-gd": "to use GD library based image processing.",
100 | "ext-imagick": "to use Imagick based image processing.",
101 | "intervention/imagecache": "Caching extension for the Intervention Image library"
102 | },
103 | "type": "library",
104 | "extra": {
105 | "branch-alias": {
106 | "dev-master": "2.3-dev"
107 | }
108 | },
109 | "autoload": {
110 | "psr-4": {
111 | "Intervention\\Image\\": "src/Intervention/Image"
112 | }
113 | },
114 | "notification-url": "https://packagist.org/downloads/",
115 | "license": [
116 | "MIT"
117 | ],
118 | "authors": [
119 | {
120 | "name": "Oliver Vogel",
121 | "email": "oliver@olivervogel.net",
122 | "homepage": "http://olivervogel.net/"
123 | }
124 | ],
125 | "description": "Image handling and manipulation library with support for Laravel integration",
126 | "homepage": "http://image.intervention.io/",
127 | "keywords": [
128 | "gd",
129 | "image",
130 | "imagick",
131 | "laravel",
132 | "thumbnail",
133 | "watermark"
134 | ],
135 | "time": "2017-04-22 14:50:13"
136 | },
137 | {
138 | "name": "ps/image-optimizer",
139 | "version": "1.1.0",
140 | "source": {
141 | "type": "git",
142 | "url": "https://github.com/psliwa/image-optimizer.git",
143 | "reference": "6e7461722d798ab6e77fb7f483d679ac37b71bec"
144 | },
145 | "dist": {
146 | "type": "zip",
147 | "url": "https://api.github.com/repos/psliwa/image-optimizer/zipball/6e7461722d798ab6e77fb7f483d679ac37b71bec",
148 | "reference": "6e7461722d798ab6e77fb7f483d679ac37b71bec",
149 | "shasum": ""
150 | },
151 | "require": {
152 | "psr/log": "1.0.*",
153 | "symfony/options-resolver": "~2.1 | ~3.0",
154 | "symfony/process": "~2.0 | ~3.0"
155 | },
156 | "require-dev": {
157 | "phpunit/phpunit": "^5.0"
158 | },
159 | "type": "library",
160 | "autoload": {
161 | "psr-0": {
162 | "ImageOptimizer": "src/"
163 | }
164 | },
165 | "notification-url": "https://packagist.org/downloads/",
166 | "license": [
167 | "MIT"
168 | ],
169 | "authors": [
170 | {
171 | "name": "Piotr Sliwa",
172 | "email": "peter.pl7@gmail.com"
173 | }
174 | ],
175 | "description": "Image optimization / compression library. This library is able to optimize png, jpg and gif files in very easy and handy way. It uses optipng, pngquant, pngcrush, pngout, gifsicle, jpegoptim and jpegtran tools.",
176 | "keywords": [
177 | "compression",
178 | "image",
179 | "image optimizer",
180 | "jpegoptim",
181 | "optimization",
182 | "optipng"
183 | ],
184 | "time": "2017-03-25 15:42:56"
185 | },
186 | {
187 | "name": "psr/http-message",
188 | "version": "1.0.1",
189 | "source": {
190 | "type": "git",
191 | "url": "https://github.com/php-fig/http-message.git",
192 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
193 | },
194 | "dist": {
195 | "type": "zip",
196 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
197 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
198 | "shasum": ""
199 | },
200 | "require": {
201 | "php": ">=5.3.0"
202 | },
203 | "type": "library",
204 | "extra": {
205 | "branch-alias": {
206 | "dev-master": "1.0.x-dev"
207 | }
208 | },
209 | "autoload": {
210 | "psr-4": {
211 | "Psr\\Http\\Message\\": "src/"
212 | }
213 | },
214 | "notification-url": "https://packagist.org/downloads/",
215 | "license": [
216 | "MIT"
217 | ],
218 | "authors": [
219 | {
220 | "name": "PHP-FIG",
221 | "homepage": "http://www.php-fig.org/"
222 | }
223 | ],
224 | "description": "Common interface for HTTP messages",
225 | "homepage": "https://github.com/php-fig/http-message",
226 | "keywords": [
227 | "http",
228 | "http-message",
229 | "psr",
230 | "psr-7",
231 | "request",
232 | "response"
233 | ],
234 | "time": "2016-08-06 14:39:51"
235 | },
236 | {
237 | "name": "psr/log",
238 | "version": "1.0.2",
239 | "source": {
240 | "type": "git",
241 | "url": "https://github.com/php-fig/log.git",
242 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
243 | },
244 | "dist": {
245 | "type": "zip",
246 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
247 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
248 | "shasum": ""
249 | },
250 | "require": {
251 | "php": ">=5.3.0"
252 | },
253 | "type": "library",
254 | "extra": {
255 | "branch-alias": {
256 | "dev-master": "1.0.x-dev"
257 | }
258 | },
259 | "autoload": {
260 | "psr-4": {
261 | "Psr\\Log\\": "Psr/Log/"
262 | }
263 | },
264 | "notification-url": "https://packagist.org/downloads/",
265 | "license": [
266 | "MIT"
267 | ],
268 | "authors": [
269 | {
270 | "name": "PHP-FIG",
271 | "homepage": "http://www.php-fig.org/"
272 | }
273 | ],
274 | "description": "Common interface for logging libraries",
275 | "homepage": "https://github.com/php-fig/log",
276 | "keywords": [
277 | "log",
278 | "psr",
279 | "psr-3"
280 | ],
281 | "time": "2016-10-10 12:19:37"
282 | },
283 | {
284 | "name": "symfony/filesystem",
285 | "version": "v3.2.7",
286 | "source": {
287 | "type": "git",
288 | "url": "https://github.com/symfony/filesystem.git",
289 | "reference": "64421e6479c4a8e60d790fb666bd520992861b66"
290 | },
291 | "dist": {
292 | "type": "zip",
293 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/64421e6479c4a8e60d790fb666bd520992861b66",
294 | "reference": "64421e6479c4a8e60d790fb666bd520992861b66",
295 | "shasum": ""
296 | },
297 | "require": {
298 | "php": ">=5.5.9"
299 | },
300 | "type": "library",
301 | "extra": {
302 | "branch-alias": {
303 | "dev-master": "3.2-dev"
304 | }
305 | },
306 | "autoload": {
307 | "psr-4": {
308 | "Symfony\\Component\\Filesystem\\": ""
309 | },
310 | "exclude-from-classmap": [
311 | "/Tests/"
312 | ]
313 | },
314 | "notification-url": "https://packagist.org/downloads/",
315 | "license": [
316 | "MIT"
317 | ],
318 | "authors": [
319 | {
320 | "name": "Fabien Potencier",
321 | "email": "fabien@symfony.com"
322 | },
323 | {
324 | "name": "Symfony Community",
325 | "homepage": "https://symfony.com/contributors"
326 | }
327 | ],
328 | "description": "Symfony Filesystem Component",
329 | "homepage": "https://symfony.com",
330 | "time": "2017-03-26 15:47:15"
331 | },
332 | {
333 | "name": "symfony/finder",
334 | "version": "v3.2.7",
335 | "source": {
336 | "type": "git",
337 | "url": "https://github.com/symfony/finder.git",
338 | "reference": "b20900ce5ea164cd9314af52725b0bb5a758217a"
339 | },
340 | "dist": {
341 | "type": "zip",
342 | "url": "https://api.github.com/repos/symfony/finder/zipball/b20900ce5ea164cd9314af52725b0bb5a758217a",
343 | "reference": "b20900ce5ea164cd9314af52725b0bb5a758217a",
344 | "shasum": ""
345 | },
346 | "require": {
347 | "php": ">=5.5.9"
348 | },
349 | "type": "library",
350 | "extra": {
351 | "branch-alias": {
352 | "dev-master": "3.2-dev"
353 | }
354 | },
355 | "autoload": {
356 | "psr-4": {
357 | "Symfony\\Component\\Finder\\": ""
358 | },
359 | "exclude-from-classmap": [
360 | "/Tests/"
361 | ]
362 | },
363 | "notification-url": "https://packagist.org/downloads/",
364 | "license": [
365 | "MIT"
366 | ],
367 | "authors": [
368 | {
369 | "name": "Fabien Potencier",
370 | "email": "fabien@symfony.com"
371 | },
372 | {
373 | "name": "Symfony Community",
374 | "homepage": "https://symfony.com/contributors"
375 | }
376 | ],
377 | "description": "Symfony Finder Component",
378 | "homepage": "https://symfony.com",
379 | "time": "2017-03-20 09:32:19"
380 | },
381 | {
382 | "name": "symfony/options-resolver",
383 | "version": "v3.2.7",
384 | "source": {
385 | "type": "git",
386 | "url": "https://github.com/symfony/options-resolver.git",
387 | "reference": "6a19be85237fe8bbd4975f86942b4763bb0da6ca"
388 | },
389 | "dist": {
390 | "type": "zip",
391 | "url": "https://api.github.com/repos/symfony/options-resolver/zipball/6a19be85237fe8bbd4975f86942b4763bb0da6ca",
392 | "reference": "6a19be85237fe8bbd4975f86942b4763bb0da6ca",
393 | "shasum": ""
394 | },
395 | "require": {
396 | "php": ">=5.5.9"
397 | },
398 | "type": "library",
399 | "extra": {
400 | "branch-alias": {
401 | "dev-master": "3.2-dev"
402 | }
403 | },
404 | "autoload": {
405 | "psr-4": {
406 | "Symfony\\Component\\OptionsResolver\\": ""
407 | },
408 | "exclude-from-classmap": [
409 | "/Tests/"
410 | ]
411 | },
412 | "notification-url": "https://packagist.org/downloads/",
413 | "license": [
414 | "MIT"
415 | ],
416 | "authors": [
417 | {
418 | "name": "Fabien Potencier",
419 | "email": "fabien@symfony.com"
420 | },
421 | {
422 | "name": "Symfony Community",
423 | "homepage": "https://symfony.com/contributors"
424 | }
425 | ],
426 | "description": "Symfony OptionsResolver Component",
427 | "homepage": "https://symfony.com",
428 | "keywords": [
429 | "config",
430 | "configuration",
431 | "options"
432 | ],
433 | "time": "2017-03-21 21:44:32"
434 | },
435 | {
436 | "name": "symfony/process",
437 | "version": "v3.2.7",
438 | "source": {
439 | "type": "git",
440 | "url": "https://github.com/symfony/process.git",
441 | "reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282"
442 | },
443 | "dist": {
444 | "type": "zip",
445 | "url": "https://api.github.com/repos/symfony/process/zipball/57fdaa55827ae14d617550ebe71a820f0a5e2282",
446 | "reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282",
447 | "shasum": ""
448 | },
449 | "require": {
450 | "php": ">=5.5.9"
451 | },
452 | "type": "library",
453 | "extra": {
454 | "branch-alias": {
455 | "dev-master": "3.2-dev"
456 | }
457 | },
458 | "autoload": {
459 | "psr-4": {
460 | "Symfony\\Component\\Process\\": ""
461 | },
462 | "exclude-from-classmap": [
463 | "/Tests/"
464 | ]
465 | },
466 | "notification-url": "https://packagist.org/downloads/",
467 | "license": [
468 | "MIT"
469 | ],
470 | "authors": [
471 | {
472 | "name": "Fabien Potencier",
473 | "email": "fabien@symfony.com"
474 | },
475 | {
476 | "name": "Symfony Community",
477 | "homepage": "https://symfony.com/contributors"
478 | }
479 | ],
480 | "description": "Symfony Process Component",
481 | "homepage": "https://symfony.com",
482 | "time": "2017-03-27 18:07:02"
483 | }
484 | ],
485 | "packages-dev": [
486 | {
487 | "name": "doctrine/instantiator",
488 | "version": "1.0.5",
489 | "source": {
490 | "type": "git",
491 | "url": "https://github.com/doctrine/instantiator.git",
492 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
493 | },
494 | "dist": {
495 | "type": "zip",
496 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
497 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
498 | "shasum": ""
499 | },
500 | "require": {
501 | "php": ">=5.3,<8.0-DEV"
502 | },
503 | "require-dev": {
504 | "athletic/athletic": "~0.1.8",
505 | "ext-pdo": "*",
506 | "ext-phar": "*",
507 | "phpunit/phpunit": "~4.0",
508 | "squizlabs/php_codesniffer": "~2.0"
509 | },
510 | "type": "library",
511 | "extra": {
512 | "branch-alias": {
513 | "dev-master": "1.0.x-dev"
514 | }
515 | },
516 | "autoload": {
517 | "psr-4": {
518 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
519 | }
520 | },
521 | "notification-url": "https://packagist.org/downloads/",
522 | "license": [
523 | "MIT"
524 | ],
525 | "authors": [
526 | {
527 | "name": "Marco Pivetta",
528 | "email": "ocramius@gmail.com",
529 | "homepage": "http://ocramius.github.com/"
530 | }
531 | ],
532 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
533 | "homepage": "https://github.com/doctrine/instantiator",
534 | "keywords": [
535 | "constructor",
536 | "instantiate"
537 | ],
538 | "time": "2015-06-14 21:17:01"
539 | },
540 | {
541 | "name": "larapack/dd",
542 | "version": "1.1",
543 | "source": {
544 | "type": "git",
545 | "url": "https://github.com/larapack/dd.git",
546 | "reference": "561b5111a13d0094b59b5c81b1572489485fb948"
547 | },
548 | "dist": {
549 | "type": "zip",
550 | "url": "https://api.github.com/repos/larapack/dd/zipball/561b5111a13d0094b59b5c81b1572489485fb948",
551 | "reference": "561b5111a13d0094b59b5c81b1572489485fb948",
552 | "shasum": ""
553 | },
554 | "require": {
555 | "symfony/var-dumper": "*"
556 | },
557 | "type": "package",
558 | "autoload": {
559 | "files": [
560 | "src/helper.php"
561 | ]
562 | },
563 | "notification-url": "https://packagist.org/downloads/",
564 | "license": [
565 | "MIT"
566 | ],
567 | "authors": [
568 | {
569 | "name": "Mark Topper",
570 | "email": "hi@webman.io"
571 | }
572 | ],
573 | "description": "`dd` is a helper method in Laravel. This package will add the `dd` to your application.",
574 | "time": "2016-12-15 09:34:34"
575 | },
576 | {
577 | "name": "myclabs/deep-copy",
578 | "version": "1.6.1",
579 | "source": {
580 | "type": "git",
581 | "url": "https://github.com/myclabs/DeepCopy.git",
582 | "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102"
583 | },
584 | "dist": {
585 | "type": "zip",
586 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8e6e04167378abf1ddb4d3522d8755c5fd90d102",
587 | "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102",
588 | "shasum": ""
589 | },
590 | "require": {
591 | "php": ">=5.4.0"
592 | },
593 | "require-dev": {
594 | "doctrine/collections": "1.*",
595 | "phpunit/phpunit": "~4.1"
596 | },
597 | "type": "library",
598 | "autoload": {
599 | "psr-4": {
600 | "DeepCopy\\": "src/DeepCopy/"
601 | }
602 | },
603 | "notification-url": "https://packagist.org/downloads/",
604 | "license": [
605 | "MIT"
606 | ],
607 | "description": "Create deep copies (clones) of your objects",
608 | "homepage": "https://github.com/myclabs/DeepCopy",
609 | "keywords": [
610 | "clone",
611 | "copy",
612 | "duplicate",
613 | "object",
614 | "object graph"
615 | ],
616 | "time": "2017-04-12 18:52:22"
617 | },
618 | {
619 | "name": "phpdocumentor/reflection-common",
620 | "version": "1.0",
621 | "source": {
622 | "type": "git",
623 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
624 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
625 | },
626 | "dist": {
627 | "type": "zip",
628 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
629 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
630 | "shasum": ""
631 | },
632 | "require": {
633 | "php": ">=5.5"
634 | },
635 | "require-dev": {
636 | "phpunit/phpunit": "^4.6"
637 | },
638 | "type": "library",
639 | "extra": {
640 | "branch-alias": {
641 | "dev-master": "1.0.x-dev"
642 | }
643 | },
644 | "autoload": {
645 | "psr-4": {
646 | "phpDocumentor\\Reflection\\": [
647 | "src"
648 | ]
649 | }
650 | },
651 | "notification-url": "https://packagist.org/downloads/",
652 | "license": [
653 | "MIT"
654 | ],
655 | "authors": [
656 | {
657 | "name": "Jaap van Otterdijk",
658 | "email": "opensource@ijaap.nl"
659 | }
660 | ],
661 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
662 | "homepage": "http://www.phpdoc.org",
663 | "keywords": [
664 | "FQSEN",
665 | "phpDocumentor",
666 | "phpdoc",
667 | "reflection",
668 | "static analysis"
669 | ],
670 | "time": "2015-12-27 11:43:31"
671 | },
672 | {
673 | "name": "phpdocumentor/reflection-docblock",
674 | "version": "3.1.1",
675 | "source": {
676 | "type": "git",
677 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
678 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
679 | },
680 | "dist": {
681 | "type": "zip",
682 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
683 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
684 | "shasum": ""
685 | },
686 | "require": {
687 | "php": ">=5.5",
688 | "phpdocumentor/reflection-common": "^1.0@dev",
689 | "phpdocumentor/type-resolver": "^0.2.0",
690 | "webmozart/assert": "^1.0"
691 | },
692 | "require-dev": {
693 | "mockery/mockery": "^0.9.4",
694 | "phpunit/phpunit": "^4.4"
695 | },
696 | "type": "library",
697 | "autoload": {
698 | "psr-4": {
699 | "phpDocumentor\\Reflection\\": [
700 | "src/"
701 | ]
702 | }
703 | },
704 | "notification-url": "https://packagist.org/downloads/",
705 | "license": [
706 | "MIT"
707 | ],
708 | "authors": [
709 | {
710 | "name": "Mike van Riel",
711 | "email": "me@mikevanriel.com"
712 | }
713 | ],
714 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
715 | "time": "2016-09-30 07:12:33"
716 | },
717 | {
718 | "name": "phpdocumentor/type-resolver",
719 | "version": "0.2.1",
720 | "source": {
721 | "type": "git",
722 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
723 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
724 | },
725 | "dist": {
726 | "type": "zip",
727 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
728 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
729 | "shasum": ""
730 | },
731 | "require": {
732 | "php": ">=5.5",
733 | "phpdocumentor/reflection-common": "^1.0"
734 | },
735 | "require-dev": {
736 | "mockery/mockery": "^0.9.4",
737 | "phpunit/phpunit": "^5.2||^4.8.24"
738 | },
739 | "type": "library",
740 | "extra": {
741 | "branch-alias": {
742 | "dev-master": "1.0.x-dev"
743 | }
744 | },
745 | "autoload": {
746 | "psr-4": {
747 | "phpDocumentor\\Reflection\\": [
748 | "src/"
749 | ]
750 | }
751 | },
752 | "notification-url": "https://packagist.org/downloads/",
753 | "license": [
754 | "MIT"
755 | ],
756 | "authors": [
757 | {
758 | "name": "Mike van Riel",
759 | "email": "me@mikevanriel.com"
760 | }
761 | ],
762 | "time": "2016-11-25 06:54:22"
763 | },
764 | {
765 | "name": "phpspec/prophecy",
766 | "version": "v1.7.0",
767 | "source": {
768 | "type": "git",
769 | "url": "https://github.com/phpspec/prophecy.git",
770 | "reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
771 | },
772 | "dist": {
773 | "type": "zip",
774 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073",
775 | "reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
776 | "shasum": ""
777 | },
778 | "require": {
779 | "doctrine/instantiator": "^1.0.2",
780 | "php": "^5.3|^7.0",
781 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
782 | "sebastian/comparator": "^1.1|^2.0",
783 | "sebastian/recursion-context": "^1.0|^2.0|^3.0"
784 | },
785 | "require-dev": {
786 | "phpspec/phpspec": "^2.5|^3.2",
787 | "phpunit/phpunit": "^4.8 || ^5.6.5"
788 | },
789 | "type": "library",
790 | "extra": {
791 | "branch-alias": {
792 | "dev-master": "1.6.x-dev"
793 | }
794 | },
795 | "autoload": {
796 | "psr-0": {
797 | "Prophecy\\": "src/"
798 | }
799 | },
800 | "notification-url": "https://packagist.org/downloads/",
801 | "license": [
802 | "MIT"
803 | ],
804 | "authors": [
805 | {
806 | "name": "Konstantin Kudryashov",
807 | "email": "ever.zet@gmail.com",
808 | "homepage": "http://everzet.com"
809 | },
810 | {
811 | "name": "Marcello Duarte",
812 | "email": "marcello.duarte@gmail.com"
813 | }
814 | ],
815 | "description": "Highly opinionated mocking framework for PHP 5.3+",
816 | "homepage": "https://github.com/phpspec/prophecy",
817 | "keywords": [
818 | "Double",
819 | "Dummy",
820 | "fake",
821 | "mock",
822 | "spy",
823 | "stub"
824 | ],
825 | "time": "2017-03-02 20:05:34"
826 | },
827 | {
828 | "name": "phpunit/php-code-coverage",
829 | "version": "4.0.8",
830 | "source": {
831 | "type": "git",
832 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
833 | "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d"
834 | },
835 | "dist": {
836 | "type": "zip",
837 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
838 | "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
839 | "shasum": ""
840 | },
841 | "require": {
842 | "ext-dom": "*",
843 | "ext-xmlwriter": "*",
844 | "php": "^5.6 || ^7.0",
845 | "phpunit/php-file-iterator": "^1.3",
846 | "phpunit/php-text-template": "^1.2",
847 | "phpunit/php-token-stream": "^1.4.2 || ^2.0",
848 | "sebastian/code-unit-reverse-lookup": "^1.0",
849 | "sebastian/environment": "^1.3.2 || ^2.0",
850 | "sebastian/version": "^1.0 || ^2.0"
851 | },
852 | "require-dev": {
853 | "ext-xdebug": "^2.1.4",
854 | "phpunit/phpunit": "^5.7"
855 | },
856 | "suggest": {
857 | "ext-xdebug": "^2.5.1"
858 | },
859 | "type": "library",
860 | "extra": {
861 | "branch-alias": {
862 | "dev-master": "4.0.x-dev"
863 | }
864 | },
865 | "autoload": {
866 | "classmap": [
867 | "src/"
868 | ]
869 | },
870 | "notification-url": "https://packagist.org/downloads/",
871 | "license": [
872 | "BSD-3-Clause"
873 | ],
874 | "authors": [
875 | {
876 | "name": "Sebastian Bergmann",
877 | "email": "sb@sebastian-bergmann.de",
878 | "role": "lead"
879 | }
880 | ],
881 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
882 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
883 | "keywords": [
884 | "coverage",
885 | "testing",
886 | "xunit"
887 | ],
888 | "time": "2017-04-02 07:44:40"
889 | },
890 | {
891 | "name": "phpunit/php-file-iterator",
892 | "version": "1.4.2",
893 | "source": {
894 | "type": "git",
895 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
896 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
897 | },
898 | "dist": {
899 | "type": "zip",
900 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
901 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
902 | "shasum": ""
903 | },
904 | "require": {
905 | "php": ">=5.3.3"
906 | },
907 | "type": "library",
908 | "extra": {
909 | "branch-alias": {
910 | "dev-master": "1.4.x-dev"
911 | }
912 | },
913 | "autoload": {
914 | "classmap": [
915 | "src/"
916 | ]
917 | },
918 | "notification-url": "https://packagist.org/downloads/",
919 | "license": [
920 | "BSD-3-Clause"
921 | ],
922 | "authors": [
923 | {
924 | "name": "Sebastian Bergmann",
925 | "email": "sb@sebastian-bergmann.de",
926 | "role": "lead"
927 | }
928 | ],
929 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
930 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
931 | "keywords": [
932 | "filesystem",
933 | "iterator"
934 | ],
935 | "time": "2016-10-03 07:40:28"
936 | },
937 | {
938 | "name": "phpunit/php-text-template",
939 | "version": "1.2.1",
940 | "source": {
941 | "type": "git",
942 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
943 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
944 | },
945 | "dist": {
946 | "type": "zip",
947 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
948 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
949 | "shasum": ""
950 | },
951 | "require": {
952 | "php": ">=5.3.3"
953 | },
954 | "type": "library",
955 | "autoload": {
956 | "classmap": [
957 | "src/"
958 | ]
959 | },
960 | "notification-url": "https://packagist.org/downloads/",
961 | "license": [
962 | "BSD-3-Clause"
963 | ],
964 | "authors": [
965 | {
966 | "name": "Sebastian Bergmann",
967 | "email": "sebastian@phpunit.de",
968 | "role": "lead"
969 | }
970 | ],
971 | "description": "Simple template engine.",
972 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
973 | "keywords": [
974 | "template"
975 | ],
976 | "time": "2015-06-21 13:50:34"
977 | },
978 | {
979 | "name": "phpunit/php-timer",
980 | "version": "1.0.9",
981 | "source": {
982 | "type": "git",
983 | "url": "https://github.com/sebastianbergmann/php-timer.git",
984 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
985 | },
986 | "dist": {
987 | "type": "zip",
988 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
989 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
990 | "shasum": ""
991 | },
992 | "require": {
993 | "php": "^5.3.3 || ^7.0"
994 | },
995 | "require-dev": {
996 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
997 | },
998 | "type": "library",
999 | "extra": {
1000 | "branch-alias": {
1001 | "dev-master": "1.0-dev"
1002 | }
1003 | },
1004 | "autoload": {
1005 | "classmap": [
1006 | "src/"
1007 | ]
1008 | },
1009 | "notification-url": "https://packagist.org/downloads/",
1010 | "license": [
1011 | "BSD-3-Clause"
1012 | ],
1013 | "authors": [
1014 | {
1015 | "name": "Sebastian Bergmann",
1016 | "email": "sb@sebastian-bergmann.de",
1017 | "role": "lead"
1018 | }
1019 | ],
1020 | "description": "Utility class for timing",
1021 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
1022 | "keywords": [
1023 | "timer"
1024 | ],
1025 | "time": "2017-02-26 11:10:40"
1026 | },
1027 | {
1028 | "name": "phpunit/php-token-stream",
1029 | "version": "1.4.11",
1030 | "source": {
1031 | "type": "git",
1032 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
1033 | "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
1034 | },
1035 | "dist": {
1036 | "type": "zip",
1037 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
1038 | "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
1039 | "shasum": ""
1040 | },
1041 | "require": {
1042 | "ext-tokenizer": "*",
1043 | "php": ">=5.3.3"
1044 | },
1045 | "require-dev": {
1046 | "phpunit/phpunit": "~4.2"
1047 | },
1048 | "type": "library",
1049 | "extra": {
1050 | "branch-alias": {
1051 | "dev-master": "1.4-dev"
1052 | }
1053 | },
1054 | "autoload": {
1055 | "classmap": [
1056 | "src/"
1057 | ]
1058 | },
1059 | "notification-url": "https://packagist.org/downloads/",
1060 | "license": [
1061 | "BSD-3-Clause"
1062 | ],
1063 | "authors": [
1064 | {
1065 | "name": "Sebastian Bergmann",
1066 | "email": "sebastian@phpunit.de"
1067 | }
1068 | ],
1069 | "description": "Wrapper around PHP's tokenizer extension.",
1070 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
1071 | "keywords": [
1072 | "tokenizer"
1073 | ],
1074 | "time": "2017-02-27 10:12:30"
1075 | },
1076 | {
1077 | "name": "phpunit/phpunit",
1078 | "version": "5.7.19",
1079 | "source": {
1080 | "type": "git",
1081 | "url": "https://github.com/sebastianbergmann/phpunit.git",
1082 | "reference": "69c4f49ff376af2692bad9cebd883d17ebaa98a1"
1083 | },
1084 | "dist": {
1085 | "type": "zip",
1086 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/69c4f49ff376af2692bad9cebd883d17ebaa98a1",
1087 | "reference": "69c4f49ff376af2692bad9cebd883d17ebaa98a1",
1088 | "shasum": ""
1089 | },
1090 | "require": {
1091 | "ext-dom": "*",
1092 | "ext-json": "*",
1093 | "ext-libxml": "*",
1094 | "ext-mbstring": "*",
1095 | "ext-xml": "*",
1096 | "myclabs/deep-copy": "~1.3",
1097 | "php": "^5.6 || ^7.0",
1098 | "phpspec/prophecy": "^1.6.2",
1099 | "phpunit/php-code-coverage": "^4.0.4",
1100 | "phpunit/php-file-iterator": "~1.4",
1101 | "phpunit/php-text-template": "~1.2",
1102 | "phpunit/php-timer": "^1.0.6",
1103 | "phpunit/phpunit-mock-objects": "^3.2",
1104 | "sebastian/comparator": "^1.2.4",
1105 | "sebastian/diff": "~1.2",
1106 | "sebastian/environment": "^1.3.4 || ^2.0",
1107 | "sebastian/exporter": "~2.0",
1108 | "sebastian/global-state": "^1.1",
1109 | "sebastian/object-enumerator": "~2.0",
1110 | "sebastian/resource-operations": "~1.0",
1111 | "sebastian/version": "~1.0.3|~2.0",
1112 | "symfony/yaml": "~2.1|~3.0"
1113 | },
1114 | "conflict": {
1115 | "phpdocumentor/reflection-docblock": "3.0.2"
1116 | },
1117 | "require-dev": {
1118 | "ext-pdo": "*"
1119 | },
1120 | "suggest": {
1121 | "ext-xdebug": "*",
1122 | "phpunit/php-invoker": "~1.1"
1123 | },
1124 | "bin": [
1125 | "phpunit"
1126 | ],
1127 | "type": "library",
1128 | "extra": {
1129 | "branch-alias": {
1130 | "dev-master": "5.7.x-dev"
1131 | }
1132 | },
1133 | "autoload": {
1134 | "classmap": [
1135 | "src/"
1136 | ]
1137 | },
1138 | "notification-url": "https://packagist.org/downloads/",
1139 | "license": [
1140 | "BSD-3-Clause"
1141 | ],
1142 | "authors": [
1143 | {
1144 | "name": "Sebastian Bergmann",
1145 | "email": "sebastian@phpunit.de",
1146 | "role": "lead"
1147 | }
1148 | ],
1149 | "description": "The PHP Unit Testing framework.",
1150 | "homepage": "https://phpunit.de/",
1151 | "keywords": [
1152 | "phpunit",
1153 | "testing",
1154 | "xunit"
1155 | ],
1156 | "time": "2017-04-03 02:22:27"
1157 | },
1158 | {
1159 | "name": "phpunit/phpunit-mock-objects",
1160 | "version": "3.4.3",
1161 | "source": {
1162 | "type": "git",
1163 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
1164 | "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24"
1165 | },
1166 | "dist": {
1167 | "type": "zip",
1168 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
1169 | "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
1170 | "shasum": ""
1171 | },
1172 | "require": {
1173 | "doctrine/instantiator": "^1.0.2",
1174 | "php": "^5.6 || ^7.0",
1175 | "phpunit/php-text-template": "^1.2",
1176 | "sebastian/exporter": "^1.2 || ^2.0"
1177 | },
1178 | "conflict": {
1179 | "phpunit/phpunit": "<5.4.0"
1180 | },
1181 | "require-dev": {
1182 | "phpunit/phpunit": "^5.4"
1183 | },
1184 | "suggest": {
1185 | "ext-soap": "*"
1186 | },
1187 | "type": "library",
1188 | "extra": {
1189 | "branch-alias": {
1190 | "dev-master": "3.2.x-dev"
1191 | }
1192 | },
1193 | "autoload": {
1194 | "classmap": [
1195 | "src/"
1196 | ]
1197 | },
1198 | "notification-url": "https://packagist.org/downloads/",
1199 | "license": [
1200 | "BSD-3-Clause"
1201 | ],
1202 | "authors": [
1203 | {
1204 | "name": "Sebastian Bergmann",
1205 | "email": "sb@sebastian-bergmann.de",
1206 | "role": "lead"
1207 | }
1208 | ],
1209 | "description": "Mock Object library for PHPUnit",
1210 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
1211 | "keywords": [
1212 | "mock",
1213 | "xunit"
1214 | ],
1215 | "time": "2016-12-08 20:27:08"
1216 | },
1217 | {
1218 | "name": "sebastian/code-unit-reverse-lookup",
1219 | "version": "1.0.1",
1220 | "source": {
1221 | "type": "git",
1222 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
1223 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
1224 | },
1225 | "dist": {
1226 | "type": "zip",
1227 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
1228 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
1229 | "shasum": ""
1230 | },
1231 | "require": {
1232 | "php": "^5.6 || ^7.0"
1233 | },
1234 | "require-dev": {
1235 | "phpunit/phpunit": "^5.7 || ^6.0"
1236 | },
1237 | "type": "library",
1238 | "extra": {
1239 | "branch-alias": {
1240 | "dev-master": "1.0.x-dev"
1241 | }
1242 | },
1243 | "autoload": {
1244 | "classmap": [
1245 | "src/"
1246 | ]
1247 | },
1248 | "notification-url": "https://packagist.org/downloads/",
1249 | "license": [
1250 | "BSD-3-Clause"
1251 | ],
1252 | "authors": [
1253 | {
1254 | "name": "Sebastian Bergmann",
1255 | "email": "sebastian@phpunit.de"
1256 | }
1257 | ],
1258 | "description": "Looks up which function or method a line of code belongs to",
1259 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
1260 | "time": "2017-03-04 06:30:41"
1261 | },
1262 | {
1263 | "name": "sebastian/comparator",
1264 | "version": "1.2.4",
1265 | "source": {
1266 | "type": "git",
1267 | "url": "https://github.com/sebastianbergmann/comparator.git",
1268 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
1269 | },
1270 | "dist": {
1271 | "type": "zip",
1272 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
1273 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
1274 | "shasum": ""
1275 | },
1276 | "require": {
1277 | "php": ">=5.3.3",
1278 | "sebastian/diff": "~1.2",
1279 | "sebastian/exporter": "~1.2 || ~2.0"
1280 | },
1281 | "require-dev": {
1282 | "phpunit/phpunit": "~4.4"
1283 | },
1284 | "type": "library",
1285 | "extra": {
1286 | "branch-alias": {
1287 | "dev-master": "1.2.x-dev"
1288 | }
1289 | },
1290 | "autoload": {
1291 | "classmap": [
1292 | "src/"
1293 | ]
1294 | },
1295 | "notification-url": "https://packagist.org/downloads/",
1296 | "license": [
1297 | "BSD-3-Clause"
1298 | ],
1299 | "authors": [
1300 | {
1301 | "name": "Jeff Welch",
1302 | "email": "whatthejeff@gmail.com"
1303 | },
1304 | {
1305 | "name": "Volker Dusch",
1306 | "email": "github@wallbash.com"
1307 | },
1308 | {
1309 | "name": "Bernhard Schussek",
1310 | "email": "bschussek@2bepublished.at"
1311 | },
1312 | {
1313 | "name": "Sebastian Bergmann",
1314 | "email": "sebastian@phpunit.de"
1315 | }
1316 | ],
1317 | "description": "Provides the functionality to compare PHP values for equality",
1318 | "homepage": "http://www.github.com/sebastianbergmann/comparator",
1319 | "keywords": [
1320 | "comparator",
1321 | "compare",
1322 | "equality"
1323 | ],
1324 | "time": "2017-01-29 09:50:25"
1325 | },
1326 | {
1327 | "name": "sebastian/diff",
1328 | "version": "1.4.1",
1329 | "source": {
1330 | "type": "git",
1331 | "url": "https://github.com/sebastianbergmann/diff.git",
1332 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
1333 | },
1334 | "dist": {
1335 | "type": "zip",
1336 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
1337 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
1338 | "shasum": ""
1339 | },
1340 | "require": {
1341 | "php": ">=5.3.3"
1342 | },
1343 | "require-dev": {
1344 | "phpunit/phpunit": "~4.8"
1345 | },
1346 | "type": "library",
1347 | "extra": {
1348 | "branch-alias": {
1349 | "dev-master": "1.4-dev"
1350 | }
1351 | },
1352 | "autoload": {
1353 | "classmap": [
1354 | "src/"
1355 | ]
1356 | },
1357 | "notification-url": "https://packagist.org/downloads/",
1358 | "license": [
1359 | "BSD-3-Clause"
1360 | ],
1361 | "authors": [
1362 | {
1363 | "name": "Kore Nordmann",
1364 | "email": "mail@kore-nordmann.de"
1365 | },
1366 | {
1367 | "name": "Sebastian Bergmann",
1368 | "email": "sebastian@phpunit.de"
1369 | }
1370 | ],
1371 | "description": "Diff implementation",
1372 | "homepage": "https://github.com/sebastianbergmann/diff",
1373 | "keywords": [
1374 | "diff"
1375 | ],
1376 | "time": "2015-12-08 07:14:41"
1377 | },
1378 | {
1379 | "name": "sebastian/environment",
1380 | "version": "2.0.0",
1381 | "source": {
1382 | "type": "git",
1383 | "url": "https://github.com/sebastianbergmann/environment.git",
1384 | "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
1385 | },
1386 | "dist": {
1387 | "type": "zip",
1388 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
1389 | "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
1390 | "shasum": ""
1391 | },
1392 | "require": {
1393 | "php": "^5.6 || ^7.0"
1394 | },
1395 | "require-dev": {
1396 | "phpunit/phpunit": "^5.0"
1397 | },
1398 | "type": "library",
1399 | "extra": {
1400 | "branch-alias": {
1401 | "dev-master": "2.0.x-dev"
1402 | }
1403 | },
1404 | "autoload": {
1405 | "classmap": [
1406 | "src/"
1407 | ]
1408 | },
1409 | "notification-url": "https://packagist.org/downloads/",
1410 | "license": [
1411 | "BSD-3-Clause"
1412 | ],
1413 | "authors": [
1414 | {
1415 | "name": "Sebastian Bergmann",
1416 | "email": "sebastian@phpunit.de"
1417 | }
1418 | ],
1419 | "description": "Provides functionality to handle HHVM/PHP environments",
1420 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1421 | "keywords": [
1422 | "Xdebug",
1423 | "environment",
1424 | "hhvm"
1425 | ],
1426 | "time": "2016-11-26 07:53:53"
1427 | },
1428 | {
1429 | "name": "sebastian/exporter",
1430 | "version": "2.0.0",
1431 | "source": {
1432 | "type": "git",
1433 | "url": "https://github.com/sebastianbergmann/exporter.git",
1434 | "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4"
1435 | },
1436 | "dist": {
1437 | "type": "zip",
1438 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
1439 | "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
1440 | "shasum": ""
1441 | },
1442 | "require": {
1443 | "php": ">=5.3.3",
1444 | "sebastian/recursion-context": "~2.0"
1445 | },
1446 | "require-dev": {
1447 | "ext-mbstring": "*",
1448 | "phpunit/phpunit": "~4.4"
1449 | },
1450 | "type": "library",
1451 | "extra": {
1452 | "branch-alias": {
1453 | "dev-master": "2.0.x-dev"
1454 | }
1455 | },
1456 | "autoload": {
1457 | "classmap": [
1458 | "src/"
1459 | ]
1460 | },
1461 | "notification-url": "https://packagist.org/downloads/",
1462 | "license": [
1463 | "BSD-3-Clause"
1464 | ],
1465 | "authors": [
1466 | {
1467 | "name": "Jeff Welch",
1468 | "email": "whatthejeff@gmail.com"
1469 | },
1470 | {
1471 | "name": "Volker Dusch",
1472 | "email": "github@wallbash.com"
1473 | },
1474 | {
1475 | "name": "Bernhard Schussek",
1476 | "email": "bschussek@2bepublished.at"
1477 | },
1478 | {
1479 | "name": "Sebastian Bergmann",
1480 | "email": "sebastian@phpunit.de"
1481 | },
1482 | {
1483 | "name": "Adam Harvey",
1484 | "email": "aharvey@php.net"
1485 | }
1486 | ],
1487 | "description": "Provides the functionality to export PHP variables for visualization",
1488 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1489 | "keywords": [
1490 | "export",
1491 | "exporter"
1492 | ],
1493 | "time": "2016-11-19 08:54:04"
1494 | },
1495 | {
1496 | "name": "sebastian/global-state",
1497 | "version": "1.1.1",
1498 | "source": {
1499 | "type": "git",
1500 | "url": "https://github.com/sebastianbergmann/global-state.git",
1501 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1502 | },
1503 | "dist": {
1504 | "type": "zip",
1505 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1506 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1507 | "shasum": ""
1508 | },
1509 | "require": {
1510 | "php": ">=5.3.3"
1511 | },
1512 | "require-dev": {
1513 | "phpunit/phpunit": "~4.2"
1514 | },
1515 | "suggest": {
1516 | "ext-uopz": "*"
1517 | },
1518 | "type": "library",
1519 | "extra": {
1520 | "branch-alias": {
1521 | "dev-master": "1.0-dev"
1522 | }
1523 | },
1524 | "autoload": {
1525 | "classmap": [
1526 | "src/"
1527 | ]
1528 | },
1529 | "notification-url": "https://packagist.org/downloads/",
1530 | "license": [
1531 | "BSD-3-Clause"
1532 | ],
1533 | "authors": [
1534 | {
1535 | "name": "Sebastian Bergmann",
1536 | "email": "sebastian@phpunit.de"
1537 | }
1538 | ],
1539 | "description": "Snapshotting of global state",
1540 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1541 | "keywords": [
1542 | "global state"
1543 | ],
1544 | "time": "2015-10-12 03:26:01"
1545 | },
1546 | {
1547 | "name": "sebastian/object-enumerator",
1548 | "version": "2.0.1",
1549 | "source": {
1550 | "type": "git",
1551 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1552 | "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
1553 | },
1554 | "dist": {
1555 | "type": "zip",
1556 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
1557 | "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
1558 | "shasum": ""
1559 | },
1560 | "require": {
1561 | "php": ">=5.6",
1562 | "sebastian/recursion-context": "~2.0"
1563 | },
1564 | "require-dev": {
1565 | "phpunit/phpunit": "~5"
1566 | },
1567 | "type": "library",
1568 | "extra": {
1569 | "branch-alias": {
1570 | "dev-master": "2.0.x-dev"
1571 | }
1572 | },
1573 | "autoload": {
1574 | "classmap": [
1575 | "src/"
1576 | ]
1577 | },
1578 | "notification-url": "https://packagist.org/downloads/",
1579 | "license": [
1580 | "BSD-3-Clause"
1581 | ],
1582 | "authors": [
1583 | {
1584 | "name": "Sebastian Bergmann",
1585 | "email": "sebastian@phpunit.de"
1586 | }
1587 | ],
1588 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1589 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1590 | "time": "2017-02-18 15:18:39"
1591 | },
1592 | {
1593 | "name": "sebastian/recursion-context",
1594 | "version": "2.0.0",
1595 | "source": {
1596 | "type": "git",
1597 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1598 | "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a"
1599 | },
1600 | "dist": {
1601 | "type": "zip",
1602 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a",
1603 | "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a",
1604 | "shasum": ""
1605 | },
1606 | "require": {
1607 | "php": ">=5.3.3"
1608 | },
1609 | "require-dev": {
1610 | "phpunit/phpunit": "~4.4"
1611 | },
1612 | "type": "library",
1613 | "extra": {
1614 | "branch-alias": {
1615 | "dev-master": "2.0.x-dev"
1616 | }
1617 | },
1618 | "autoload": {
1619 | "classmap": [
1620 | "src/"
1621 | ]
1622 | },
1623 | "notification-url": "https://packagist.org/downloads/",
1624 | "license": [
1625 | "BSD-3-Clause"
1626 | ],
1627 | "authors": [
1628 | {
1629 | "name": "Jeff Welch",
1630 | "email": "whatthejeff@gmail.com"
1631 | },
1632 | {
1633 | "name": "Sebastian Bergmann",
1634 | "email": "sebastian@phpunit.de"
1635 | },
1636 | {
1637 | "name": "Adam Harvey",
1638 | "email": "aharvey@php.net"
1639 | }
1640 | ],
1641 | "description": "Provides functionality to recursively process PHP variables",
1642 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1643 | "time": "2016-11-19 07:33:16"
1644 | },
1645 | {
1646 | "name": "sebastian/resource-operations",
1647 | "version": "1.0.0",
1648 | "source": {
1649 | "type": "git",
1650 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
1651 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
1652 | },
1653 | "dist": {
1654 | "type": "zip",
1655 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
1656 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
1657 | "shasum": ""
1658 | },
1659 | "require": {
1660 | "php": ">=5.6.0"
1661 | },
1662 | "type": "library",
1663 | "extra": {
1664 | "branch-alias": {
1665 | "dev-master": "1.0.x-dev"
1666 | }
1667 | },
1668 | "autoload": {
1669 | "classmap": [
1670 | "src/"
1671 | ]
1672 | },
1673 | "notification-url": "https://packagist.org/downloads/",
1674 | "license": [
1675 | "BSD-3-Clause"
1676 | ],
1677 | "authors": [
1678 | {
1679 | "name": "Sebastian Bergmann",
1680 | "email": "sebastian@phpunit.de"
1681 | }
1682 | ],
1683 | "description": "Provides a list of PHP built-in functions that operate on resources",
1684 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
1685 | "time": "2015-07-28 20:34:47"
1686 | },
1687 | {
1688 | "name": "sebastian/version",
1689 | "version": "2.0.1",
1690 | "source": {
1691 | "type": "git",
1692 | "url": "https://github.com/sebastianbergmann/version.git",
1693 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
1694 | },
1695 | "dist": {
1696 | "type": "zip",
1697 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
1698 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
1699 | "shasum": ""
1700 | },
1701 | "require": {
1702 | "php": ">=5.6"
1703 | },
1704 | "type": "library",
1705 | "extra": {
1706 | "branch-alias": {
1707 | "dev-master": "2.0.x-dev"
1708 | }
1709 | },
1710 | "autoload": {
1711 | "classmap": [
1712 | "src/"
1713 | ]
1714 | },
1715 | "notification-url": "https://packagist.org/downloads/",
1716 | "license": [
1717 | "BSD-3-Clause"
1718 | ],
1719 | "authors": [
1720 | {
1721 | "name": "Sebastian Bergmann",
1722 | "email": "sebastian@phpunit.de",
1723 | "role": "lead"
1724 | }
1725 | ],
1726 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1727 | "homepage": "https://github.com/sebastianbergmann/version",
1728 | "time": "2016-10-03 07:35:21"
1729 | },
1730 | {
1731 | "name": "symfony/polyfill-mbstring",
1732 | "version": "v1.3.0",
1733 | "source": {
1734 | "type": "git",
1735 | "url": "https://github.com/symfony/polyfill-mbstring.git",
1736 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
1737 | },
1738 | "dist": {
1739 | "type": "zip",
1740 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
1741 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
1742 | "shasum": ""
1743 | },
1744 | "require": {
1745 | "php": ">=5.3.3"
1746 | },
1747 | "suggest": {
1748 | "ext-mbstring": "For best performance"
1749 | },
1750 | "type": "library",
1751 | "extra": {
1752 | "branch-alias": {
1753 | "dev-master": "1.3-dev"
1754 | }
1755 | },
1756 | "autoload": {
1757 | "psr-4": {
1758 | "Symfony\\Polyfill\\Mbstring\\": ""
1759 | },
1760 | "files": [
1761 | "bootstrap.php"
1762 | ]
1763 | },
1764 | "notification-url": "https://packagist.org/downloads/",
1765 | "license": [
1766 | "MIT"
1767 | ],
1768 | "authors": [
1769 | {
1770 | "name": "Nicolas Grekas",
1771 | "email": "p@tchwork.com"
1772 | },
1773 | {
1774 | "name": "Symfony Community",
1775 | "homepage": "https://symfony.com/contributors"
1776 | }
1777 | ],
1778 | "description": "Symfony polyfill for the Mbstring extension",
1779 | "homepage": "https://symfony.com",
1780 | "keywords": [
1781 | "compatibility",
1782 | "mbstring",
1783 | "polyfill",
1784 | "portable",
1785 | "shim"
1786 | ],
1787 | "time": "2016-11-14 01:06:16"
1788 | },
1789 | {
1790 | "name": "symfony/var-dumper",
1791 | "version": "v3.2.7",
1792 | "source": {
1793 | "type": "git",
1794 | "url": "https://github.com/symfony/var-dumper.git",
1795 | "reference": "81dce20f69a8b40427e1f4e6462178df87cafc03"
1796 | },
1797 | "dist": {
1798 | "type": "zip",
1799 | "url": "https://api.github.com/repos/symfony/var-dumper/zipball/81dce20f69a8b40427e1f4e6462178df87cafc03",
1800 | "reference": "81dce20f69a8b40427e1f4e6462178df87cafc03",
1801 | "shasum": ""
1802 | },
1803 | "require": {
1804 | "php": ">=5.5.9",
1805 | "symfony/polyfill-mbstring": "~1.0"
1806 | },
1807 | "conflict": {
1808 | "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
1809 | },
1810 | "require-dev": {
1811 | "twig/twig": "~1.20|~2.0"
1812 | },
1813 | "suggest": {
1814 | "ext-symfony_debug": ""
1815 | },
1816 | "type": "library",
1817 | "extra": {
1818 | "branch-alias": {
1819 | "dev-master": "3.2-dev"
1820 | }
1821 | },
1822 | "autoload": {
1823 | "files": [
1824 | "Resources/functions/dump.php"
1825 | ],
1826 | "psr-4": {
1827 | "Symfony\\Component\\VarDumper\\": ""
1828 | },
1829 | "exclude-from-classmap": [
1830 | "/Tests/"
1831 | ]
1832 | },
1833 | "notification-url": "https://packagist.org/downloads/",
1834 | "license": [
1835 | "MIT"
1836 | ],
1837 | "authors": [
1838 | {
1839 | "name": "Nicolas Grekas",
1840 | "email": "p@tchwork.com"
1841 | },
1842 | {
1843 | "name": "Symfony Community",
1844 | "homepage": "https://symfony.com/contributors"
1845 | }
1846 | ],
1847 | "description": "Symfony mechanism for exploring and dumping PHP variables",
1848 | "homepage": "https://symfony.com",
1849 | "keywords": [
1850 | "debug",
1851 | "dump"
1852 | ],
1853 | "time": "2017-03-12 16:07:05"
1854 | },
1855 | {
1856 | "name": "symfony/yaml",
1857 | "version": "v3.2.7",
1858 | "source": {
1859 | "type": "git",
1860 | "url": "https://github.com/symfony/yaml.git",
1861 | "reference": "62b4cdb99d52cb1ff253c465eb1532a80cebb621"
1862 | },
1863 | "dist": {
1864 | "type": "zip",
1865 | "url": "https://api.github.com/repos/symfony/yaml/zipball/62b4cdb99d52cb1ff253c465eb1532a80cebb621",
1866 | "reference": "62b4cdb99d52cb1ff253c465eb1532a80cebb621",
1867 | "shasum": ""
1868 | },
1869 | "require": {
1870 | "php": ">=5.5.9"
1871 | },
1872 | "require-dev": {
1873 | "symfony/console": "~2.8|~3.0"
1874 | },
1875 | "suggest": {
1876 | "symfony/console": "For validating YAML files using the lint command"
1877 | },
1878 | "type": "library",
1879 | "extra": {
1880 | "branch-alias": {
1881 | "dev-master": "3.2-dev"
1882 | }
1883 | },
1884 | "autoload": {
1885 | "psr-4": {
1886 | "Symfony\\Component\\Yaml\\": ""
1887 | },
1888 | "exclude-from-classmap": [
1889 | "/Tests/"
1890 | ]
1891 | },
1892 | "notification-url": "https://packagist.org/downloads/",
1893 | "license": [
1894 | "MIT"
1895 | ],
1896 | "authors": [
1897 | {
1898 | "name": "Fabien Potencier",
1899 | "email": "fabien@symfony.com"
1900 | },
1901 | {
1902 | "name": "Symfony Community",
1903 | "homepage": "https://symfony.com/contributors"
1904 | }
1905 | ],
1906 | "description": "Symfony Yaml Component",
1907 | "homepage": "https://symfony.com",
1908 | "time": "2017-03-20 09:45:15"
1909 | },
1910 | {
1911 | "name": "webmozart/assert",
1912 | "version": "1.2.0",
1913 | "source": {
1914 | "type": "git",
1915 | "url": "https://github.com/webmozart/assert.git",
1916 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
1917 | },
1918 | "dist": {
1919 | "type": "zip",
1920 | "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
1921 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
1922 | "shasum": ""
1923 | },
1924 | "require": {
1925 | "php": "^5.3.3 || ^7.0"
1926 | },
1927 | "require-dev": {
1928 | "phpunit/phpunit": "^4.6",
1929 | "sebastian/version": "^1.0.1"
1930 | },
1931 | "type": "library",
1932 | "extra": {
1933 | "branch-alias": {
1934 | "dev-master": "1.3-dev"
1935 | }
1936 | },
1937 | "autoload": {
1938 | "psr-4": {
1939 | "Webmozart\\Assert\\": "src/"
1940 | }
1941 | },
1942 | "notification-url": "https://packagist.org/downloads/",
1943 | "license": [
1944 | "MIT"
1945 | ],
1946 | "authors": [
1947 | {
1948 | "name": "Bernhard Schussek",
1949 | "email": "bschussek@gmail.com"
1950 | }
1951 | ],
1952 | "description": "Assertions to validate method input/output with nice error messages.",
1953 | "keywords": [
1954 | "assert",
1955 | "check",
1956 | "validate"
1957 | ],
1958 | "time": "2016-11-23 20:04:58"
1959 | }
1960 | ],
1961 | "aliases": [],
1962 | "minimum-stability": "stable",
1963 | "stability-flags": [],
1964 | "prefer-stable": true,
1965 | "prefer-lowest": false,
1966 | "platform": {
1967 | "php": ">=7.0"
1968 | },
1969 | "platform-dev": []
1970 | }
1971 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 | tests/Brendt
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/Brendt/Image/Config/DefaultConfigurator.php:
--------------------------------------------------------------------------------
1 | 'gd',
23 | 'publicPath' => './',
24 | 'sourcePath' => './',
25 | 'rebase' => false,
26 | 'enableCache' => false,
27 | 'optimize' => false,
28 | 'scaler' => 'filesize',
29 | 'stepModifier' => 0.5,
30 | 'minFileSize' => 5000,
31 | 'maxFileSize' => null,
32 | 'minWidth' => 300,
33 | 'maxWidth' => null,
34 | 'sizes' => [],
35 | 'optimizerOptions' => [],
36 | 'includeSource' => true,
37 | ];
38 |
39 | /**
40 | * ResponsiveFactoryConfigurator constructor.
41 | *
42 | * @param array $config
43 | *
44 | * @throws InvalidConfigurationException
45 | */
46 | public function __construct(array $config = []) {
47 | if (isset($config['driver']) && !in_array($config['driver'], ['gd', 'imagick'])) {
48 | throw new InvalidConfigurationException('Invalid driver. Possible drivers are `gd` and `imagick`');
49 | }
50 |
51 | $this->config = array_merge($this->config, $config);
52 | }
53 |
54 | /**
55 | * @param ResponsiveFactory $factory
56 | *
57 | * @return void
58 | */
59 | public function configure(ResponsiveFactory $factory) {
60 | /** @var AbstractScaler $scaler */
61 | switch ($this->config['scaler']) {
62 | case 'filesize':
63 | $scaler = new FileSizeScaler($this);
64 | break;
65 | case 'width':
66 | $scaler = new WidthScaler($this);
67 | break;
68 | case 'sizes':
69 | default:
70 | $scaler = new SizesScaler($this);
71 | $scaler->setSizes($this->config['sizes']);
72 | break;
73 | }
74 |
75 | $factory
76 | ->setDriver($this->config['driver'])
77 | ->setPublicPath($this->config['publicPath'])
78 | ->setSourcePath($this->config['sourcePath'])
79 | ->setRebase($this->config['rebase'])
80 | ->setEnableCache($this->config['enableCache'])
81 | ->setOptimize($this->config['optimize'])
82 | ->setOptimizerOptions($this->config['optimizerOptions'])
83 | ->setScaler($scaler);
84 | }
85 |
86 | /**
87 | * @param Scaler $scaler
88 | *
89 | * @return Scaler
90 | */
91 | public function configureScaler(Scaler $scaler) {
92 | $scaler
93 | ->setIncludeSource($this->config['includeSource'])
94 | ->setMinFileSize($this->config['minFileSize'])
95 | ->setMinWidth($this->config['minWidth'])
96 | ->setMaxFileSize($this->config['maxFileSize'])
97 | ->setMaxWidth($this->config['maxWidth'])
98 | ->setStepModifier($this->config['stepModifier']);
99 |
100 | return $scaler;
101 | }
102 |
103 | /**
104 | * @return array
105 | */
106 | public function getConfig() {
107 | return $this->config;
108 | }
109 |
110 | /**
111 | * @param $key
112 | *
113 | * @return mixed|null
114 | */
115 | public function get($key) {
116 | return isset($this->config[$key]) ? $this->config[$key] : null;
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/Brendt/Image/Config/ResponsiveFactoryConfigurator.php:
--------------------------------------------------------------------------------
1 | configure($this);
95 |
96 | $this->sourcePath = rtrim($this->sourcePath, '/');
97 | $this->publicPath = rtrim($this->publicPath, '/');
98 |
99 | $this->engine = new ImageManager([
100 | 'driver' => $this->driver,
101 | ]);
102 |
103 | $this->optimizer = (new OptimizerFactory($this->optimizerOptions))->get();
104 | $this->fs = new Filesystem();
105 |
106 | if (!$this->fs->exists($this->publicPath)) {
107 | $this->fs->mkdir($this->publicPath);
108 | }
109 | }
110 |
111 | /**
112 | * @param string $src
113 | *
114 | * @return ResponsiveImage
115 | * @throws FileNotFoundException
116 | */
117 | public function create($src) {
118 | $responsiveImage = new ResponsiveImage($src);
119 | $src = $responsiveImage->src();
120 | $sourceFilename = $this->rebase ? pathinfo($src, PATHINFO_BASENAME) : $src;
121 | $sourceFile = $this->getImageFile($this->sourcePath, $sourceFilename);
122 |
123 | $filename = pathinfo($sourceFile->getFilename(), PATHINFO_FILENAME);
124 | $urlPath = '/' . trim(pathinfo($src, PATHINFO_DIRNAME), '/');
125 |
126 | $responsiveImage->setExtension($sourceFile->getExtension());
127 | $responsiveImage->setFileName($filename);
128 | $responsiveImage->setUrlPath($urlPath);
129 |
130 | if ($cachedResponsiveImage = $this->getCachedResponsiveImage($responsiveImage, $sourceFile)) {
131 | return $cachedResponsiveImage;
132 | }
133 |
134 | $this->fs->dumpFile("{$this->publicPath}{$src}", $sourceFile->getContents());
135 | $this->createScaledImages($sourceFile, $responsiveImage);
136 |
137 | return $responsiveImage;
138 | }
139 |
140 | /**
141 | * @param ResponsiveImage $responsiveImage
142 | * @param SplFileInfo $imageFile
143 | *
144 | * @return ResponsiveImage|null
145 | */
146 | public function getCachedResponsiveImage(ResponsiveImage $responsiveImage, SplFileInfo $imageFile) {
147 | $src = $responsiveImage->src();
148 | $publicImagePath = "{$this->publicPath}{$src}";
149 |
150 | if ($this->enableCache && $this->fs->exists($publicImagePath)) {
151 | $extension = $imageFile->getExtension();
152 | $publicDirectory = $this->rebase ? trim(pathinfo($src, PATHINFO_DIRNAME), '/') : $imageFile->getRelativePath();
153 | $imageFilename = pathinfo($imageFile->getFilename(), PATHINFO_FILENAME);
154 |
155 | /** @var SplFileInfo[] $cachedFiles */
156 | $cachedFiles = Finder::create()->files()->in("{$this->publicPath}/{$publicDirectory}")->name("{$imageFilename}-*.{$extension}");
157 |
158 | foreach ($cachedFiles as $cachedFile) {
159 | $cachedFilename = $cachedFile->getFilename();
160 | $size = (int) str_replace(".{$extension}", '', str_replace("{$imageFilename}-", '', $cachedFilename));
161 |
162 | $responsiveImage->addSource("{$responsiveImage->getUrlPath()}/{$cachedFilename}", $size);
163 | }
164 |
165 | return $responsiveImage;
166 | }
167 |
168 | return null;
169 | }
170 |
171 | /**
172 | * Create scaled image files and add them as sources to a Responsive Image, based on an array of file sizes:
173 | * [
174 | * width => height,
175 | * ...
176 | * ]
177 | *
178 | * @param SplFileInfo $sourceImage
179 | * @param ResponsiveImage $responsiveImage
180 | *
181 | * @return ResponsiveImage
182 | */
183 | public function createScaledImages(SplFileInfo $sourceImage, ResponsiveImage $responsiveImage) : ResponsiveImage {
184 | $imageObject = $this->engine->make($sourceImage->getPathname());
185 | $urlPath = $responsiveImage->getUrlPath();
186 | $sizes = $this->scaler->scale($sourceImage, $imageObject);
187 |
188 | foreach ($sizes as $width => $height) {
189 | $scaledFileSrc = trim("{$urlPath}/{$imageObject->filename}-{$width}.{$imageObject->extension}", '/');
190 | $scaledFilePath = "{$this->getPublicPath()}/{$scaledFileSrc}";
191 | $responsiveImage->addSource($scaledFileSrc, $width);
192 |
193 | $scaledImage = $imageObject->resize((int) $width, (int) $height)->encode($imageObject->extension);
194 |
195 | if (!$this->enableCache || !$this->fs->exists($scaledFilePath)) {
196 | $this->fs->dumpFile($scaledFilePath, $scaledImage);
197 | }
198 | }
199 |
200 | $imageObject->destroy();
201 |
202 | if ($this->optimize) {
203 | $this->optimizeResponsiveImage($responsiveImage);
204 | }
205 |
206 | return $responsiveImage;
207 | }
208 |
209 | /**
210 | * Optimize all sources of a Responsive Image
211 | *
212 | * @param ResponsiveImage $responsiveImage
213 | *
214 | * @return ResponsiveImage
215 | */
216 | private function optimizeResponsiveImage(ResponsiveImage $responsiveImage) : ResponsiveImage {
217 | foreach ($responsiveImage->getSrcset() as $imageFile) {
218 | $this->optimizer->optimize("{$this->publicPath}/{$imageFile}");
219 | }
220 |
221 | return $responsiveImage;
222 | }
223 |
224 | /**
225 | * @param string $directory
226 | * @param string $path
227 | *
228 | * @return null|SplFileInfo
229 | * @throws FileNotFoundException
230 | */
231 | private function getImageFile(string $directory, string $path) {
232 | $path = ltrim($path, '/');
233 | $iterator = Finder::create()->files()->in($directory)->path($path)->getIterator();
234 | $iterator->rewind();
235 |
236 | $sourceImage = $iterator->current();
237 |
238 | if (!$sourceImage) {
239 | throw new FileNotFoundException("{$this->sourcePath}/{$path}");
240 | }
241 |
242 | return $sourceImage;
243 | }
244 |
245 | /**
246 | * @param string $driver
247 | *
248 | * @return ResponsiveFactory
249 | */
250 | public function setDriver($driver) : ResponsiveFactory {
251 | $this->driver = $driver;
252 |
253 | return $this;
254 | }
255 |
256 | /**
257 | * @param string $publicPath
258 | *
259 | * @return ResponsiveFactory
260 | */
261 | public function setPublicPath($publicPath) : ResponsiveFactory {
262 | $this->publicPath = $publicPath;
263 |
264 | return $this;
265 | }
266 |
267 | /**
268 | * @param boolean $enableCache
269 | *
270 | * @return ResponsiveFactory
271 | */
272 | public function setEnableCache($enableCache) : ResponsiveFactory {
273 | $this->enableCache = $enableCache;
274 |
275 | return $this;
276 | }
277 |
278 | /**
279 | * @param string $sourcePath
280 | *
281 | * @return ResponsiveFactory
282 | */
283 | public function setSourcePath($sourcePath) : ResponsiveFactory {
284 | $this->sourcePath = $sourcePath;
285 |
286 | return $this;
287 | }
288 |
289 | /**
290 | * @param Scaler $scaler
291 | *
292 | * @return ResponsiveFactory
293 | */
294 | public function setScaler($scaler) : ResponsiveFactory {
295 | $this->scaler = $scaler;
296 |
297 | return $this;
298 | }
299 |
300 | /**
301 | * @param bool $optimize
302 | *
303 | * @return ResponsiveFactory
304 | */
305 | public function setOptimize(bool $optimize) : ResponsiveFactory {
306 | $this->optimize = $optimize;
307 |
308 | return $this;
309 | }
310 |
311 | /**
312 | * @return string
313 | */
314 | public function getPublicPath() : string {
315 | return $this->publicPath;
316 | }
317 |
318 | /**
319 | * @param mixed $optimizerOptions
320 | *
321 | * @return ResponsiveFactory
322 | */
323 | public function setOptimizerOptions($optimizerOptions) : ResponsiveFactory {
324 | $this->optimizerOptions = $optimizerOptions;
325 |
326 | return $this;
327 | }
328 |
329 | /**
330 | * @param bool $rebase
331 | *
332 | * @return ResponsiveFactory
333 | */
334 | public function setRebase(bool $rebase) : ResponsiveFactory {
335 | $this->rebase = $rebase;
336 |
337 | return $this;
338 | }
339 |
340 | }
341 |
--------------------------------------------------------------------------------
/src/Brendt/Image/ResponsiveImage.php:
--------------------------------------------------------------------------------
1 | src = "/{$src}";
47 | }
48 |
49 | /**
50 | * @return string
51 | */
52 | public function src() {
53 | return $this->src;
54 | }
55 |
56 | /**
57 | * @param $sources
58 | * @param null $value
59 | *
60 | * @return ResponsiveImage
61 | */
62 | public function addSource($sources, $value = null) {
63 | if (!is_array($sources) && $value) {
64 | $sources = [$sources => $value];
65 | } elseif (!is_array($sources)) {
66 | return $this;
67 | }
68 |
69 | foreach ($sources as $url => $width) {
70 | $url = ltrim($url, '/');
71 | $width = str_replace('px', '', $width);
72 |
73 | $this->srcset[$width] = "/{$url}";
74 | }
75 |
76 | krsort($this->srcset);
77 |
78 | return $this;
79 | }
80 |
81 | /**
82 | * @return string
83 | */
84 | public function srcset() {
85 | $srcset = [];
86 |
87 | foreach ($this->srcset as $w => $url) {
88 | $srcset[] = "{$url} {$w}w";
89 | }
90 |
91 | return implode(',', $srcset);
92 | }
93 |
94 | /**
95 | * @param array|string $sizes
96 | * @param null $value
97 | *
98 | * @return ResponsiveImage
99 | */
100 | public function addSizes($sizes, $value = null) {
101 | if (!is_array($sizes) && $value) {
102 | $sizes = [$sizes => $value];
103 | } elseif (!is_array($sizes)) {
104 | return $this;
105 | }
106 |
107 | foreach ($sizes as $media => $value) {
108 | $this->sizes[$media] = $value;
109 | }
110 |
111 | return $this;
112 | }
113 |
114 | /**
115 | * @return string
116 | */
117 | public function sizes() {
118 | $sizes = [];
119 |
120 | foreach ($this->sizes as $media => $value) {
121 | $media = rtrim(ltrim($media, '('), ')');
122 |
123 | if (is_numeric($media)) {
124 | $sizes[] = "$value";
125 | } else {
126 | $sizes[] = "({$media}) $value";
127 | }
128 | }
129 |
130 | return implode(', ', $sizes);
131 | }
132 |
133 | /**
134 | * @return string
135 | */
136 | public function getFileName() {
137 | return $this->fileName;
138 | }
139 |
140 | /**
141 | * @param string $fileName
142 | */
143 | public function setFileName($fileName) {
144 | $this->fileName = $fileName;
145 | }
146 |
147 | /**
148 | * @return string
149 | */
150 | public function getExtension() {
151 | return $this->extension;
152 | }
153 |
154 | /**
155 | * @param string $extension
156 | */
157 | public function setExtension($extension) {
158 | $this->extension = $extension;
159 | }
160 |
161 | /**
162 | * @return string
163 | */
164 | public function getUrlPath() {
165 | return $this->urlPath;
166 | }
167 |
168 | /**
169 | * @param string $urlPath
170 | */
171 | public function setUrlPath($urlPath) {
172 | $this->urlPath = $urlPath;
173 | }
174 |
175 | /**
176 | * @return \string[]
177 | */
178 | public function getSrcset() {
179 | return $this->srcset;
180 | }
181 |
182 | /**
183 | * @return string
184 | */
185 | public function getSrc() {
186 | return $this->src;
187 | }
188 |
189 | }
190 |
--------------------------------------------------------------------------------
/src/Brendt/Image/Scaler/AbstractScaler.php:
--------------------------------------------------------------------------------
1 | configureScaler($this);
46 | }
47 |
48 | /**
49 | * @param mixed $minFileSize
50 | *
51 | * @return AbstractScaler
52 | */
53 | public function setMinFileSize($minFileSize) {
54 | $this->minFileSize = $minFileSize;
55 |
56 | return $this;
57 | }
58 |
59 | /**
60 | * @param mixed $minWidth
61 | *
62 | * @return AbstractScaler
63 | */
64 | public function setMinWidth($minWidth) {
65 | $this->minWidth = $minWidth;
66 |
67 | return $this;
68 | }
69 |
70 | /**
71 | * @param mixed $maxFileSize
72 | *
73 | * @return AbstractScaler
74 | */
75 | public function setMaxFileSize($maxFileSize) {
76 | $this->maxFileSize = $maxFileSize;
77 |
78 | return $this;
79 | }
80 |
81 | /**
82 | * @param mixed $maxWidth
83 | *
84 | * @return AbstractScaler
85 | */
86 | public function setMaxWidth($maxWidth) {
87 | $this->maxWidth = $maxWidth;
88 |
89 | return $this;
90 | }
91 |
92 | /**
93 | * @param mixed $stepModifier
94 | *
95 | * @return AbstractScaler
96 | */
97 | public function setStepModifier($stepModifier) {
98 | $this->stepModifier = $stepModifier;
99 |
100 | return $this;
101 | }
102 |
103 | /**
104 | * @param bool $includeSource
105 | *
106 | * @return Scaler
107 | */
108 | public function setIncludeSource(bool $includeSource) : Scaler {
109 | $this->includeSource = $includeSource;
110 |
111 | return $this;
112 | }
113 |
114 | }
115 |
--------------------------------------------------------------------------------
/src/Brendt/Image/Scaler/FileSizeScaler.php:
--------------------------------------------------------------------------------
1 | getSize();
19 | $width = $imageObject->getWidth();
20 | $height = $imageObject->getHeight();
21 | $ratio = $height / $width;
22 | $area = $width * $width * $ratio;
23 | $pixelPrice = $fileSize / $area;
24 |
25 | $sizes = [];
26 |
27 | if ($this->includeSource && (!$this->maxWidth || $width <= $this->maxWidth) && (!$this->maxFileSize || $fileSize <= $this->maxFileSize)) {
28 | $sizes[$width] = $height;
29 | }
30 |
31 | do {
32 | $fileSize = $fileSize * $this->stepModifier;
33 | $newWidth = floor(sqrt(($fileSize / $pixelPrice) / $ratio));
34 |
35 | if ((!$this->maxFileSize || $fileSize <= $this->maxFileSize) && (!$this->maxWidth || $newWidth <= $this->maxWidth)) {
36 | $sizes[(int) $newWidth] = (int) $newWidth * $ratio;
37 | }
38 | } while ($fileSize > $this->minFileSize && $newWidth > $this->minWidth);
39 |
40 | return $sizes;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Brendt/Image/Scaler/Scaler.php:
--------------------------------------------------------------------------------
1 | sizes = $sizes;
23 |
24 | return $this;
25 | }
26 |
27 | /**
28 | * @param SplFileInfo $sourceFile
29 | * @param Image $imageObject
30 | *
31 | * @return array
32 | */
33 | public function scale(SplFileInfo $sourceFile, Image $imageObject) : array {
34 | $imageWidth = $imageObject->getWidth();
35 | $imageHeight = $imageObject->getHeight();
36 | $ratio = $imageHeight / $imageWidth;
37 |
38 | $sizes = [];
39 |
40 | if ($this->includeSource) {
41 | $sizes[$imageWidth] = $imageHeight;
42 | }
43 |
44 | foreach ($this->sizes as $width) {
45 | if ($width > $imageWidth) {
46 | continue;
47 | }
48 |
49 | $sizes[$width] = round($width * $ratio);
50 | }
51 |
52 | return $sizes;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Brendt/Image/Scaler/WidthScaler.php:
--------------------------------------------------------------------------------
1 | getWidth();
19 | $height = $imageObject->getHeight();
20 | $sizes = [];
21 |
22 | if ($this->includeSource && (!$this->maxWidth || $width <= $this->maxWidth)) {
23 | $sizes[$width] = $height;
24 | }
25 |
26 | while ($width >= $this->minWidth) {
27 | $width = floor($width * $this->stepModifier);
28 | $height = floor($height * $this->stepModifier);
29 |
30 | if (!$this->maxWidth || $width <= $this->maxWidth) {
31 | $sizes[(int) $width] = $height;
32 | }
33 | }
34 |
35 | return $sizes;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/Brendt/Image/ResponsiveFactoryTest.php:
--------------------------------------------------------------------------------
1 | fs = new Filesystem();
34 | }
35 |
36 | protected function tearDown() {
37 | if ($this->fs->exists($this->publicPath)) {
38 | $this->fs->remove($this->publicPath);
39 | }
40 | }
41 |
42 | public function setUp() {
43 | $this->configurator = new DefaultConfigurator([
44 | 'publicPath' => $this->publicPath,
45 | 'engine' => 'gd',
46 | 'stepModifier' => 0.5,
47 | 'scaler' => 'width',
48 | ]);
49 | }
50 |
51 | public function test_simple_construct() {
52 | new ResponsiveFactory();
53 | }
54 |
55 | public function test_create() {
56 | $factory = new ResponsiveFactory($this->configurator);
57 | $image = $factory->create('img/image.jpeg');
58 |
59 | $this->assertTrue($this->fs->exists("{$this->publicPath}/img/image.jpeg"));
60 |
61 | $this->assertNotEmpty($image->srcset());
62 | }
63 |
64 | public function test_create_sets_correct_src() {
65 | $factory = new ResponsiveFactory($this->configurator);
66 | $url = 'img/image.jpeg';
67 | $image = $factory->create($url);
68 |
69 | $this->assertEquals("/{$url}", $image->src());
70 | }
71 |
72 | public function test_create_doesnt_render_full_width_srcset() {
73 | $factory = new ResponsiveFactory($this->configurator);
74 | $url = 'img/image.jpeg';
75 | $publicPath = $this->configurator->getConfig()['publicPath'];
76 | $factory->create($url);
77 |
78 | $this->assertFalse($this->fs->exists("{$publicPath}/image-1920.jpeg"));
79 | }
80 |
81 | public function test_create_sets_correct_srcset() {
82 | $factory = new ResponsiveFactory($this->configurator);
83 | $url = 'img/image.jpeg';
84 | $image = $factory->create($url);
85 |
86 | $srcset = $image->srcset();
87 |
88 | $this->assertNotEmpty($srcset);
89 | }
90 |
91 | public function test_create_sets_default_srcset() {
92 | $factory = new ResponsiveFactory($this->configurator);
93 | $url = 'img/image.jpeg';
94 | $image = $factory->create($url);
95 |
96 | $srcset = $image->srcset();
97 |
98 | $this->assertContains('/img/image-1920.jpeg 1920w', $srcset);
99 | }
100 |
101 | public function test_optimizer() {
102 | $url = 'img/image.jpeg';
103 |
104 | $normalFactory = new ResponsiveFactory($this->configurator);
105 | $optimizedFactory = new ResponsiveFactory(new DefaultConfigurator([
106 | 'publicPath' => $this->publicPath,
107 | 'engine' => 'gd',
108 | 'stepModifier' => 0.5,
109 | 'scaler' => 'width',
110 | 'optimize' => true,
111 | 'enableCache' => false,
112 | ]));
113 |
114 | $normalImage = $normalFactory->create($url);
115 | $normalImageFiles = Finder::create()->files()->in($this->publicPath)->path(trim($normalImage->getSrc(), '/'))->getIterator();
116 | $normalImageFiles->rewind();
117 | /** @var SplFileInfo $normalImageFile */
118 | $normalImageFile = $normalImageFiles->current();
119 | $normalImageFileSize = $normalImageFile->getSize();
120 |
121 | $optimizedImage = $optimizedFactory->create($url);
122 | $optimizedImageFiles = Finder::create()->files()->in($this->publicPath)->path(trim($optimizedImage->getSrc(), '/'))->getIterator();
123 | $optimizedImageFiles->rewind();
124 | /** @var SplFileInfo $optimizedImageFile */
125 | $optimizedImageFile = $optimizedImageFiles->current();
126 | $optimizedImageFileSize = $optimizedImageFile->getSize();
127 |
128 | $this->assertTrue($optimizedImageFileSize <= $normalImageFileSize);
129 | }
130 |
131 | /**
132 | * @test
133 | */
134 | public function test_rebase() {
135 | $configurator = new DefaultConfigurator([
136 | 'publicPath' => './tests/public',
137 | 'sourcePath' => './tests/img',
138 | 'rebase' => true,
139 | 'engine' => 'gd',
140 | 'stepModifier' => 0.5,
141 | 'scaler' => 'width',
142 | ]);
143 |
144 | $responsiveFactory = new ResponsiveFactory($configurator);
145 |
146 | $image = $responsiveFactory->create('/img/responsive/image.jpeg');
147 |
148 | $this->assertTrue($this->fs->exists('./tests/public/img/responsive/image.jpeg'));
149 | $this->assertEquals('/img/responsive/image.jpeg', $image->src());
150 | $this->assertContains('/img/responsive', $image->srcset());
151 | }
152 |
153 | public function test_cached_result() {
154 | $src = file_get_contents('./tests/img/image.jpeg');
155 |
156 | if (!$this->fs->exists('./tests/public/img')) {
157 | $this->fs->mkdir('./tests/public/img');
158 | }
159 |
160 | $this->fs->dumpFile('./tests/public/img/image.jpeg', $src);
161 | $this->fs->dumpFile('./tests/public/img/image-500.jpeg', $src);
162 | $this->fs->dumpFile('./tests/public/img/image-1000.jpeg', $src);
163 |
164 | $factory = new ResponsiveFactory(new DefaultConfigurator([
165 | 'publicPath' => './tests/public',
166 | 'sourcePath' => './tests',
167 | 'enableCache' => true
168 | ]));
169 | $image = $factory->create('/img/image.jpeg');
170 |
171 | $srcset = $image->getSrcset();
172 | $this->assertArrayHasKey(500, $srcset);
173 | $this->assertArrayHasKey(1000, $srcset);
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/tests/Brendt/Image/ResponsiveImageTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('/img/image.jpeg', $image->src());
18 | }
19 |
20 | public function test_src_with_slash() {
21 | $image = new ResponsiveImage('/img/image.jpeg');
22 |
23 | $this->assertEquals('/img/image.jpeg', $image->src());
24 | }
25 |
26 | public function test_srcset_empty_on_construct() {
27 | $image = new ResponsiveImage('img/image.jpeg');
28 |
29 | $this->assertEquals('', $image->srcset());
30 | }
31 |
32 | public function test_srcset_add_single_source() {
33 | $image = new ResponsiveImage('img/image.jpeg');
34 | $image->addSource('img/test-500.jpg', '500px');
35 |
36 | $this->assertEquals('/img/test-500.jpg 500w', $image->srcset());
37 | }
38 |
39 | public function test_srcset_add_multiple_sources() {
40 | $image = new ResponsiveImage('img/image.jpeg');
41 |
42 | $image->addSource([
43 | 'img/test.jpg' => 1920,
44 | 'img/test-300.jpg' => 300,
45 | ]);
46 |
47 | $this->assertEquals('/img/test.jpg 1920w,/img/test-300.jpg 300w', $image->srcset());
48 | }
49 |
50 | public function test_sizes_empty_on_construct() {
51 | $image = new ResponsiveImage('img/image.jpeg');
52 |
53 | $this->assertEquals('', $image->sizes());
54 | }
55 |
56 | public function test_sizes_add_single_size() {
57 | $image = new ResponsiveImage('tests/img/image.jpeg');
58 | $image->addSizes('min-width: 650px', '33vw');
59 |
60 | $this->assertEquals('(min-width: 650px) 33vw', $image->sizes());
61 | }
62 |
63 | public function test_sizes_add_multiple_sizes() {
64 | $image = new ResponsiveImage('tests/img/image.jpeg');
65 |
66 | $image->addSizes([
67 | 'min-width: 1000px' => '50vw',
68 | '100vw',
69 | ]);
70 |
71 | $this->assertEquals('(min-width: 1000px) 50vw, 100vw', $image->sizes());
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/tests/Brendt/Image/Scaler/FileSizeScalerTest.php:
--------------------------------------------------------------------------------
1 | fs = new Filesystem();
39 | $this->engine = new ImageManager([
40 | 'driver' => 'gd',
41 | ]);
42 | }
43 |
44 | public function __destruct() {
45 | if ($this->fs->exists($this->publicPath)) {
46 | $this->fs->remove($this->publicPath);
47 | }
48 | }
49 |
50 | public function setUp() {
51 | $this->scaler = new FileSizeScaler(new DefaultConfigurator([
52 | 'publicPath' => $this->publicPath,
53 | ]));
54 | }
55 |
56 | public function test_scale_down() {
57 | $sourceFile = $this->createSourceFile();
58 | $imageObject = $this->createImageObject();
59 |
60 | $sizes = $this->scaler->scale($sourceFile, $imageObject);
61 |
62 | $this->assertTrue(count($sizes) > 1);
63 | }
64 |
65 | public function test_scale_down_with_max_width() {
66 | $sourceFile = $this->createSourceFile();
67 | $imageObject = $this->createImageObject();
68 |
69 | $this->scaler->setMaxWidth(1000);
70 | $sizes = $this->scaler->scale($sourceFile, $imageObject);
71 |
72 | foreach ($sizes as $width => $height) {
73 | $this->assertTrue($width < 1000);
74 | }
75 | }
76 |
77 | public function test_scale_down_with_max_filesize() {
78 | $sourceFile = $this->createSourceFile();
79 | $imageObject = $this->createImageObject();
80 |
81 | $this->scaler->setMaxFileSize(100000);
82 | $sizes = $this->scaler->scale($sourceFile, $imageObject);
83 |
84 | $this->assertCount(3, $sizes);
85 | }
86 |
87 | public function test_scale_down_with_include_source_disabled() {
88 | $sourceFile = $this->createSourceFile();
89 | $imageObject = $this->createImageObject();
90 |
91 | $this->scaler->setIncludeSource(false);
92 | $sizes = $this->scaler->scale($sourceFile, $imageObject);
93 |
94 | $this->assertFalse(array_key_exists(1920, $sizes));
95 | }
96 |
97 | // TODO: test algorithm
98 |
99 | private function createImageObject() {
100 | $imageObject = $this->engine->make('./tests/img/image.jpeg');
101 |
102 | return $imageObject;
103 | }
104 |
105 | private function createSourceFile() {
106 | $sourceFiles = Finder::create()->files()->in('./tests/img')->name('image.jpeg')->getIterator();
107 | $sourceFiles->rewind();
108 |
109 | return $sourceFiles->current();
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/tests/Brendt/Image/Scaler/SizesScalerTest.php:
--------------------------------------------------------------------------------
1 | fs = new Filesystem();
34 | $this->engine = new ImageManager([
35 | 'driver' => 'gd',
36 | ]);
37 | }
38 |
39 | public function __destruct() {
40 | if ($this->fs->exists($this->publicPath)) {
41 | $this->fs->remove($this->publicPath);
42 | }
43 | }
44 |
45 | public function test_scale_down() {
46 | $scaler = new SizesScaler(new DefaultConfigurator([
47 | 'publicPath' => $this->publicPath,
48 | 'includeSource' => false,
49 | ]));
50 | $scaler->setSizes([500, 10000, 1920]);
51 |
52 | $sourceFile = $this->createSourceFile();
53 | $imageObject = $this->createImageObject();
54 |
55 | $sizes = $scaler->scale($sourceFile, $imageObject);
56 |
57 | $this->assertCount(2, $sizes);
58 | }
59 |
60 | public function test_scale_down_with_include_source() {
61 | $scaler = new SizesScaler(new DefaultConfigurator([
62 | 'publicPath' => $this->publicPath,
63 | 'includeSource' => true,
64 | ]));
65 | $scaler->setSizes([500, 800]);
66 |
67 | $sourceFile = $this->createSourceFile();
68 | $imageObject = $this->createImageObject();
69 |
70 | $sizes = $scaler->scale($sourceFile, $imageObject);
71 |
72 | $this->assertCount(3, $sizes);
73 | }
74 |
75 |
76 | private function createImageObject() {
77 | $imageObject = $this->engine->make('./tests/img/image.jpeg');
78 |
79 | return $imageObject;
80 | }
81 |
82 | private function createSourceFile() {
83 | $sourceFiles = Finder::create()->files()->in('./tests/img')->name('image.jpeg')->getIterator();
84 | $sourceFiles->rewind();
85 |
86 | return $sourceFiles->current();
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/tests/Brendt/Image/Scaler/WidthScalerTest.php:
--------------------------------------------------------------------------------
1 | fs = new Filesystem();
40 | $this->engine = new ImageManager([
41 | 'driver' => 'gd',
42 | ]);
43 | }
44 |
45 | public function __destruct() {
46 | if ($this->fs->exists($this->publicPath)) {
47 | $this->fs->remove($this->publicPath);
48 | }
49 | }
50 |
51 | public function setUp() {
52 | $this->scaler = new WidthScaler(new DefaultConfigurator([
53 | 'scaler' => 'width',
54 | 'stepModifier' => 0.8,
55 | 'publicPath' => $this->publicPath
56 | ]));
57 | }
58 |
59 | public function test_scale_down() {
60 | $sourceFile = $this->createSourceFile();
61 | $imageObject = $this->createImageObject();
62 |
63 | $sizes = $this->scaler->scale($sourceFile, $imageObject);
64 |
65 | $this->assertTrue(count($sizes) > 1);
66 | }
67 |
68 | public function test_scale_down_with_max_width() {
69 | $sourceFile = $this->createSourceFile();
70 | $imageObject = $this->createImageObject();
71 |
72 | $this->scaler->setMaxWidth(1000);
73 | $sizes = $this->scaler->scale($sourceFile, $imageObject);
74 |
75 | foreach ($sizes as $width => $height) {
76 | $this->assertTrue($width < 1000);
77 | }
78 | }
79 |
80 | public function test_scale_down_with_include_source_disabled() {
81 | $sourceFile = $this->createSourceFile();
82 | $imageObject = $this->createImageObject();
83 |
84 | $this->scaler->setIncludeSource(false);
85 | $sizes = $this->scaler->scale($sourceFile, $imageObject);
86 |
87 | $this->assertFalse(array_key_exists(1920, $sizes));
88 | }
89 |
90 | private function createSourceFile() {
91 | $sourceFiles = Finder::create()->files()->in('./tests/img')->name('image.jpeg')->getIterator();
92 | $sourceFiles->rewind();
93 |
94 | return $sourceFiles->current();
95 | }
96 |
97 | private function createImageObject() {
98 | $imageObject = $this->engine->make('./tests/img/image.jpeg');
99 |
100 | return $imageObject;
101 | }
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/tests/Brendt/Image/config/DefaultConfiguratorTest.php:
--------------------------------------------------------------------------------
1 | true,
17 | ]);
18 |
19 | $this->assertTrue($configurator->getConfig()['enableCache']);
20 | $this->assertEquals('gd', $configurator->getConfig()['driver']);
21 | }
22 |
23 | /**
24 | * @expectedException \Brendt\Image\Exception\InvalidConfigurationException
25 | */
26 | public function test_construct_throws_exception_with_unknown_driver() {
27 | new DefaultConfigurator([
28 | 'driver' => 'unknown',
29 | ]);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/tests/img/image.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brendt/responsive-images/c3ba0c66abf404db34a1d683470b58595433471e/tests/img/image.jpeg
--------------------------------------------------------------------------------