├── .gitignore
├── README.md
├── composer.json
├── composer.lock
├── example
└── index.php
├── phpunit.xml
├── src
├── JSignFileService.php
├── JSignPDF.php
└── Sign
│ ├── JSignParam.php
│ └── JSignService.php
├── tests
├── Builder
│ └── JSignParamBuilder.php
├── JSignPDFTest.php
└── resources
│ ├── certificado.pfx
│ ├── pdf-error-test.pdf
│ └── pdf-test.pdf
└── tmp
└── .gitignore
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .phpunit.result.cache
3 | vendor
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jsignpdf-php
2 |
3 | This package is only wrapper of [JSignPdf](http://jsignpdf.sourceforge.net/) to use in PHP
4 |
5 | ## Installation:
6 |
7 | ```bash
8 | $ composer require jeidison/jsignpdf-php
9 | ```
10 |
11 | ## Examples
12 |
13 | ```php
14 | use Jeidison\JSignPDF\JSignPDF;
15 | use Jeidison\JSignPDF\Sign\JSignParam;
16 |
17 | $param = JSignParam::instance();
18 | $param->setCertificate(file_get_contents('/path/to/file/certificate.pfx'));
19 | $param->setPdf(file_get_contents('/path/to/file/pdf_to_sign.pdf'));
20 | $param->setPassword('certificate_password');
21 |
22 | $jSignPdf = new JSignPDF($param);
23 | $fileSigned = $jSignPdf->sign();
24 | file_put_contents('/path/to/file/file_signed.pdf', $fileSigned);
25 | ```
26 |
27 | With Java Installed:
28 | ```php
29 | $param->setIsUseJavaInstalled(true);
30 | ```
31 |
32 | With standalone Java:
33 | ```php
34 | $param->setJavaPath('/path/to/bin/java');
35 | ```
36 |
37 | With JSignPDF bin:
38 | ```php
39 | $param->setjSignPdfJarPath('/path/to/jsignpdf');
40 | ```
41 |
42 | Without JSignPDF bin:
43 | ```bash
44 | composer require jsignpdf/jsignpdf-bin
45 | ```
46 |
47 | File signed as base64:
48 | ```php
49 | $param->setIsOutputTypeBase64(true);
50 | ```
51 |
52 | Change temp directory:
53 | ```php
54 | $param->setTempPath('/path/temp/to/sign/files/');
55 | ```
56 |
57 | Change parameters of JSignPDF:
58 | ```php
59 | $param->setJSignParameters("-a -kst PKCS12 -ts https://freetsa.org/tsr");
60 | ```
61 |
62 | ## Credits
63 | - [Jeidison Farias](https://github.com/jeidison)
64 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jsignpdf/jsignpdf-php",
3 | "description": "jsignpdf-php",
4 | "keywords": [
5 | "JSignPdf",
6 | "PHP",
7 | "Signature",
8 | "PHP Signature",
9 | "PDF",
10 | "PDF Sign PHP"
11 | ],
12 | "type": "library",
13 | "license": "MIT",
14 | "authors": [
15 | {
16 | "name": "Jeidison Farias",
17 | "email": "jeidison.farias@gmail.com"
18 | }
19 | ],
20 | "minimum-stability": "stable",
21 | "require": {
22 | "php": "^7.4|^8.0",
23 | "ext-openssl": "*",
24 | "ext-json": "*"
25 | },
26 | "require-dev": {
27 | "phpunit/phpunit": "^9.5"
28 | },
29 | "autoload": {
30 | "psr-4": {
31 | "Jeidison\\JSignPDF\\": "src/"
32 | }
33 | },
34 | "autoload-dev": {
35 | "psr-4": {
36 | "Jeidison\\JSignPDF\\Tests\\": "tests/"
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/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#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "3d432d4d8bd7bd8d2abb8152b506de44",
8 | "packages": [],
9 | "packages-dev": [
10 | {
11 | "name": "doctrine/instantiator",
12 | "version": "1.4.0",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/doctrine/instantiator.git",
16 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
21 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "php": "^7.1 || ^8.0"
26 | },
27 | "require-dev": {
28 | "doctrine/coding-standard": "^8.0",
29 | "ext-pdo": "*",
30 | "ext-phar": "*",
31 | "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
32 | "phpstan/phpstan": "^0.12",
33 | "phpstan/phpstan-phpunit": "^0.12",
34 | "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
35 | },
36 | "type": "library",
37 | "autoload": {
38 | "psr-4": {
39 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
40 | }
41 | },
42 | "notification-url": "https://packagist.org/downloads/",
43 | "license": [
44 | "MIT"
45 | ],
46 | "authors": [
47 | {
48 | "name": "Marco Pivetta",
49 | "email": "ocramius@gmail.com",
50 | "homepage": "https://ocramius.github.io/"
51 | }
52 | ],
53 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
54 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
55 | "keywords": [
56 | "constructor",
57 | "instantiate"
58 | ],
59 | "support": {
60 | "issues": "https://github.com/doctrine/instantiator/issues",
61 | "source": "https://github.com/doctrine/instantiator/tree/1.4.0"
62 | },
63 | "funding": [
64 | {
65 | "url": "https://www.doctrine-project.org/sponsorship.html",
66 | "type": "custom"
67 | },
68 | {
69 | "url": "https://www.patreon.com/phpdoctrine",
70 | "type": "patreon"
71 | },
72 | {
73 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
74 | "type": "tidelift"
75 | }
76 | ],
77 | "time": "2020-11-10T18:47:58+00:00"
78 | },
79 | {
80 | "name": "myclabs/deep-copy",
81 | "version": "1.10.2",
82 | "source": {
83 | "type": "git",
84 | "url": "https://github.com/myclabs/DeepCopy.git",
85 | "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
86 | },
87 | "dist": {
88 | "type": "zip",
89 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
90 | "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
91 | "shasum": ""
92 | },
93 | "require": {
94 | "php": "^7.1 || ^8.0"
95 | },
96 | "replace": {
97 | "myclabs/deep-copy": "self.version"
98 | },
99 | "require-dev": {
100 | "doctrine/collections": "^1.0",
101 | "doctrine/common": "^2.6",
102 | "phpunit/phpunit": "^7.1"
103 | },
104 | "type": "library",
105 | "autoload": {
106 | "psr-4": {
107 | "DeepCopy\\": "src/DeepCopy/"
108 | },
109 | "files": [
110 | "src/DeepCopy/deep_copy.php"
111 | ]
112 | },
113 | "notification-url": "https://packagist.org/downloads/",
114 | "license": [
115 | "MIT"
116 | ],
117 | "description": "Create deep copies (clones) of your objects",
118 | "keywords": [
119 | "clone",
120 | "copy",
121 | "duplicate",
122 | "object",
123 | "object graph"
124 | ],
125 | "support": {
126 | "issues": "https://github.com/myclabs/DeepCopy/issues",
127 | "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
128 | },
129 | "funding": [
130 | {
131 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
132 | "type": "tidelift"
133 | }
134 | ],
135 | "time": "2020-11-13T09:40:50+00:00"
136 | },
137 | {
138 | "name": "nikic/php-parser",
139 | "version": "v4.10.4",
140 | "source": {
141 | "type": "git",
142 | "url": "https://github.com/nikic/PHP-Parser.git",
143 | "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e"
144 | },
145 | "dist": {
146 | "type": "zip",
147 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e",
148 | "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e",
149 | "shasum": ""
150 | },
151 | "require": {
152 | "ext-tokenizer": "*",
153 | "php": ">=7.0"
154 | },
155 | "require-dev": {
156 | "ircmaxell/php-yacc": "^0.0.7",
157 | "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
158 | },
159 | "bin": [
160 | "bin/php-parse"
161 | ],
162 | "type": "library",
163 | "extra": {
164 | "branch-alias": {
165 | "dev-master": "4.9-dev"
166 | }
167 | },
168 | "autoload": {
169 | "psr-4": {
170 | "PhpParser\\": "lib/PhpParser"
171 | }
172 | },
173 | "notification-url": "https://packagist.org/downloads/",
174 | "license": [
175 | "BSD-3-Clause"
176 | ],
177 | "authors": [
178 | {
179 | "name": "Nikita Popov"
180 | }
181 | ],
182 | "description": "A PHP parser written in PHP",
183 | "keywords": [
184 | "parser",
185 | "php"
186 | ],
187 | "support": {
188 | "issues": "https://github.com/nikic/PHP-Parser/issues",
189 | "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4"
190 | },
191 | "time": "2020-12-20T10:01:03+00:00"
192 | },
193 | {
194 | "name": "phar-io/manifest",
195 | "version": "2.0.1",
196 | "source": {
197 | "type": "git",
198 | "url": "https://github.com/phar-io/manifest.git",
199 | "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133"
200 | },
201 | "dist": {
202 | "type": "zip",
203 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
204 | "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
205 | "shasum": ""
206 | },
207 | "require": {
208 | "ext-dom": "*",
209 | "ext-phar": "*",
210 | "ext-xmlwriter": "*",
211 | "phar-io/version": "^3.0.1",
212 | "php": "^7.2 || ^8.0"
213 | },
214 | "type": "library",
215 | "extra": {
216 | "branch-alias": {
217 | "dev-master": "2.0.x-dev"
218 | }
219 | },
220 | "autoload": {
221 | "classmap": [
222 | "src/"
223 | ]
224 | },
225 | "notification-url": "https://packagist.org/downloads/",
226 | "license": [
227 | "BSD-3-Clause"
228 | ],
229 | "authors": [
230 | {
231 | "name": "Arne Blankerts",
232 | "email": "arne@blankerts.de",
233 | "role": "Developer"
234 | },
235 | {
236 | "name": "Sebastian Heuer",
237 | "email": "sebastian@phpeople.de",
238 | "role": "Developer"
239 | },
240 | {
241 | "name": "Sebastian Bergmann",
242 | "email": "sebastian@phpunit.de",
243 | "role": "Developer"
244 | }
245 | ],
246 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
247 | "support": {
248 | "issues": "https://github.com/phar-io/manifest/issues",
249 | "source": "https://github.com/phar-io/manifest/tree/master"
250 | },
251 | "time": "2020-06-27T14:33:11+00:00"
252 | },
253 | {
254 | "name": "phar-io/version",
255 | "version": "3.1.0",
256 | "source": {
257 | "type": "git",
258 | "url": "https://github.com/phar-io/version.git",
259 | "reference": "bae7c545bef187884426f042434e561ab1ddb182"
260 | },
261 | "dist": {
262 | "type": "zip",
263 | "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182",
264 | "reference": "bae7c545bef187884426f042434e561ab1ddb182",
265 | "shasum": ""
266 | },
267 | "require": {
268 | "php": "^7.2 || ^8.0"
269 | },
270 | "type": "library",
271 | "autoload": {
272 | "classmap": [
273 | "src/"
274 | ]
275 | },
276 | "notification-url": "https://packagist.org/downloads/",
277 | "license": [
278 | "BSD-3-Clause"
279 | ],
280 | "authors": [
281 | {
282 | "name": "Arne Blankerts",
283 | "email": "arne@blankerts.de",
284 | "role": "Developer"
285 | },
286 | {
287 | "name": "Sebastian Heuer",
288 | "email": "sebastian@phpeople.de",
289 | "role": "Developer"
290 | },
291 | {
292 | "name": "Sebastian Bergmann",
293 | "email": "sebastian@phpunit.de",
294 | "role": "Developer"
295 | }
296 | ],
297 | "description": "Library for handling version information and constraints",
298 | "support": {
299 | "issues": "https://github.com/phar-io/version/issues",
300 | "source": "https://github.com/phar-io/version/tree/3.1.0"
301 | },
302 | "time": "2021-02-23T14:00:09+00:00"
303 | },
304 | {
305 | "name": "phpdocumentor/reflection-common",
306 | "version": "2.2.0",
307 | "source": {
308 | "type": "git",
309 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
310 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
311 | },
312 | "dist": {
313 | "type": "zip",
314 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
315 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
316 | "shasum": ""
317 | },
318 | "require": {
319 | "php": "^7.2 || ^8.0"
320 | },
321 | "type": "library",
322 | "extra": {
323 | "branch-alias": {
324 | "dev-2.x": "2.x-dev"
325 | }
326 | },
327 | "autoload": {
328 | "psr-4": {
329 | "phpDocumentor\\Reflection\\": "src/"
330 | }
331 | },
332 | "notification-url": "https://packagist.org/downloads/",
333 | "license": [
334 | "MIT"
335 | ],
336 | "authors": [
337 | {
338 | "name": "Jaap van Otterdijk",
339 | "email": "opensource@ijaap.nl"
340 | }
341 | ],
342 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
343 | "homepage": "http://www.phpdoc.org",
344 | "keywords": [
345 | "FQSEN",
346 | "phpDocumentor",
347 | "phpdoc",
348 | "reflection",
349 | "static analysis"
350 | ],
351 | "support": {
352 | "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
353 | "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
354 | },
355 | "time": "2020-06-27T09:03:43+00:00"
356 | },
357 | {
358 | "name": "phpdocumentor/reflection-docblock",
359 | "version": "5.2.2",
360 | "source": {
361 | "type": "git",
362 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
363 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556"
364 | },
365 | "dist": {
366 | "type": "zip",
367 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556",
368 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556",
369 | "shasum": ""
370 | },
371 | "require": {
372 | "ext-filter": "*",
373 | "php": "^7.2 || ^8.0",
374 | "phpdocumentor/reflection-common": "^2.2",
375 | "phpdocumentor/type-resolver": "^1.3",
376 | "webmozart/assert": "^1.9.1"
377 | },
378 | "require-dev": {
379 | "mockery/mockery": "~1.3.2"
380 | },
381 | "type": "library",
382 | "extra": {
383 | "branch-alias": {
384 | "dev-master": "5.x-dev"
385 | }
386 | },
387 | "autoload": {
388 | "psr-4": {
389 | "phpDocumentor\\Reflection\\": "src"
390 | }
391 | },
392 | "notification-url": "https://packagist.org/downloads/",
393 | "license": [
394 | "MIT"
395 | ],
396 | "authors": [
397 | {
398 | "name": "Mike van Riel",
399 | "email": "me@mikevanriel.com"
400 | },
401 | {
402 | "name": "Jaap van Otterdijk",
403 | "email": "account@ijaap.nl"
404 | }
405 | ],
406 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
407 | "support": {
408 | "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
409 | "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master"
410 | },
411 | "time": "2020-09-03T19:13:55+00:00"
412 | },
413 | {
414 | "name": "phpdocumentor/type-resolver",
415 | "version": "1.4.0",
416 | "source": {
417 | "type": "git",
418 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
419 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0"
420 | },
421 | "dist": {
422 | "type": "zip",
423 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
424 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
425 | "shasum": ""
426 | },
427 | "require": {
428 | "php": "^7.2 || ^8.0",
429 | "phpdocumentor/reflection-common": "^2.0"
430 | },
431 | "require-dev": {
432 | "ext-tokenizer": "*"
433 | },
434 | "type": "library",
435 | "extra": {
436 | "branch-alias": {
437 | "dev-1.x": "1.x-dev"
438 | }
439 | },
440 | "autoload": {
441 | "psr-4": {
442 | "phpDocumentor\\Reflection\\": "src"
443 | }
444 | },
445 | "notification-url": "https://packagist.org/downloads/",
446 | "license": [
447 | "MIT"
448 | ],
449 | "authors": [
450 | {
451 | "name": "Mike van Riel",
452 | "email": "me@mikevanriel.com"
453 | }
454 | ],
455 | "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
456 | "support": {
457 | "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
458 | "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0"
459 | },
460 | "time": "2020-09-17T18:55:26+00:00"
461 | },
462 | {
463 | "name": "phpspec/prophecy",
464 | "version": "1.12.2",
465 | "source": {
466 | "type": "git",
467 | "url": "https://github.com/phpspec/prophecy.git",
468 | "reference": "245710e971a030f42e08f4912863805570f23d39"
469 | },
470 | "dist": {
471 | "type": "zip",
472 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39",
473 | "reference": "245710e971a030f42e08f4912863805570f23d39",
474 | "shasum": ""
475 | },
476 | "require": {
477 | "doctrine/instantiator": "^1.2",
478 | "php": "^7.2 || ~8.0, <8.1",
479 | "phpdocumentor/reflection-docblock": "^5.2",
480 | "sebastian/comparator": "^3.0 || ^4.0",
481 | "sebastian/recursion-context": "^3.0 || ^4.0"
482 | },
483 | "require-dev": {
484 | "phpspec/phpspec": "^6.0",
485 | "phpunit/phpunit": "^8.0 || ^9.0"
486 | },
487 | "type": "library",
488 | "extra": {
489 | "branch-alias": {
490 | "dev-master": "1.11.x-dev"
491 | }
492 | },
493 | "autoload": {
494 | "psr-4": {
495 | "Prophecy\\": "src/Prophecy"
496 | }
497 | },
498 | "notification-url": "https://packagist.org/downloads/",
499 | "license": [
500 | "MIT"
501 | ],
502 | "authors": [
503 | {
504 | "name": "Konstantin Kudryashov",
505 | "email": "ever.zet@gmail.com",
506 | "homepage": "http://everzet.com"
507 | },
508 | {
509 | "name": "Marcello Duarte",
510 | "email": "marcello.duarte@gmail.com"
511 | }
512 | ],
513 | "description": "Highly opinionated mocking framework for PHP 5.3+",
514 | "homepage": "https://github.com/phpspec/prophecy",
515 | "keywords": [
516 | "Double",
517 | "Dummy",
518 | "fake",
519 | "mock",
520 | "spy",
521 | "stub"
522 | ],
523 | "support": {
524 | "issues": "https://github.com/phpspec/prophecy/issues",
525 | "source": "https://github.com/phpspec/prophecy/tree/1.12.2"
526 | },
527 | "time": "2020-12-19T10:15:11+00:00"
528 | },
529 | {
530 | "name": "phpunit/php-code-coverage",
531 | "version": "9.2.5",
532 | "source": {
533 | "type": "git",
534 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
535 | "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1"
536 | },
537 | "dist": {
538 | "type": "zip",
539 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1",
540 | "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1",
541 | "shasum": ""
542 | },
543 | "require": {
544 | "ext-dom": "*",
545 | "ext-libxml": "*",
546 | "ext-xmlwriter": "*",
547 | "nikic/php-parser": "^4.10.2",
548 | "php": ">=7.3",
549 | "phpunit/php-file-iterator": "^3.0.3",
550 | "phpunit/php-text-template": "^2.0.2",
551 | "sebastian/code-unit-reverse-lookup": "^2.0.2",
552 | "sebastian/complexity": "^2.0",
553 | "sebastian/environment": "^5.1.2",
554 | "sebastian/lines-of-code": "^1.0.3",
555 | "sebastian/version": "^3.0.1",
556 | "theseer/tokenizer": "^1.2.0"
557 | },
558 | "require-dev": {
559 | "phpunit/phpunit": "^9.3"
560 | },
561 | "suggest": {
562 | "ext-pcov": "*",
563 | "ext-xdebug": "*"
564 | },
565 | "type": "library",
566 | "extra": {
567 | "branch-alias": {
568 | "dev-master": "9.2-dev"
569 | }
570 | },
571 | "autoload": {
572 | "classmap": [
573 | "src/"
574 | ]
575 | },
576 | "notification-url": "https://packagist.org/downloads/",
577 | "license": [
578 | "BSD-3-Clause"
579 | ],
580 | "authors": [
581 | {
582 | "name": "Sebastian Bergmann",
583 | "email": "sebastian@phpunit.de",
584 | "role": "lead"
585 | }
586 | ],
587 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
588 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
589 | "keywords": [
590 | "coverage",
591 | "testing",
592 | "xunit"
593 | ],
594 | "support": {
595 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
596 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5"
597 | },
598 | "funding": [
599 | {
600 | "url": "https://github.com/sebastianbergmann",
601 | "type": "github"
602 | }
603 | ],
604 | "time": "2020-11-28T06:44:49+00:00"
605 | },
606 | {
607 | "name": "phpunit/php-file-iterator",
608 | "version": "3.0.5",
609 | "source": {
610 | "type": "git",
611 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
612 | "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8"
613 | },
614 | "dist": {
615 | "type": "zip",
616 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8",
617 | "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8",
618 | "shasum": ""
619 | },
620 | "require": {
621 | "php": ">=7.3"
622 | },
623 | "require-dev": {
624 | "phpunit/phpunit": "^9.3"
625 | },
626 | "type": "library",
627 | "extra": {
628 | "branch-alias": {
629 | "dev-master": "3.0-dev"
630 | }
631 | },
632 | "autoload": {
633 | "classmap": [
634 | "src/"
635 | ]
636 | },
637 | "notification-url": "https://packagist.org/downloads/",
638 | "license": [
639 | "BSD-3-Clause"
640 | ],
641 | "authors": [
642 | {
643 | "name": "Sebastian Bergmann",
644 | "email": "sebastian@phpunit.de",
645 | "role": "lead"
646 | }
647 | ],
648 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
649 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
650 | "keywords": [
651 | "filesystem",
652 | "iterator"
653 | ],
654 | "support": {
655 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
656 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5"
657 | },
658 | "funding": [
659 | {
660 | "url": "https://github.com/sebastianbergmann",
661 | "type": "github"
662 | }
663 | ],
664 | "time": "2020-09-28T05:57:25+00:00"
665 | },
666 | {
667 | "name": "phpunit/php-invoker",
668 | "version": "3.1.1",
669 | "source": {
670 | "type": "git",
671 | "url": "https://github.com/sebastianbergmann/php-invoker.git",
672 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
673 | },
674 | "dist": {
675 | "type": "zip",
676 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
677 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
678 | "shasum": ""
679 | },
680 | "require": {
681 | "php": ">=7.3"
682 | },
683 | "require-dev": {
684 | "ext-pcntl": "*",
685 | "phpunit/phpunit": "^9.3"
686 | },
687 | "suggest": {
688 | "ext-pcntl": "*"
689 | },
690 | "type": "library",
691 | "extra": {
692 | "branch-alias": {
693 | "dev-master": "3.1-dev"
694 | }
695 | },
696 | "autoload": {
697 | "classmap": [
698 | "src/"
699 | ]
700 | },
701 | "notification-url": "https://packagist.org/downloads/",
702 | "license": [
703 | "BSD-3-Clause"
704 | ],
705 | "authors": [
706 | {
707 | "name": "Sebastian Bergmann",
708 | "email": "sebastian@phpunit.de",
709 | "role": "lead"
710 | }
711 | ],
712 | "description": "Invoke callables with a timeout",
713 | "homepage": "https://github.com/sebastianbergmann/php-invoker/",
714 | "keywords": [
715 | "process"
716 | ],
717 | "support": {
718 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
719 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
720 | },
721 | "funding": [
722 | {
723 | "url": "https://github.com/sebastianbergmann",
724 | "type": "github"
725 | }
726 | ],
727 | "time": "2020-09-28T05:58:55+00:00"
728 | },
729 | {
730 | "name": "phpunit/php-text-template",
731 | "version": "2.0.4",
732 | "source": {
733 | "type": "git",
734 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
735 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
736 | },
737 | "dist": {
738 | "type": "zip",
739 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
740 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
741 | "shasum": ""
742 | },
743 | "require": {
744 | "php": ">=7.3"
745 | },
746 | "require-dev": {
747 | "phpunit/phpunit": "^9.3"
748 | },
749 | "type": "library",
750 | "extra": {
751 | "branch-alias": {
752 | "dev-master": "2.0-dev"
753 | }
754 | },
755 | "autoload": {
756 | "classmap": [
757 | "src/"
758 | ]
759 | },
760 | "notification-url": "https://packagist.org/downloads/",
761 | "license": [
762 | "BSD-3-Clause"
763 | ],
764 | "authors": [
765 | {
766 | "name": "Sebastian Bergmann",
767 | "email": "sebastian@phpunit.de",
768 | "role": "lead"
769 | }
770 | ],
771 | "description": "Simple template engine.",
772 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
773 | "keywords": [
774 | "template"
775 | ],
776 | "support": {
777 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
778 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
779 | },
780 | "funding": [
781 | {
782 | "url": "https://github.com/sebastianbergmann",
783 | "type": "github"
784 | }
785 | ],
786 | "time": "2020-10-26T05:33:50+00:00"
787 | },
788 | {
789 | "name": "phpunit/php-timer",
790 | "version": "5.0.3",
791 | "source": {
792 | "type": "git",
793 | "url": "https://github.com/sebastianbergmann/php-timer.git",
794 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
795 | },
796 | "dist": {
797 | "type": "zip",
798 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
799 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
800 | "shasum": ""
801 | },
802 | "require": {
803 | "php": ">=7.3"
804 | },
805 | "require-dev": {
806 | "phpunit/phpunit": "^9.3"
807 | },
808 | "type": "library",
809 | "extra": {
810 | "branch-alias": {
811 | "dev-master": "5.0-dev"
812 | }
813 | },
814 | "autoload": {
815 | "classmap": [
816 | "src/"
817 | ]
818 | },
819 | "notification-url": "https://packagist.org/downloads/",
820 | "license": [
821 | "BSD-3-Clause"
822 | ],
823 | "authors": [
824 | {
825 | "name": "Sebastian Bergmann",
826 | "email": "sebastian@phpunit.de",
827 | "role": "lead"
828 | }
829 | ],
830 | "description": "Utility class for timing",
831 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
832 | "keywords": [
833 | "timer"
834 | ],
835 | "support": {
836 | "issues": "https://github.com/sebastianbergmann/php-timer/issues",
837 | "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
838 | },
839 | "funding": [
840 | {
841 | "url": "https://github.com/sebastianbergmann",
842 | "type": "github"
843 | }
844 | ],
845 | "time": "2020-10-26T13:16:10+00:00"
846 | },
847 | {
848 | "name": "phpunit/phpunit",
849 | "version": "9.5.2",
850 | "source": {
851 | "type": "git",
852 | "url": "https://github.com/sebastianbergmann/phpunit.git",
853 | "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4"
854 | },
855 | "dist": {
856 | "type": "zip",
857 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f661659747f2f87f9e72095bb207bceb0f151cb4",
858 | "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4",
859 | "shasum": ""
860 | },
861 | "require": {
862 | "doctrine/instantiator": "^1.3.1",
863 | "ext-dom": "*",
864 | "ext-json": "*",
865 | "ext-libxml": "*",
866 | "ext-mbstring": "*",
867 | "ext-xml": "*",
868 | "ext-xmlwriter": "*",
869 | "myclabs/deep-copy": "^1.10.1",
870 | "phar-io/manifest": "^2.0.1",
871 | "phar-io/version": "^3.0.2",
872 | "php": ">=7.3",
873 | "phpspec/prophecy": "^1.12.1",
874 | "phpunit/php-code-coverage": "^9.2.3",
875 | "phpunit/php-file-iterator": "^3.0.5",
876 | "phpunit/php-invoker": "^3.1.1",
877 | "phpunit/php-text-template": "^2.0.3",
878 | "phpunit/php-timer": "^5.0.2",
879 | "sebastian/cli-parser": "^1.0.1",
880 | "sebastian/code-unit": "^1.0.6",
881 | "sebastian/comparator": "^4.0.5",
882 | "sebastian/diff": "^4.0.3",
883 | "sebastian/environment": "^5.1.3",
884 | "sebastian/exporter": "^4.0.3",
885 | "sebastian/global-state": "^5.0.1",
886 | "sebastian/object-enumerator": "^4.0.3",
887 | "sebastian/resource-operations": "^3.0.3",
888 | "sebastian/type": "^2.3",
889 | "sebastian/version": "^3.0.2"
890 | },
891 | "require-dev": {
892 | "ext-pdo": "*",
893 | "phpspec/prophecy-phpunit": "^2.0.1"
894 | },
895 | "suggest": {
896 | "ext-soap": "*",
897 | "ext-xdebug": "*"
898 | },
899 | "bin": [
900 | "phpunit"
901 | ],
902 | "type": "library",
903 | "extra": {
904 | "branch-alias": {
905 | "dev-master": "9.5-dev"
906 | }
907 | },
908 | "autoload": {
909 | "classmap": [
910 | "src/"
911 | ],
912 | "files": [
913 | "src/Framework/Assert/Functions.php"
914 | ]
915 | },
916 | "notification-url": "https://packagist.org/downloads/",
917 | "license": [
918 | "BSD-3-Clause"
919 | ],
920 | "authors": [
921 | {
922 | "name": "Sebastian Bergmann",
923 | "email": "sebastian@phpunit.de",
924 | "role": "lead"
925 | }
926 | ],
927 | "description": "The PHP Unit Testing framework.",
928 | "homepage": "https://phpunit.de/",
929 | "keywords": [
930 | "phpunit",
931 | "testing",
932 | "xunit"
933 | ],
934 | "support": {
935 | "issues": "https://github.com/sebastianbergmann/phpunit/issues",
936 | "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.2"
937 | },
938 | "funding": [
939 | {
940 | "url": "https://phpunit.de/donate.html",
941 | "type": "custom"
942 | },
943 | {
944 | "url": "https://github.com/sebastianbergmann",
945 | "type": "github"
946 | }
947 | ],
948 | "time": "2021-02-02T14:45:58+00:00"
949 | },
950 | {
951 | "name": "sebastian/cli-parser",
952 | "version": "1.0.1",
953 | "source": {
954 | "type": "git",
955 | "url": "https://github.com/sebastianbergmann/cli-parser.git",
956 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
957 | },
958 | "dist": {
959 | "type": "zip",
960 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
961 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
962 | "shasum": ""
963 | },
964 | "require": {
965 | "php": ">=7.3"
966 | },
967 | "require-dev": {
968 | "phpunit/phpunit": "^9.3"
969 | },
970 | "type": "library",
971 | "extra": {
972 | "branch-alias": {
973 | "dev-master": "1.0-dev"
974 | }
975 | },
976 | "autoload": {
977 | "classmap": [
978 | "src/"
979 | ]
980 | },
981 | "notification-url": "https://packagist.org/downloads/",
982 | "license": [
983 | "BSD-3-Clause"
984 | ],
985 | "authors": [
986 | {
987 | "name": "Sebastian Bergmann",
988 | "email": "sebastian@phpunit.de",
989 | "role": "lead"
990 | }
991 | ],
992 | "description": "Library for parsing CLI options",
993 | "homepage": "https://github.com/sebastianbergmann/cli-parser",
994 | "support": {
995 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
996 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
997 | },
998 | "funding": [
999 | {
1000 | "url": "https://github.com/sebastianbergmann",
1001 | "type": "github"
1002 | }
1003 | ],
1004 | "time": "2020-09-28T06:08:49+00:00"
1005 | },
1006 | {
1007 | "name": "sebastian/code-unit",
1008 | "version": "1.0.8",
1009 | "source": {
1010 | "type": "git",
1011 | "url": "https://github.com/sebastianbergmann/code-unit.git",
1012 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
1013 | },
1014 | "dist": {
1015 | "type": "zip",
1016 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
1017 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
1018 | "shasum": ""
1019 | },
1020 | "require": {
1021 | "php": ">=7.3"
1022 | },
1023 | "require-dev": {
1024 | "phpunit/phpunit": "^9.3"
1025 | },
1026 | "type": "library",
1027 | "extra": {
1028 | "branch-alias": {
1029 | "dev-master": "1.0-dev"
1030 | }
1031 | },
1032 | "autoload": {
1033 | "classmap": [
1034 | "src/"
1035 | ]
1036 | },
1037 | "notification-url": "https://packagist.org/downloads/",
1038 | "license": [
1039 | "BSD-3-Clause"
1040 | ],
1041 | "authors": [
1042 | {
1043 | "name": "Sebastian Bergmann",
1044 | "email": "sebastian@phpunit.de",
1045 | "role": "lead"
1046 | }
1047 | ],
1048 | "description": "Collection of value objects that represent the PHP code units",
1049 | "homepage": "https://github.com/sebastianbergmann/code-unit",
1050 | "support": {
1051 | "issues": "https://github.com/sebastianbergmann/code-unit/issues",
1052 | "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
1053 | },
1054 | "funding": [
1055 | {
1056 | "url": "https://github.com/sebastianbergmann",
1057 | "type": "github"
1058 | }
1059 | ],
1060 | "time": "2020-10-26T13:08:54+00:00"
1061 | },
1062 | {
1063 | "name": "sebastian/code-unit-reverse-lookup",
1064 | "version": "2.0.3",
1065 | "source": {
1066 | "type": "git",
1067 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
1068 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
1069 | },
1070 | "dist": {
1071 | "type": "zip",
1072 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
1073 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
1074 | "shasum": ""
1075 | },
1076 | "require": {
1077 | "php": ">=7.3"
1078 | },
1079 | "require-dev": {
1080 | "phpunit/phpunit": "^9.3"
1081 | },
1082 | "type": "library",
1083 | "extra": {
1084 | "branch-alias": {
1085 | "dev-master": "2.0-dev"
1086 | }
1087 | },
1088 | "autoload": {
1089 | "classmap": [
1090 | "src/"
1091 | ]
1092 | },
1093 | "notification-url": "https://packagist.org/downloads/",
1094 | "license": [
1095 | "BSD-3-Clause"
1096 | ],
1097 | "authors": [
1098 | {
1099 | "name": "Sebastian Bergmann",
1100 | "email": "sebastian@phpunit.de"
1101 | }
1102 | ],
1103 | "description": "Looks up which function or method a line of code belongs to",
1104 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
1105 | "support": {
1106 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
1107 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3"
1108 | },
1109 | "funding": [
1110 | {
1111 | "url": "https://github.com/sebastianbergmann",
1112 | "type": "github"
1113 | }
1114 | ],
1115 | "time": "2020-09-28T05:30:19+00:00"
1116 | },
1117 | {
1118 | "name": "sebastian/comparator",
1119 | "version": "4.0.6",
1120 | "source": {
1121 | "type": "git",
1122 | "url": "https://github.com/sebastianbergmann/comparator.git",
1123 | "reference": "55f4261989e546dc112258c7a75935a81a7ce382"
1124 | },
1125 | "dist": {
1126 | "type": "zip",
1127 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382",
1128 | "reference": "55f4261989e546dc112258c7a75935a81a7ce382",
1129 | "shasum": ""
1130 | },
1131 | "require": {
1132 | "php": ">=7.3",
1133 | "sebastian/diff": "^4.0",
1134 | "sebastian/exporter": "^4.0"
1135 | },
1136 | "require-dev": {
1137 | "phpunit/phpunit": "^9.3"
1138 | },
1139 | "type": "library",
1140 | "extra": {
1141 | "branch-alias": {
1142 | "dev-master": "4.0-dev"
1143 | }
1144 | },
1145 | "autoload": {
1146 | "classmap": [
1147 | "src/"
1148 | ]
1149 | },
1150 | "notification-url": "https://packagist.org/downloads/",
1151 | "license": [
1152 | "BSD-3-Clause"
1153 | ],
1154 | "authors": [
1155 | {
1156 | "name": "Sebastian Bergmann",
1157 | "email": "sebastian@phpunit.de"
1158 | },
1159 | {
1160 | "name": "Jeff Welch",
1161 | "email": "whatthejeff@gmail.com"
1162 | },
1163 | {
1164 | "name": "Volker Dusch",
1165 | "email": "github@wallbash.com"
1166 | },
1167 | {
1168 | "name": "Bernhard Schussek",
1169 | "email": "bschussek@2bepublished.at"
1170 | }
1171 | ],
1172 | "description": "Provides the functionality to compare PHP values for equality",
1173 | "homepage": "https://github.com/sebastianbergmann/comparator",
1174 | "keywords": [
1175 | "comparator",
1176 | "compare",
1177 | "equality"
1178 | ],
1179 | "support": {
1180 | "issues": "https://github.com/sebastianbergmann/comparator/issues",
1181 | "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6"
1182 | },
1183 | "funding": [
1184 | {
1185 | "url": "https://github.com/sebastianbergmann",
1186 | "type": "github"
1187 | }
1188 | ],
1189 | "time": "2020-10-26T15:49:45+00:00"
1190 | },
1191 | {
1192 | "name": "sebastian/complexity",
1193 | "version": "2.0.2",
1194 | "source": {
1195 | "type": "git",
1196 | "url": "https://github.com/sebastianbergmann/complexity.git",
1197 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
1198 | },
1199 | "dist": {
1200 | "type": "zip",
1201 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
1202 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
1203 | "shasum": ""
1204 | },
1205 | "require": {
1206 | "nikic/php-parser": "^4.7",
1207 | "php": ">=7.3"
1208 | },
1209 | "require-dev": {
1210 | "phpunit/phpunit": "^9.3"
1211 | },
1212 | "type": "library",
1213 | "extra": {
1214 | "branch-alias": {
1215 | "dev-master": "2.0-dev"
1216 | }
1217 | },
1218 | "autoload": {
1219 | "classmap": [
1220 | "src/"
1221 | ]
1222 | },
1223 | "notification-url": "https://packagist.org/downloads/",
1224 | "license": [
1225 | "BSD-3-Clause"
1226 | ],
1227 | "authors": [
1228 | {
1229 | "name": "Sebastian Bergmann",
1230 | "email": "sebastian@phpunit.de",
1231 | "role": "lead"
1232 | }
1233 | ],
1234 | "description": "Library for calculating the complexity of PHP code units",
1235 | "homepage": "https://github.com/sebastianbergmann/complexity",
1236 | "support": {
1237 | "issues": "https://github.com/sebastianbergmann/complexity/issues",
1238 | "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
1239 | },
1240 | "funding": [
1241 | {
1242 | "url": "https://github.com/sebastianbergmann",
1243 | "type": "github"
1244 | }
1245 | ],
1246 | "time": "2020-10-26T15:52:27+00:00"
1247 | },
1248 | {
1249 | "name": "sebastian/diff",
1250 | "version": "4.0.4",
1251 | "source": {
1252 | "type": "git",
1253 | "url": "https://github.com/sebastianbergmann/diff.git",
1254 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d"
1255 | },
1256 | "dist": {
1257 | "type": "zip",
1258 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d",
1259 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d",
1260 | "shasum": ""
1261 | },
1262 | "require": {
1263 | "php": ">=7.3"
1264 | },
1265 | "require-dev": {
1266 | "phpunit/phpunit": "^9.3",
1267 | "symfony/process": "^4.2 || ^5"
1268 | },
1269 | "type": "library",
1270 | "extra": {
1271 | "branch-alias": {
1272 | "dev-master": "4.0-dev"
1273 | }
1274 | },
1275 | "autoload": {
1276 | "classmap": [
1277 | "src/"
1278 | ]
1279 | },
1280 | "notification-url": "https://packagist.org/downloads/",
1281 | "license": [
1282 | "BSD-3-Clause"
1283 | ],
1284 | "authors": [
1285 | {
1286 | "name": "Sebastian Bergmann",
1287 | "email": "sebastian@phpunit.de"
1288 | },
1289 | {
1290 | "name": "Kore Nordmann",
1291 | "email": "mail@kore-nordmann.de"
1292 | }
1293 | ],
1294 | "description": "Diff implementation",
1295 | "homepage": "https://github.com/sebastianbergmann/diff",
1296 | "keywords": [
1297 | "diff",
1298 | "udiff",
1299 | "unidiff",
1300 | "unified diff"
1301 | ],
1302 | "support": {
1303 | "issues": "https://github.com/sebastianbergmann/diff/issues",
1304 | "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
1305 | },
1306 | "funding": [
1307 | {
1308 | "url": "https://github.com/sebastianbergmann",
1309 | "type": "github"
1310 | }
1311 | ],
1312 | "time": "2020-10-26T13:10:38+00:00"
1313 | },
1314 | {
1315 | "name": "sebastian/environment",
1316 | "version": "5.1.3",
1317 | "source": {
1318 | "type": "git",
1319 | "url": "https://github.com/sebastianbergmann/environment.git",
1320 | "reference": "388b6ced16caa751030f6a69e588299fa09200ac"
1321 | },
1322 | "dist": {
1323 | "type": "zip",
1324 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac",
1325 | "reference": "388b6ced16caa751030f6a69e588299fa09200ac",
1326 | "shasum": ""
1327 | },
1328 | "require": {
1329 | "php": ">=7.3"
1330 | },
1331 | "require-dev": {
1332 | "phpunit/phpunit": "^9.3"
1333 | },
1334 | "suggest": {
1335 | "ext-posix": "*"
1336 | },
1337 | "type": "library",
1338 | "extra": {
1339 | "branch-alias": {
1340 | "dev-master": "5.1-dev"
1341 | }
1342 | },
1343 | "autoload": {
1344 | "classmap": [
1345 | "src/"
1346 | ]
1347 | },
1348 | "notification-url": "https://packagist.org/downloads/",
1349 | "license": [
1350 | "BSD-3-Clause"
1351 | ],
1352 | "authors": [
1353 | {
1354 | "name": "Sebastian Bergmann",
1355 | "email": "sebastian@phpunit.de"
1356 | }
1357 | ],
1358 | "description": "Provides functionality to handle HHVM/PHP environments",
1359 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1360 | "keywords": [
1361 | "Xdebug",
1362 | "environment",
1363 | "hhvm"
1364 | ],
1365 | "support": {
1366 | "issues": "https://github.com/sebastianbergmann/environment/issues",
1367 | "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3"
1368 | },
1369 | "funding": [
1370 | {
1371 | "url": "https://github.com/sebastianbergmann",
1372 | "type": "github"
1373 | }
1374 | ],
1375 | "time": "2020-09-28T05:52:38+00:00"
1376 | },
1377 | {
1378 | "name": "sebastian/exporter",
1379 | "version": "4.0.3",
1380 | "source": {
1381 | "type": "git",
1382 | "url": "https://github.com/sebastianbergmann/exporter.git",
1383 | "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65"
1384 | },
1385 | "dist": {
1386 | "type": "zip",
1387 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65",
1388 | "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65",
1389 | "shasum": ""
1390 | },
1391 | "require": {
1392 | "php": ">=7.3",
1393 | "sebastian/recursion-context": "^4.0"
1394 | },
1395 | "require-dev": {
1396 | "ext-mbstring": "*",
1397 | "phpunit/phpunit": "^9.3"
1398 | },
1399 | "type": "library",
1400 | "extra": {
1401 | "branch-alias": {
1402 | "dev-master": "4.0-dev"
1403 | }
1404 | },
1405 | "autoload": {
1406 | "classmap": [
1407 | "src/"
1408 | ]
1409 | },
1410 | "notification-url": "https://packagist.org/downloads/",
1411 | "license": [
1412 | "BSD-3-Clause"
1413 | ],
1414 | "authors": [
1415 | {
1416 | "name": "Sebastian Bergmann",
1417 | "email": "sebastian@phpunit.de"
1418 | },
1419 | {
1420 | "name": "Jeff Welch",
1421 | "email": "whatthejeff@gmail.com"
1422 | },
1423 | {
1424 | "name": "Volker Dusch",
1425 | "email": "github@wallbash.com"
1426 | },
1427 | {
1428 | "name": "Adam Harvey",
1429 | "email": "aharvey@php.net"
1430 | },
1431 | {
1432 | "name": "Bernhard Schussek",
1433 | "email": "bschussek@gmail.com"
1434 | }
1435 | ],
1436 | "description": "Provides the functionality to export PHP variables for visualization",
1437 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1438 | "keywords": [
1439 | "export",
1440 | "exporter"
1441 | ],
1442 | "support": {
1443 | "issues": "https://github.com/sebastianbergmann/exporter/issues",
1444 | "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3"
1445 | },
1446 | "funding": [
1447 | {
1448 | "url": "https://github.com/sebastianbergmann",
1449 | "type": "github"
1450 | }
1451 | ],
1452 | "time": "2020-09-28T05:24:23+00:00"
1453 | },
1454 | {
1455 | "name": "sebastian/global-state",
1456 | "version": "5.0.2",
1457 | "source": {
1458 | "type": "git",
1459 | "url": "https://github.com/sebastianbergmann/global-state.git",
1460 | "reference": "a90ccbddffa067b51f574dea6eb25d5680839455"
1461 | },
1462 | "dist": {
1463 | "type": "zip",
1464 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455",
1465 | "reference": "a90ccbddffa067b51f574dea6eb25d5680839455",
1466 | "shasum": ""
1467 | },
1468 | "require": {
1469 | "php": ">=7.3",
1470 | "sebastian/object-reflector": "^2.0",
1471 | "sebastian/recursion-context": "^4.0"
1472 | },
1473 | "require-dev": {
1474 | "ext-dom": "*",
1475 | "phpunit/phpunit": "^9.3"
1476 | },
1477 | "suggest": {
1478 | "ext-uopz": "*"
1479 | },
1480 | "type": "library",
1481 | "extra": {
1482 | "branch-alias": {
1483 | "dev-master": "5.0-dev"
1484 | }
1485 | },
1486 | "autoload": {
1487 | "classmap": [
1488 | "src/"
1489 | ]
1490 | },
1491 | "notification-url": "https://packagist.org/downloads/",
1492 | "license": [
1493 | "BSD-3-Clause"
1494 | ],
1495 | "authors": [
1496 | {
1497 | "name": "Sebastian Bergmann",
1498 | "email": "sebastian@phpunit.de"
1499 | }
1500 | ],
1501 | "description": "Snapshotting of global state",
1502 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1503 | "keywords": [
1504 | "global state"
1505 | ],
1506 | "support": {
1507 | "issues": "https://github.com/sebastianbergmann/global-state/issues",
1508 | "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2"
1509 | },
1510 | "funding": [
1511 | {
1512 | "url": "https://github.com/sebastianbergmann",
1513 | "type": "github"
1514 | }
1515 | ],
1516 | "time": "2020-10-26T15:55:19+00:00"
1517 | },
1518 | {
1519 | "name": "sebastian/lines-of-code",
1520 | "version": "1.0.3",
1521 | "source": {
1522 | "type": "git",
1523 | "url": "https://github.com/sebastianbergmann/lines-of-code.git",
1524 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
1525 | },
1526 | "dist": {
1527 | "type": "zip",
1528 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
1529 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
1530 | "shasum": ""
1531 | },
1532 | "require": {
1533 | "nikic/php-parser": "^4.6",
1534 | "php": ">=7.3"
1535 | },
1536 | "require-dev": {
1537 | "phpunit/phpunit": "^9.3"
1538 | },
1539 | "type": "library",
1540 | "extra": {
1541 | "branch-alias": {
1542 | "dev-master": "1.0-dev"
1543 | }
1544 | },
1545 | "autoload": {
1546 | "classmap": [
1547 | "src/"
1548 | ]
1549 | },
1550 | "notification-url": "https://packagist.org/downloads/",
1551 | "license": [
1552 | "BSD-3-Clause"
1553 | ],
1554 | "authors": [
1555 | {
1556 | "name": "Sebastian Bergmann",
1557 | "email": "sebastian@phpunit.de",
1558 | "role": "lead"
1559 | }
1560 | ],
1561 | "description": "Library for counting the lines of code in PHP source code",
1562 | "homepage": "https://github.com/sebastianbergmann/lines-of-code",
1563 | "support": {
1564 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
1565 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
1566 | },
1567 | "funding": [
1568 | {
1569 | "url": "https://github.com/sebastianbergmann",
1570 | "type": "github"
1571 | }
1572 | ],
1573 | "time": "2020-11-28T06:42:11+00:00"
1574 | },
1575 | {
1576 | "name": "sebastian/object-enumerator",
1577 | "version": "4.0.4",
1578 | "source": {
1579 | "type": "git",
1580 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1581 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
1582 | },
1583 | "dist": {
1584 | "type": "zip",
1585 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
1586 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
1587 | "shasum": ""
1588 | },
1589 | "require": {
1590 | "php": ">=7.3",
1591 | "sebastian/object-reflector": "^2.0",
1592 | "sebastian/recursion-context": "^4.0"
1593 | },
1594 | "require-dev": {
1595 | "phpunit/phpunit": "^9.3"
1596 | },
1597 | "type": "library",
1598 | "extra": {
1599 | "branch-alias": {
1600 | "dev-master": "4.0-dev"
1601 | }
1602 | },
1603 | "autoload": {
1604 | "classmap": [
1605 | "src/"
1606 | ]
1607 | },
1608 | "notification-url": "https://packagist.org/downloads/",
1609 | "license": [
1610 | "BSD-3-Clause"
1611 | ],
1612 | "authors": [
1613 | {
1614 | "name": "Sebastian Bergmann",
1615 | "email": "sebastian@phpunit.de"
1616 | }
1617 | ],
1618 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1619 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1620 | "support": {
1621 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
1622 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
1623 | },
1624 | "funding": [
1625 | {
1626 | "url": "https://github.com/sebastianbergmann",
1627 | "type": "github"
1628 | }
1629 | ],
1630 | "time": "2020-10-26T13:12:34+00:00"
1631 | },
1632 | {
1633 | "name": "sebastian/object-reflector",
1634 | "version": "2.0.4",
1635 | "source": {
1636 | "type": "git",
1637 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
1638 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
1639 | },
1640 | "dist": {
1641 | "type": "zip",
1642 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
1643 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
1644 | "shasum": ""
1645 | },
1646 | "require": {
1647 | "php": ">=7.3"
1648 | },
1649 | "require-dev": {
1650 | "phpunit/phpunit": "^9.3"
1651 | },
1652 | "type": "library",
1653 | "extra": {
1654 | "branch-alias": {
1655 | "dev-master": "2.0-dev"
1656 | }
1657 | },
1658 | "autoload": {
1659 | "classmap": [
1660 | "src/"
1661 | ]
1662 | },
1663 | "notification-url": "https://packagist.org/downloads/",
1664 | "license": [
1665 | "BSD-3-Clause"
1666 | ],
1667 | "authors": [
1668 | {
1669 | "name": "Sebastian Bergmann",
1670 | "email": "sebastian@phpunit.de"
1671 | }
1672 | ],
1673 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
1674 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
1675 | "support": {
1676 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
1677 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
1678 | },
1679 | "funding": [
1680 | {
1681 | "url": "https://github.com/sebastianbergmann",
1682 | "type": "github"
1683 | }
1684 | ],
1685 | "time": "2020-10-26T13:14:26+00:00"
1686 | },
1687 | {
1688 | "name": "sebastian/recursion-context",
1689 | "version": "4.0.4",
1690 | "source": {
1691 | "type": "git",
1692 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1693 | "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172"
1694 | },
1695 | "dist": {
1696 | "type": "zip",
1697 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172",
1698 | "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172",
1699 | "shasum": ""
1700 | },
1701 | "require": {
1702 | "php": ">=7.3"
1703 | },
1704 | "require-dev": {
1705 | "phpunit/phpunit": "^9.3"
1706 | },
1707 | "type": "library",
1708 | "extra": {
1709 | "branch-alias": {
1710 | "dev-master": "4.0-dev"
1711 | }
1712 | },
1713 | "autoload": {
1714 | "classmap": [
1715 | "src/"
1716 | ]
1717 | },
1718 | "notification-url": "https://packagist.org/downloads/",
1719 | "license": [
1720 | "BSD-3-Clause"
1721 | ],
1722 | "authors": [
1723 | {
1724 | "name": "Sebastian Bergmann",
1725 | "email": "sebastian@phpunit.de"
1726 | },
1727 | {
1728 | "name": "Jeff Welch",
1729 | "email": "whatthejeff@gmail.com"
1730 | },
1731 | {
1732 | "name": "Adam Harvey",
1733 | "email": "aharvey@php.net"
1734 | }
1735 | ],
1736 | "description": "Provides functionality to recursively process PHP variables",
1737 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1738 | "support": {
1739 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
1740 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4"
1741 | },
1742 | "funding": [
1743 | {
1744 | "url": "https://github.com/sebastianbergmann",
1745 | "type": "github"
1746 | }
1747 | ],
1748 | "time": "2020-10-26T13:17:30+00:00"
1749 | },
1750 | {
1751 | "name": "sebastian/resource-operations",
1752 | "version": "3.0.3",
1753 | "source": {
1754 | "type": "git",
1755 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
1756 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
1757 | },
1758 | "dist": {
1759 | "type": "zip",
1760 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
1761 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
1762 | "shasum": ""
1763 | },
1764 | "require": {
1765 | "php": ">=7.3"
1766 | },
1767 | "require-dev": {
1768 | "phpunit/phpunit": "^9.0"
1769 | },
1770 | "type": "library",
1771 | "extra": {
1772 | "branch-alias": {
1773 | "dev-master": "3.0-dev"
1774 | }
1775 | },
1776 | "autoload": {
1777 | "classmap": [
1778 | "src/"
1779 | ]
1780 | },
1781 | "notification-url": "https://packagist.org/downloads/",
1782 | "license": [
1783 | "BSD-3-Clause"
1784 | ],
1785 | "authors": [
1786 | {
1787 | "name": "Sebastian Bergmann",
1788 | "email": "sebastian@phpunit.de"
1789 | }
1790 | ],
1791 | "description": "Provides a list of PHP built-in functions that operate on resources",
1792 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
1793 | "support": {
1794 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
1795 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
1796 | },
1797 | "funding": [
1798 | {
1799 | "url": "https://github.com/sebastianbergmann",
1800 | "type": "github"
1801 | }
1802 | ],
1803 | "time": "2020-09-28T06:45:17+00:00"
1804 | },
1805 | {
1806 | "name": "sebastian/type",
1807 | "version": "2.3.1",
1808 | "source": {
1809 | "type": "git",
1810 | "url": "https://github.com/sebastianbergmann/type.git",
1811 | "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2"
1812 | },
1813 | "dist": {
1814 | "type": "zip",
1815 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/81cd61ab7bbf2de744aba0ea61fae32f721df3d2",
1816 | "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2",
1817 | "shasum": ""
1818 | },
1819 | "require": {
1820 | "php": ">=7.3"
1821 | },
1822 | "require-dev": {
1823 | "phpunit/phpunit": "^9.3"
1824 | },
1825 | "type": "library",
1826 | "extra": {
1827 | "branch-alias": {
1828 | "dev-master": "2.3-dev"
1829 | }
1830 | },
1831 | "autoload": {
1832 | "classmap": [
1833 | "src/"
1834 | ]
1835 | },
1836 | "notification-url": "https://packagist.org/downloads/",
1837 | "license": [
1838 | "BSD-3-Clause"
1839 | ],
1840 | "authors": [
1841 | {
1842 | "name": "Sebastian Bergmann",
1843 | "email": "sebastian@phpunit.de",
1844 | "role": "lead"
1845 | }
1846 | ],
1847 | "description": "Collection of value objects that represent the types of the PHP type system",
1848 | "homepage": "https://github.com/sebastianbergmann/type",
1849 | "support": {
1850 | "issues": "https://github.com/sebastianbergmann/type/issues",
1851 | "source": "https://github.com/sebastianbergmann/type/tree/2.3.1"
1852 | },
1853 | "funding": [
1854 | {
1855 | "url": "https://github.com/sebastianbergmann",
1856 | "type": "github"
1857 | }
1858 | ],
1859 | "time": "2020-10-26T13:18:59+00:00"
1860 | },
1861 | {
1862 | "name": "sebastian/version",
1863 | "version": "3.0.2",
1864 | "source": {
1865 | "type": "git",
1866 | "url": "https://github.com/sebastianbergmann/version.git",
1867 | "reference": "c6c1022351a901512170118436c764e473f6de8c"
1868 | },
1869 | "dist": {
1870 | "type": "zip",
1871 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
1872 | "reference": "c6c1022351a901512170118436c764e473f6de8c",
1873 | "shasum": ""
1874 | },
1875 | "require": {
1876 | "php": ">=7.3"
1877 | },
1878 | "type": "library",
1879 | "extra": {
1880 | "branch-alias": {
1881 | "dev-master": "3.0-dev"
1882 | }
1883 | },
1884 | "autoload": {
1885 | "classmap": [
1886 | "src/"
1887 | ]
1888 | },
1889 | "notification-url": "https://packagist.org/downloads/",
1890 | "license": [
1891 | "BSD-3-Clause"
1892 | ],
1893 | "authors": [
1894 | {
1895 | "name": "Sebastian Bergmann",
1896 | "email": "sebastian@phpunit.de",
1897 | "role": "lead"
1898 | }
1899 | ],
1900 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1901 | "homepage": "https://github.com/sebastianbergmann/version",
1902 | "support": {
1903 | "issues": "https://github.com/sebastianbergmann/version/issues",
1904 | "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
1905 | },
1906 | "funding": [
1907 | {
1908 | "url": "https://github.com/sebastianbergmann",
1909 | "type": "github"
1910 | }
1911 | ],
1912 | "time": "2020-09-28T06:39:44+00:00"
1913 | },
1914 | {
1915 | "name": "symfony/polyfill-ctype",
1916 | "version": "v1.22.1",
1917 | "source": {
1918 | "type": "git",
1919 | "url": "https://github.com/symfony/polyfill-ctype.git",
1920 | "reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
1921 | },
1922 | "dist": {
1923 | "type": "zip",
1924 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
1925 | "reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
1926 | "shasum": ""
1927 | },
1928 | "require": {
1929 | "php": ">=7.1"
1930 | },
1931 | "suggest": {
1932 | "ext-ctype": "For best performance"
1933 | },
1934 | "type": "library",
1935 | "extra": {
1936 | "branch-alias": {
1937 | "dev-main": "1.22-dev"
1938 | },
1939 | "thanks": {
1940 | "name": "symfony/polyfill",
1941 | "url": "https://github.com/symfony/polyfill"
1942 | }
1943 | },
1944 | "autoload": {
1945 | "psr-4": {
1946 | "Symfony\\Polyfill\\Ctype\\": ""
1947 | },
1948 | "files": [
1949 | "bootstrap.php"
1950 | ]
1951 | },
1952 | "notification-url": "https://packagist.org/downloads/",
1953 | "license": [
1954 | "MIT"
1955 | ],
1956 | "authors": [
1957 | {
1958 | "name": "Gert de Pagter",
1959 | "email": "BackEndTea@gmail.com"
1960 | },
1961 | {
1962 | "name": "Symfony Community",
1963 | "homepage": "https://symfony.com/contributors"
1964 | }
1965 | ],
1966 | "description": "Symfony polyfill for ctype functions",
1967 | "homepage": "https://symfony.com",
1968 | "keywords": [
1969 | "compatibility",
1970 | "ctype",
1971 | "polyfill",
1972 | "portable"
1973 | ],
1974 | "support": {
1975 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1"
1976 | },
1977 | "funding": [
1978 | {
1979 | "url": "https://symfony.com/sponsor",
1980 | "type": "custom"
1981 | },
1982 | {
1983 | "url": "https://github.com/fabpot",
1984 | "type": "github"
1985 | },
1986 | {
1987 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
1988 | "type": "tidelift"
1989 | }
1990 | ],
1991 | "time": "2021-01-07T16:49:33+00:00"
1992 | },
1993 | {
1994 | "name": "theseer/tokenizer",
1995 | "version": "1.2.0",
1996 | "source": {
1997 | "type": "git",
1998 | "url": "https://github.com/theseer/tokenizer.git",
1999 | "reference": "75a63c33a8577608444246075ea0af0d052e452a"
2000 | },
2001 | "dist": {
2002 | "type": "zip",
2003 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a",
2004 | "reference": "75a63c33a8577608444246075ea0af0d052e452a",
2005 | "shasum": ""
2006 | },
2007 | "require": {
2008 | "ext-dom": "*",
2009 | "ext-tokenizer": "*",
2010 | "ext-xmlwriter": "*",
2011 | "php": "^7.2 || ^8.0"
2012 | },
2013 | "type": "library",
2014 | "autoload": {
2015 | "classmap": [
2016 | "src/"
2017 | ]
2018 | },
2019 | "notification-url": "https://packagist.org/downloads/",
2020 | "license": [
2021 | "BSD-3-Clause"
2022 | ],
2023 | "authors": [
2024 | {
2025 | "name": "Arne Blankerts",
2026 | "email": "arne@blankerts.de",
2027 | "role": "Developer"
2028 | }
2029 | ],
2030 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
2031 | "support": {
2032 | "issues": "https://github.com/theseer/tokenizer/issues",
2033 | "source": "https://github.com/theseer/tokenizer/tree/master"
2034 | },
2035 | "funding": [
2036 | {
2037 | "url": "https://github.com/theseer",
2038 | "type": "github"
2039 | }
2040 | ],
2041 | "time": "2020-07-12T23:59:07+00:00"
2042 | },
2043 | {
2044 | "name": "webmozart/assert",
2045 | "version": "1.9.1",
2046 | "source": {
2047 | "type": "git",
2048 | "url": "https://github.com/webmozarts/assert.git",
2049 | "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
2050 | },
2051 | "dist": {
2052 | "type": "zip",
2053 | "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
2054 | "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
2055 | "shasum": ""
2056 | },
2057 | "require": {
2058 | "php": "^5.3.3 || ^7.0 || ^8.0",
2059 | "symfony/polyfill-ctype": "^1.8"
2060 | },
2061 | "conflict": {
2062 | "phpstan/phpstan": "<0.12.20",
2063 | "vimeo/psalm": "<3.9.1"
2064 | },
2065 | "require-dev": {
2066 | "phpunit/phpunit": "^4.8.36 || ^7.5.13"
2067 | },
2068 | "type": "library",
2069 | "autoload": {
2070 | "psr-4": {
2071 | "Webmozart\\Assert\\": "src/"
2072 | }
2073 | },
2074 | "notification-url": "https://packagist.org/downloads/",
2075 | "license": [
2076 | "MIT"
2077 | ],
2078 | "authors": [
2079 | {
2080 | "name": "Bernhard Schussek",
2081 | "email": "bschussek@gmail.com"
2082 | }
2083 | ],
2084 | "description": "Assertions to validate method input/output with nice error messages.",
2085 | "keywords": [
2086 | "assert",
2087 | "check",
2088 | "validate"
2089 | ],
2090 | "support": {
2091 | "issues": "https://github.com/webmozarts/assert/issues",
2092 | "source": "https://github.com/webmozarts/assert/tree/1.9.1"
2093 | },
2094 | "time": "2020-07-08T17:02:28+00:00"
2095 | }
2096 | ],
2097 | "aliases": [],
2098 | "minimum-stability": "stable",
2099 | "stability-flags": [],
2100 | "prefer-stable": false,
2101 | "prefer-lowest": false,
2102 | "platform": {
2103 | "php": ">=7.4",
2104 | "ext-openssl": "*",
2105 | "ext-json": "*"
2106 | },
2107 | "platform-dev": [],
2108 | "plugin-api-version": "2.0.0"
2109 | }
2110 |
--------------------------------------------------------------------------------
/example/index.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 | require_once "../src/JSignPDF.php";
7 |
8 | use Jeidison\JSignPDF\JSignPDF;
9 | use Jeidison\JSignPDF\Sign\JSignParam;
10 |
11 | $param = JSignParam::instance();
12 | $param->setCertificate(file_get_contents('../tests/resources/certificado.pfx'));
13 | $param->setPdf(file_get_contents('../tests/resources/pdf-test.pdf'));
14 | $param->setPassword('123');
15 |
16 | $jSignPdf = new JSignPDF($param);
17 | $fileSigned = $jSignPdf->sign();
18 | file_put_contents('../tmp/file_signed.pdf', $fileSigned);
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 | ./tests
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/JSignFileService.php:
--------------------------------------------------------------------------------
1 |
7 | */
8 | class JSignFileService
9 | {
10 |
11 | public static function instance()
12 | {
13 | return new self();
14 | }
15 |
16 | public function contentFile($path, $isInBase64 = false)
17 | {
18 | $content = file_get_contents($path);
19 | return $isInBase64 ? base64_encode($content) : $content;
20 | }
21 |
22 | public function storeFile($path, $name, $content)
23 | {
24 | $filename = $path . $name;
25 | file_put_contents($filename, $content);
26 | return $filename;
27 | }
28 |
29 | public function deleteFile(string $path)
30 | {
31 | if (is_file($path))
32 | unlink($path);
33 | }
34 |
35 | public function deleteTempFiles(string $pathTemp, string $name)
36 | {
37 | $pathPfxFile = "$pathTemp$name.pfx";
38 | $pathPdfFile = "$pathTemp$name.pdf";
39 | $pathPdfSignedFile = "{$pathTemp}{$name}_signed.pdf";
40 | $tempFiles = [$pathPfxFile, $pathPdfFile, $pathPdfSignedFile];
41 | foreach ($tempFiles as $path)
42 | $this->deleteFile($path);
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/JSignPDF.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | class JSignPDF
12 | {
13 | private $service;
14 | private $param;
15 |
16 | public function __construct(JSignParam $param = null)
17 | {
18 | $this->service = new JSignService();
19 | $this->param = $param;
20 | }
21 |
22 | public static function instance(JSignParam $param = null)
23 | {
24 | return new self($param);
25 | }
26 |
27 | public function sign()
28 | {
29 | return $this->service->sign($this->param);
30 | }
31 |
32 | public function getVersion()
33 | {
34 | return $this->service->getVersion($this->param);
35 | }
36 |
37 | public function setParam(JSignParam $param)
38 | {
39 | $this->param = $param;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/Sign/JSignParam.php:
--------------------------------------------------------------------------------
1 |
7 | */
8 | class JSignParam
9 | {
10 | private $pdf;
11 | private $certificate;
12 | private $password;
13 | private $pathPdfSigned;
14 | private $JSignParameters = "-a -kst PKCS12";
15 | private $isUseJavaInstalled = false;
16 | private $javaPath = '';
17 | private $tempPath;
18 | private $tempName;
19 | private $isOutputTypeBase64 = false;
20 | private $jSignPdfJarPath;
21 |
22 | public function __construct()
23 | {
24 | $this->tempName = md5(time() . uniqid() . mt_rand());
25 | $this->tempPath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
26 | }
27 |
28 | public static function instance()
29 | {
30 | return new self();
31 | }
32 |
33 | public function getPdf()
34 | {
35 | return $this->pdf;
36 | }
37 |
38 | public function setPdf($pdf)
39 | {
40 | $this->pdf = $pdf;
41 | return $this;
42 | }
43 |
44 | public function getCertificate()
45 | {
46 | return $this->certificate;
47 | }
48 |
49 | public function setCertificate($certificate)
50 | {
51 | $this->certificate = $certificate;
52 | return $this;
53 | }
54 |
55 | public function getPassword()
56 | {
57 | return $this->password;
58 | }
59 |
60 | public function setPassword($password)
61 | {
62 | $this->password = $password;
63 | return $this;
64 | }
65 |
66 | public function getPathPdfSigned()
67 | {
68 | return $this->pathPdfSigned != null ? $this->pathPdfSigned : $this->getTempPath();
69 | }
70 |
71 | public function setPathPdfSigned($pathPdfSigned)
72 | {
73 | $this->pathPdfSigned = $pathPdfSigned;
74 | return $this;
75 | }
76 |
77 | public function getJSignParameters(): string
78 | {
79 | return $this->JSignParameters;
80 | }
81 |
82 | public function setJSignParameters(string $JSignParameters)
83 | {
84 | $this->JSignParameters = $JSignParameters;
85 | return $this;
86 | }
87 |
88 | public function getTempPath()
89 | {
90 | return $this->tempPath;
91 | }
92 |
93 | public function setTempPath($tempPath)
94 | {
95 | $this->tempPath = $tempPath;
96 | return $this;
97 | }
98 |
99 | public function getTempName($extension = null)
100 | {
101 | return $this->tempName.$extension;
102 | }
103 |
104 | public function isUseJavaInstalled(): bool
105 | {
106 | return $this->isUseJavaInstalled;
107 | }
108 |
109 | public function setIsUseJavaInstalled(bool $isUseJavaInstalled)
110 | {
111 | $this->isUseJavaInstalled = $isUseJavaInstalled;
112 | return $this;
113 | }
114 |
115 | public function setJavaPath($javaPath): self {
116 | $this->javaPath = $javaPath;
117 | return $this;
118 | }
119 |
120 | public function getJavaPath(): string {
121 | return $this->javaPath;
122 | }
123 |
124 | public function setjSignPdfJarPath($jSignPdfJarPath)
125 | {
126 | $this->jSignPdfJarPath = $jSignPdfJarPath;
127 | return $this;
128 | }
129 |
130 | public function getjSignPdfJarPath()
131 | {
132 | return $this->jSignPdfJarPath;
133 | }
134 |
135 | public function isOutputTypeBase64(): bool
136 | {
137 | return $this->isOutputTypeBase64;
138 | }
139 |
140 | public function setIsOutputTypeBase64(bool $isOutputTypeBase64)
141 | {
142 | $this->isOutputTypeBase64 = $isOutputTypeBase64;
143 | return $this;
144 | }
145 |
146 | public function getTempPdfPath()
147 | {
148 | return $this->getTempPath() . $this->getTempName('.pdf');
149 | }
150 |
151 | public function getTempPdfSignedPath()
152 | {
153 | return $this->getPathPdfSigned() . $this->getTempName('_signed.pdf');
154 | }
155 |
156 | public function getTempCertificatePath()
157 | {
158 | return $this->getTempPath() . $this->getTempName('.pfx');
159 | }
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/src/Sign/JSignService.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class JSignService
13 | {
14 | private $fileService;
15 |
16 | public function __construct()
17 | {
18 | $this->fileService = JSignFileService::instance();
19 | }
20 |
21 | public function sign(JSignParam $params)
22 | {
23 | try {
24 | $this->validation($params);
25 |
26 | $commandSign = $this->commandSign($params);
27 | exec($commandSign, $output);
28 |
29 | $out = json_encode($output);
30 | $messageSuccess = "Finished: Signature succesfully created.";
31 | $isSigned = strpos($out, $messageSuccess) !== false;
32 |
33 | $this->throwIf(!$isSigned, "Error to sign PDF. $out");
34 |
35 | $fileSigned = $this->fileService->contentFile(
36 | $params->getTempPdfSignedPath(),
37 | $params->isOutputTypeBase64()
38 | );
39 |
40 | $this->fileService->deleteTempFiles(
41 | $params->getTempPath(),
42 | $params->getTempName()
43 | );
44 |
45 | return $fileSigned;
46 | } catch (Throwable $e) {
47 | if ($params->getTempPath())
48 | $this->fileService->deleteTempFiles($params->getTempPath(), $params->getTempName());
49 |
50 | throw new Exception($e->getMessage());
51 | }
52 | }
53 |
54 | /**
55 | * JSignPdf don't works as well at CLI interfaceif the password have
56 | * unicode chars. As workaround, I changed the password certificate in
57 | * memory.
58 | */
59 | private function repackCertificateIfPasswordIsUnicode(JSignParam $params, $cert, $pkey)
60 | {
61 | if (!mb_detect_encoding($params->getPassword(), 'ASCII', true)) {
62 | $password = md5(microtime());
63 | $newCert = $this->exportToPkcs12($cert, $pkey, $password);
64 | $params->setPassword($password);
65 | $params->setCertificate($newCert);
66 | }
67 | }
68 |
69 | public function getVersion(JSignParam $params)
70 | {
71 | $java = $this->javaCommand($params);
72 | $jSignPdf = $params->getjSignPdfJarPath();
73 | if (!$jSignPdf && class_exists('JSignPDF\JSignPDFBin\JSignPdfPathService')) {
74 | $jSignPdf = \JSignPDF\JSignPDFBin\JSignPdfPathService::jSignPdfJarPath();
75 | }
76 | $this->throwIf(!file_exists($jSignPdf), 'Jar of JSignPDF not found on path: '. $jSignPdf);
77 |
78 | $command = "$java -jar $jSignPdf --version 2>&1";
79 | \exec($command, $output);
80 | $lastRow = end($output);
81 | if (empty($output) || strpos($lastRow, 'version') === false) {
82 | return '';
83 | }
84 | return explode('version ', $lastRow)[1];
85 | }
86 |
87 | private function validation(JSignParam $params)
88 | {
89 | $this->throwIf(empty($params->getTempPath()) || !is_writable($params->getTempPath()), 'Temp Path is invalid or has not permission to writable.');
90 | $this->throwIf(empty($params->getPdf()), 'PDF is Empty or Invalid.');
91 | $this->throwIf(empty($params->getCertificate()), 'Certificate is Empty or Invalid.');
92 | $this->throwIf(empty($params->getPassword()), 'Certificate Password is Empty.');
93 | $this->throwIf(!$this->isPasswordCertificateValid($params), 'Certificate Password Invalid.');
94 | $this->throwIf($this->isExpiredCertificate($params), 'Certificate expired.');
95 | if ($params->isUseJavaInstalled()) {
96 | $javaVersion = exec("java -version 2>&1");
97 | $hasJavaVersion = strpos($javaVersion, 'not found') === false;
98 | $this->throwIf(!$hasJavaVersion, 'Java not installed, set the flag "isUseJavaInstalled" as false or install java.');
99 | }
100 | }
101 |
102 | private function storeTempFiles(JSignParam $params)
103 | {
104 | $pdf = $this->fileService->storeFile(
105 | $params->getTempPath(),
106 | $params->getTempName('.pdf'),
107 | $params->getPdf()
108 | );
109 |
110 | $certificate = $this->fileService->storeFile(
111 | $params->getTempPath(),
112 | $params->getTempName('.pfx'),
113 | $params->getCertificate()
114 | );
115 |
116 | return [$pdf, $certificate];
117 | }
118 |
119 | private function commandSign(JSignParam $params)
120 | {
121 | list ($pdf, $certificate) = $this->storeTempFiles($params);
122 | $java = $this->javaCommand($params);
123 | $jSignPdf = $params->getjSignPdfJarPath();
124 | if (!$jSignPdf && class_exists('JSignPDF\JSignPDFBin\JSignPdfPathService')) {
125 | $jSignPdf = \JSignPDF\JSignPDFBin\JSignPdfPathService::jSignPdfJarPath();
126 | }
127 | $this->throwIf(!file_exists($jSignPdf), 'Jar of JSignPDF not found on path: '. $jSignPdf);
128 |
129 | $password = escapeshellarg($params->getPassword());
130 | return "$java -Duser.language=en -jar $jSignPdf $pdf -ksf $certificate -ksp {$password} {$params->getJSignParameters()} -d {$params->getPathPdfSigned()} 2>&1";
131 | }
132 |
133 | private function javaCommand(JSignParam $params)
134 | {
135 | if ($params->isUseJavaInstalled()) {
136 | return 'java';
137 | }
138 | if ($params->getJavaPath()) {
139 | return $params->getJavaPath();
140 | }
141 | if (!class_exists('JSignPDF\JSignPDFBin\JavaCommandService')) {
142 | throw new Exception("JSignPDF not found, install manually or run composer require jsignpdf/jsignpdf-bin", 1);
143 | }
144 | return \JSignPDF\JSignPDFBin\JavaCommandService::instance()->command($params->isUseJavaInstalled());
145 | }
146 |
147 | private function throwIf($condition, $message)
148 | {
149 | if ($condition)
150 | throw new Exception($message);
151 | }
152 |
153 | private function isPasswordCertificateValid(JSignParam $params)
154 | {
155 | return $this->pkcs12Read($params);
156 | }
157 |
158 | /**
159 | * Prevent error to read certificate generated with old version of
160 | * openssl and using a newest version of openssl.
161 | *
162 | * To check the password is necessary to repack the certificate using
163 | * openssl command. If the command don't exists, will consider that
164 | * the password is invalid.
165 | *
166 | * Reference:
167 | *
168 | * https://github.com/php/php-src/issues/12128
169 | * https://www.php.net/manual/en/function.openssl-pkcs12-read.php#128992
170 | */
171 | private function pkcs12Read(JSignParam $params)
172 | {
173 | $certificate = $params->getCertificate();
174 | $password = $params->getPassword();
175 | if (openssl_pkcs12_read($certificate, $certInfo, $password)) {
176 | $this->repackCertificateIfPasswordIsUnicode($params, $certInfo['cert'], $certInfo['pkey']);
177 | return $certInfo;
178 | }
179 | $msg = openssl_error_string();
180 | if ($msg === 'error:0308010C:digital envelope routines::unsupported') {
181 | if (!shell_exec('openssl version')) {
182 | return [];
183 | }
184 | $tempPassword = tempnam(sys_get_temp_dir(), 'pfx');
185 | $tempEncriptedOriginal = tempnam(sys_get_temp_dir(), 'original');
186 | $tempEncriptedRepacked = tempnam(sys_get_temp_dir(), 'repacked');
187 | $tempDecrypted = tempnam(sys_get_temp_dir(), 'decripted');
188 | file_put_contents($tempPassword, $password);
189 | file_put_contents($tempEncriptedOriginal, $certificate);
190 | shell_exec(<<setCertificate($certificateRepacked);
197 | unlink($tempPassword);
198 | unlink($tempEncriptedOriginal);
199 | unlink($tempEncriptedRepacked);
200 | unlink($tempDecrypted);
201 | openssl_pkcs12_read($certificateRepacked, $certInfo, $password);
202 | $this->repackCertificateIfPasswordIsUnicode($params, $certInfo['cert'], $certInfo['pkey']);
203 | return $certInfo;
204 | }
205 | return [];
206 | }
207 |
208 | private function exportToPkcs12(\OpenSSLCertificate|string $certificate, \OpenSSLAsymmetricKey|\OpenSSLCertificate|string $privateKey, string $password)
209 | {
210 | $certContent = null;
211 | openssl_pkcs12_export(
212 | $certificate,
213 | $certContent,
214 | $privateKey,
215 | $password,
216 | );
217 | return $certContent;
218 | }
219 |
220 | private function isExpiredCertificate(JSignParam $params)
221 | {
222 | $certInfo = $this->pkcs12Read($params);
223 | $certificate = openssl_x509_parse($certInfo['cert']);
224 | $dateCert = date_create()->setTimestamp($certificate['validTo_time_t']);
225 | return $dateCert <= date_create();
226 | }
227 | }
228 |
--------------------------------------------------------------------------------
/tests/Builder/JSignParamBuilder.php:
--------------------------------------------------------------------------------
1 | params = JSignParam::instance();
14 | }
15 |
16 | public static function instance()
17 | {
18 | return new self();
19 | }
20 |
21 | public function getParams()
22 | {
23 | return $this->params;
24 | }
25 |
26 | public function withDefault()
27 | {
28 | $params = JSignParam::instance();
29 | $params->setCertificate(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR. '..' . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'certificado.pfx'));
30 | $params->setPdf(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR. '..' . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'pdf-test.pdf'));
31 | $params->setPassword('123');
32 | return $params;
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/tests/JSignPDFTest.php:
--------------------------------------------------------------------------------
1 |
23 | */
24 | class JSignPDFTest extends TestCase
25 | {
26 | private $service;
27 |
28 | protected function setUp(): void
29 | {
30 | global $mockExec;
31 | $mockExec = null;
32 | $this->service = new JSignService();
33 | }
34 |
35 | private function getNewCert($password)
36 | {
37 | $privateKey = openssl_pkey_new([
38 | 'private_key_bits' => 2048,
39 | 'private_key_type' => OPENSSL_KEYTYPE_RSA,
40 | ]);
41 |
42 | $csrNames = ['commonName' => 'Jhon Doe'];
43 |
44 | $csr = openssl_csr_new($csrNames, $privateKey, ['digest_alg' => 'sha256']);
45 | $x509 = openssl_csr_sign($csr, null, $privateKey, $days = 365, ['digest_alg' => 'sha256']);
46 |
47 | openssl_x509_export($x509, $rootCertificate);
48 | openssl_pkey_export($privateKey, $rootPrivateKey);
49 |
50 | $privateKey = openssl_pkey_new([
51 | 'private_key_bits' => 2048,
52 | 'private_key_type' => OPENSSL_KEYTYPE_RSA,
53 | ]);
54 | $temporaryFile = tempnam(sys_get_temp_dir(), 'cfg');
55 | $csr = openssl_csr_new($csrNames, $privateKey);
56 | $x509 = openssl_csr_sign($csr, $rootCertificate, $rootPrivateKey, 365);
57 | $certContent = null;
58 | openssl_pkcs12_export(
59 | $x509,
60 | $certContent,
61 | $privateKey,
62 | $password,
63 | );
64 | return $certContent;
65 | }
66 |
67 | public function testSignSuccess()
68 | {
69 | if (!class_exists('JSignPDF\JSignPDFBin\JavaCommandService')) {
70 | $this->markTestSkipped('Install jsignpdf/jsignpdf-bin');
71 | }
72 | $params = JSignParamBuilder::instance()->withDefault();
73 | $params->setCertificate($this->getNewCert($params->getPassword()));
74 | $fileSigned = $this->service->sign($params);
75 | $this->assertNotNull($fileSigned);
76 | }
77 |
78 | /**
79 | * @dataProvider providerSignUsingDifferentPasswords
80 | */
81 | public function testSignUsingDifferentPasswords(string $password)
82 | {
83 | global $mockExec;
84 | if (!class_exists('JSignPDF\JSignPDFBin\JavaCommandService')) {
85 | $this->markTestSkipped('Install jsignpdf/jsignpdf-bin');
86 | }
87 | $params = JSignParamBuilder::instance()->withDefault();
88 | $params->setCertificate($this->getNewCert($password));
89 | $params->setPassword($password);
90 | $mockExec = 'Finished: Signature succesfully created.';
91 | $path = $params->getTempPdfSignedPath();
92 | file_put_contents($path, 'dummy');
93 | $fileSigned = $this->service->sign($params);
94 | $this->assertNotNull($fileSigned);
95 | }
96 |
97 | public function providerSignUsingDifferentPasswords()
98 | {
99 | return [
100 | ["with ' quote"],
101 | ['with ( parentheis )'],
102 | ['with $ dollar'],
103 | ['with 😃 unicode'],
104 | ];
105 | }
106 |
107 | public function testCertificateExpired()
108 | {
109 | if (!class_exists('JSignPDF\JSignPDFBin\JavaCommandService')) {
110 | $this->markTestSkipped('Install jsignpdf/jsignpdf-bin');
111 | }
112 | $this->expectExceptionMessage('Certificate expired.');
113 | $params = JSignParamBuilder::instance()->withDefault();
114 | $fileSigned = $this->service->sign($params);
115 | $this->assertNotNull($fileSigned);
116 | }
117 |
118 | public function testSignError()
119 | {
120 | $this->expectException(Exception::class);
121 | $params = JSignParamBuilder::instance();
122 | $this->service->sign($params->getParams());
123 | }
124 |
125 |
126 | public function testWithWhenResponseIsBase64()
127 | {
128 | if (!class_exists('JSignPDF\JSignPDFBin\JavaCommandService')) {
129 | $this->markTestSkipped('Install jsignpdf/jsignpdf-bin');
130 | }
131 | $params = JSignParamBuilder::instance()->withDefault()->setIsOutputTypeBase64(true);
132 | $params->setCertificate($this->getNewCert($params->getPassword()));
133 | $fileSigned = $this->service->sign($params);
134 | $this->assertTrue(base64_decode($fileSigned, true) == true);
135 | }
136 |
137 | public function testSignWhenCertificateIsNull()
138 | {
139 | $this->expectExceptionMessage('Certificate is Empty or Invalid.');
140 | $params = JSignParamBuilder::instance()->withDefault()->setCertificate(null);
141 | $this->service->sign($params);
142 | }
143 |
144 | public function testSignWhenPdfIsNull()
145 | {
146 | $this->expectExceptionMessage('PDF is Empty or Invalid.');
147 | $params = JSignParamBuilder::instance()->withDefault()->setPdf(null);
148 | $this->service->sign($params);
149 | }
150 |
151 | public function testSignWhenPasswordIsNull()
152 | {
153 | $this->expectExceptionMessage('Certificate Password is Empty.');
154 | $params = JSignParamBuilder::instance()->withDefault()->setPassword(null);
155 | $this->service->sign($params);
156 | }
157 |
158 | public function testSignWhenTempPathIsInvalid()
159 | {
160 | $this->expectExceptionMessage('Temp Path is invalid or has not permission to writable.');
161 | $params = JSignParamBuilder::instance()->withDefault()->setTempPath(null);
162 | $this->service->sign($params);
163 | }
164 |
165 | public function testSignWhenPasswordIsInvalid()
166 | {
167 | $this->expectExceptionMessage('Certificate Password Invalid.');
168 | $params = JSignParamBuilder::instance()->withDefault()->setPassword('123456');
169 | $this->service->sign($params);
170 | }
171 |
172 | public function testJSignPDFNotFound()
173 | {
174 | $this->expectExceptionMessageMatches('/Jar of JSignPDF not found on path/');
175 | $params = JSignParamBuilder::instance()->withDefault()->setjSignPdfJarPath('invalid_path');
176 | $params->setCertificate($this->getNewCert($params->getPassword()));
177 | $this->service->getVersion($params);
178 | }
179 |
180 | public function testSignWhenJavaNotFound()
181 | {
182 | $javaVersion = exec("java -version 2>&1");
183 | $hasJavaVersion = strpos($javaVersion, 'not found') === false;
184 | if ($hasJavaVersion) {
185 | $this->markTestSkipped('Java is already installed, impossible to test if it is not installed');
186 | }
187 | $this->expectExceptionMessage('Java not installed, set the flag "isUseJavaInstalled" as false or install java.');
188 | $params = JSignParamBuilder::instance()->withDefault()->setIsUseJavaInstalled(true);
189 | $params->setCertificate($this->getNewCert($params->getPassword()));
190 | $this->service->sign($params);
191 | }
192 |
193 | public function testGetVersion()
194 | {
195 | $params = JSignParamBuilder::instance()->withDefault();
196 | $version = $this->service->getVersion($params);
197 | $this->assertNotEmpty($version);
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/tests/resources/certificado.pfx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JSignPdf/jsignpdf-php/5e0a02873fad59e28f464261c11c69bfe5766304/tests/resources/certificado.pfx
--------------------------------------------------------------------------------
/tests/resources/pdf-error-test.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JSignPdf/jsignpdf-php/5e0a02873fad59e28f464261c11c69bfe5766304/tests/resources/pdf-error-test.pdf
--------------------------------------------------------------------------------
/tests/resources/pdf-test.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JSignPdf/jsignpdf-php/5e0a02873fad59e28f464261c11c69bfe5766304/tests/resources/pdf-test.pdf
--------------------------------------------------------------------------------
/tmp/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------