diff options
22 files changed, 2640 insertions, 50 deletions
diff --git a/app/Http/RequestHandlers/ReportGenerate.php b/app/Http/RequestHandlers/ReportGenerate.php index eae61fb344..3f9e6e1da6 100644 --- a/app/Http/RequestHandlers/ReportGenerate.php +++ b/app/Http/RequestHandlers/ReportGenerate.php @@ -128,19 +128,6 @@ class ReportGenerate implements RequestHandlerInterface return $response; case 'PDF': - if (PHP_VERSION_ID >= 70400) { - $pr = 'https://github.com/tecnickcom/TCPDF/pull/137'; - $error = 'PDF reports do not currently work on PHP >= 7.4'; - $error .= '<br>'; - $error .= 'Waiting for <a href="' . $pr . '" class="alert-link">' . $pr . '</a>'; - - return $this->viewResponse('errors/unhandled-exception', [ - 'error' => $error, - 'title' => 'TCPDF error', - 'tree' => $tree, - ]); - } - ob_start(); new ReportParserGenerate($xml_filename, new PdfRenderer(), $variables, $tree, $data_filesystem); $pdf = ob_get_clean(); diff --git a/composer.json b/composer.json index dd76b33b29..80a18a5c5b 100644 --- a/composer.json +++ b/composer.json @@ -41,6 +41,7 @@ "ext-xml": "*", "ext-zip": "*", "aura/router": "~3.1", + "cweagans/composer-patches": "~1.6", "doctrine/dbal": "~2.9", "ezyang/htmlpurifier": "~4.10", "fig/http-message-util": "^1.1", @@ -166,8 +167,12 @@ "webtrees:po": "Update the language (webtrees.pot, *.po)" }, "extra": { - "branch-alias": { - "dev-master": "2.0-dev" + "composer-exit-on-patch-failure": true, + "enable-patching": true, + "patches": { + "tecnickcom/tcpdf": { + "PR #137": "https://github.com/tecnickcom/TCPDF/commit/0c73a9c580246b6f4e2eea196f0e4759f79ad632.patch" + } } } } diff --git a/composer.lock b/composer.lock index 90e080c89f..3f68cea5d5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5540a9c2cf0a60b0c2ea9a13185e5586", + "content-hash": "e22273a27154a3154f8c05d33ac2f5f2", "packages": [ { "name": "aura/router", @@ -56,6 +56,50 @@ "time": "2017-03-02T16:34:47+00:00" }, { + "name": "cweagans/composer-patches", + "version": "1.6.7", + "source": { + "type": "git", + "url": "https://github.com/cweagans/composer-patches.git", + "reference": "2e6f72a2ad8d59cd7e2b729f218bf42adb14f590" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/2e6f72a2ad8d59cd7e2b729f218bf42adb14f590", + "reference": "2e6f72a2ad8d59cd7e2b729f218bf42adb14f590", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": ">=5.3.0" + }, + "require-dev": { + "composer/composer": "~1.0", + "phpunit/phpunit": "~4.6" + }, + "type": "composer-plugin", + "extra": { + "class": "cweagans\\Composer\\Patches" + }, + "autoload": { + "psr-4": { + "cweagans\\Composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Cameron Eagans", + "email": "me@cweagans.net" + } + ], + "description": "Provides a way to patch Composer packages.", + "time": "2019-08-29T20:11:49+00:00" + }, + { "name": "doctrine/cache", "version": "1.10.0", "source": { @@ -4219,16 +4263,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.2", + "version": "4.3.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" + "reference": "2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62", + "reference": "2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62", "shasum": "" }, "require": { @@ -4266,7 +4310,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-09-12T14:27:41+00:00" + "time": "2019-12-20T13:40:23+00:00" }, { "name": "phpdocumentor/type-resolver", diff --git a/tests/app/Module/AhnentafelReportModuleTest.php b/tests/app/Module/AhnentafelReportModuleTest.php index f2518f4fe2..480b4decb1 100644 --- a/tests/app/Module/AhnentafelReportModuleTest.php +++ b/tests/app/Module/AhnentafelReportModuleTest.php @@ -108,16 +108,9 @@ class AhnentafelReportModuleTest extends TestCase $this->assertStringEndsWith('>', $html); ob_start(); - try { - if (PHP_VERSION_ID >= 70400) { - $this->expectException(Notice::class); - $this->expectExceptionMessage('Trying to access array offset on value of type int'); - } + new ReportParserGenerate($xml, new PdfRenderer(), $vars, $tree, $data_filesystem); + $pdf = ob_get_clean(); - new ReportParserGenerate($xml, new PdfRenderer(), $vars, $tree, $data_filesystem); - } finally { - $pdf = ob_get_clean(); - } $this->assertStringStartsWith('%PDF', $pdf); $this->assertStringEndsWith("%%EOF\n", $pdf); } diff --git a/tests/app/Module/DescendancyReportModuleTest.php b/tests/app/Module/DescendancyReportModuleTest.php index 2c17e1b407..cc8ca16a6f 100644 --- a/tests/app/Module/DescendancyReportModuleTest.php +++ b/tests/app/Module/DescendancyReportModuleTest.php @@ -104,16 +104,9 @@ class DescendancyReportModuleTest extends TestCase $this->assertStringEndsWith('>', $html); ob_start(); - try { - if (PHP_VERSION_ID >= 70400) { - $this->expectException(Notice::class); - $this->expectExceptionMessage('Trying to access array offset on value of type int'); - } + new ReportParserGenerate($xml, new PdfRenderer(), $vars, $tree, $data_filesystem); + $pdf = ob_get_clean(); - new ReportParserGenerate($xml, new PdfRenderer(), $vars, $tree, $data_filesystem); - } finally { - $pdf = ob_get_clean(); - } $this->assertStringStartsWith('%PDF', $pdf); $this->assertStringEndsWith("%%EOF\n", $pdf); } diff --git a/tests/app/Module/IndividualFamiliesReportModuleTest.php b/tests/app/Module/IndividualFamiliesReportModuleTest.php index e22560a75e..6a3bb50d83 100644 --- a/tests/app/Module/IndividualFamiliesReportModuleTest.php +++ b/tests/app/Module/IndividualFamiliesReportModuleTest.php @@ -109,16 +109,9 @@ class IndividualFamiliesReportModuleTest extends TestCase $this->assertStringEndsWith('>', $html); ob_start(); - try { - if (PHP_VERSION_ID >= 70400) { - $this->expectException(Notice::class); - $this->expectExceptionMessage('Trying to access array offset on value of type int'); - } + new ReportParserGenerate($xml, new PdfRenderer(), $vars, $tree, $data_filesystem); + $pdf = ob_get_clean(); - new ReportParserGenerate($xml, new PdfRenderer(), $vars, $tree, $data_filesystem); - } finally { - $pdf = ob_get_clean(); - } $this->assertStringStartsWith('%PDF', $pdf); $this->assertStringEndsWith("%%EOF\n", $pdf); } diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 034a05d380..a5de7c4bc6 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'cweagans\\Composer\\' => array($vendorDir . '/cweagans/composer-patches/src'), 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 5f0e1f6ec8..c2c037b155 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -25,6 +25,10 @@ class ComposerStaticInit00d031cf6ee8ec5ce4becbbe7ea38e99 ); public static $prefixLengthsPsr4 = array ( + 'c' => + array ( + 'cweagans\\Composer\\' => 18, + ), 'S' => array ( 'Symfony\\Polyfill\\Php72\\' => 23, @@ -122,6 +126,10 @@ class ComposerStaticInit00d031cf6ee8ec5ce4becbbe7ea38e99 ); public static $prefixDirsPsr4 = array ( + 'cweagans\\Composer\\' => + array ( + 0 => __DIR__ . '/..' . '/cweagans/composer-patches/src', + ), 'Symfony\\Polyfill\\Php72\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php72', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index a77f1203d5..1d74894917 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -51,6 +51,52 @@ ] }, { + "name": "cweagans/composer-patches", + "version": "1.6.7", + "version_normalized": "1.6.7.0", + "source": { + "type": "git", + "url": "https://github.com/cweagans/composer-patches.git", + "reference": "2e6f72a2ad8d59cd7e2b729f218bf42adb14f590" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/2e6f72a2ad8d59cd7e2b729f218bf42adb14f590", + "reference": "2e6f72a2ad8d59cd7e2b729f218bf42adb14f590", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": ">=5.3.0" + }, + "require-dev": { + "composer/composer": "~1.0", + "phpunit/phpunit": "~4.6" + }, + "time": "2019-08-29T20:11:49+00:00", + "type": "composer-plugin", + "extra": { + "class": "cweagans\\Composer\\Patches" + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "cweagans\\Composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Cameron Eagans", + "email": "me@cweagans.net" + } + ], + "description": "Provides a way to patch Composer packages." + }, + { "name": "doctrine/cache", "version": "1.10.0", "version_normalized": "1.10.0.0", @@ -3459,6 +3505,11 @@ }, "time": "2019-09-20T09:35:01+00:00", "type": "library", + "extra": { + "patches_applied": { + "PR #137": "https://github.com/tecnickcom/TCPDF/commit/0c73a9c580246b6f4e2eea196f0e4759f79ad632.patch" + } + }, "installation-source": "dist", "autoload": { "classmap": [ diff --git a/vendor/cweagans/composer-patches/.editorconfig b/vendor/cweagans/composer-patches/.editorconfig new file mode 100644 index 0000000000..8e82594112 --- /dev/null +++ b/vendor/cweagans/composer-patches/.editorconfig @@ -0,0 +1,11 @@ +# This is the top-most .editorconfig file; do not search in parent directories. +root = true + +# All files. +[*] +end_of_line = LF +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/vendor/cweagans/composer-patches/.gitignore b/vendor/cweagans/composer-patches/.gitignore new file mode 100644 index 0000000000..48b8bf9072 --- /dev/null +++ b/vendor/cweagans/composer-patches/.gitignore @@ -0,0 +1 @@ +vendor/ diff --git a/vendor/cweagans/composer-patches/LICENSE.md b/vendor/cweagans/composer-patches/LICENSE.md new file mode 100644 index 0000000000..d0dad3df74 --- /dev/null +++ b/vendor/cweagans/composer-patches/LICENSE.md @@ -0,0 +1,9 @@ +Copyright 2013 Cameron Eagans + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/cweagans/composer-patches/README.md b/vendor/cweagans/composer-patches/README.md new file mode 100644 index 0000000000..972694028d --- /dev/null +++ b/vendor/cweagans/composer-patches/README.md @@ -0,0 +1,178 @@ +# composer-patches + +Simple patches plugin for Composer. Applies a patch from a local or remote file to any package required with composer. + +Note that the 1.x versions of Composer Patches are supported on a best-effort +basis due to the imminent release of 2.0.0. You may still be interested in +using 1.x if you need Composer to cooperate with earlier PHP versions. No new +features will be added to 1.x releases, but any security or bug fixes will +still be accepted. + +## Usage + +Example composer.json: + +```json +{ + "require": { + "cweagans/composer-patches": "~1.0", + "drupal/drupal": "~8.2" + }, + "config": { + "preferred-install": "source" + }, + "extra": { + "patches": { + "drupal/drupal": { + "Add startup configuration for PHP server": "https://www.drupal.org/files/issues/add_a_startup-1543858-30.patch" + } + } + } +} + +``` + +## Using an external patch file + +Instead of a patches key in your root composer.json, use a patches-file key. + +```json +{ + "require": { + "cweagans/composer-patches": "~1.0", + "drupal/drupal": "~8.2" + }, + "config": { + "preferred-install": "source" + }, + "extra": { + "patches-file": "local/path/to/your/composer.patches.json" + } +} + +``` + +Then your `composer.patches.json` should look like this: + +``` +{ + "patches": { + "vendor/project": { + "Patch title": "http://example.com/url/to/patch.patch" + } + } +} +``` + +## Allowing patches to be applied from dependencies + +If your project doesn't supply any patches of its own, but you still want to accept patches from dependencies, you must have the following in your composer file: + +```json +{ + "require": { + "cweagans/composer-patches": "^1.5.0" + }, + "extra": { + "enable-patching": true + } +} +``` + +If you do have a `patches` section in your composer file that defines your own set of patches then the `enable-patching` setting will be ignored and patches from dependencies will always be applied. + +## Ignoring patches + +There may be situations in which you want to ignore a patch supplied by a dependency. For example: + +- You use a different more recent version of a dependency, and now a patch isn't applying. +- You have a more up to date patch than the dependency, and want to use yours instead of theirs. +- A dependency's patch adds a feature to a project that you don't need. +- Your patches conflict with a dependency's patches. + +```json +{ + "require": { + "cweagans/composer-patches": "~1.0", + "drupal/drupal": "~8.2", + "drupal/lightning": "~8.1" + }, + "config": { + "preferred-install": "source" + }, + "extra": { + "patches": { + "drupal/drupal": { + "Add startup configuration for PHP server": "https://www.drupal.org/files/issues/add_a_startup-1543858-30.patch" + } + }, + "patches-ignore": { + "drupal/lightning": { + "drupal/panelizer": { + "This patch has known conflicts with our Quick Edit integration": "https://www.drupal.org/files/issues/2664682-49.patch" + } + } + } + } +} +``` + +## Allowing to force the patch level (-pX) + +Some situations require to force the patchLevel used to apply patches on a particular package. +Its useful for packages like drupal/core which packages only a subdir of the original upstream project on which patches are based. + +```json +{ + "extra": { + "patchLevel": { + "drupal/core": "-p2" + } + } +} +``` + +## Using patches from HTTP URLs + +Composer [blocks](https://getcomposer.org/doc/06-config.md#secure-http) you from downloading anything from HTTP URLs, you can disable this for your project by adding a `secure-http` setting in the config section of your `composer.json`. Note that the `config` section should be under the root of your `composer.json`. + +```json +{ + "config": { + "secure-http": false + } +} +``` + +However, it's always advised to setup HTTPS to prevent MITM code injection. + +## Patches containing modifications to composer.json files + +Because patching occurs _after_ Composer calculates dependencies and installs packages, changes to an underlying dependency's `composer.json` file introduced in a patch will have _no effect_ on installed packages. + +If you need to modify a dependency's `composer.json` or its underlying dependencies, you cannot use this plugin. Instead, you must do one of the following: +- Work to get the underlying issue resolved in the upstream package. +- Fork the package and [specify your fork as the package repository](https://getcomposer.org/doc/05-repositories.md#vcs) in your root `composer.json` +- Specify compatible package version requirements in your root `composer.json` + +## Error handling + +If a patch cannot be applied (hunk failed, different line endings, etc.) a message will be shown and the patch will be skipped. + +To enforce throwing an error and stopping package installation/update immediately, you have two available options: + +1. Add `"composer-exit-on-patch-failure": true` option to the `extra` section of your composer.json file. +1. Export `COMPOSER_EXIT_ON_PATCH_FAILURE=1` + +By default, failed patches are skipped. + +## Difference between this and netresearch/composer-patches-plugin + +- This plugin is much more simple to use and maintain +- This plugin doesn't require you to specify which package version you're patching +- This plugin is easy to use with Drupal modules (which don't use semantic versioning). +- This plugin will gather patches from all dependencies and apply them as if they were in the root composer.json + +## Credits + +A ton of this code is adapted or taken straight from https://github.com/jpstacey/composer-patcher, which is abandoned in favor of https://github.com/netresearch/composer-patches-plugin, which is (IMHO) overly complex and difficult to use. diff --git a/vendor/cweagans/composer-patches/composer.json b/vendor/cweagans/composer-patches/composer.json new file mode 100644 index 0000000000..1cdcd76625 --- /dev/null +++ b/vendor/cweagans/composer-patches/composer.json @@ -0,0 +1,30 @@ +{ + "name": "cweagans/composer-patches", + "description": "Provides a way to patch Composer packages.", + "minimum-stability": "dev", + "license": "BSD-3-Clause", + "type": "composer-plugin", + "extra": { + "class": "cweagans\\Composer\\Patches" + }, + "authors": [ + { + "name": "Cameron Eagans", + "email": "me@cweagans.net" + } + ], + "require": { + "php": ">=5.3.0", + "composer-plugin-api": "^1.0" + }, + "require-dev": { + "composer/composer": "~1.0", + "phpunit/phpunit": "~4.6" + }, + "autoload": { + "psr-4": {"cweagans\\Composer\\": "src"} + }, + "autoload-dev": { + "psr-4": {"cweagans\\Composer\\Tests\\": "tests"} + } +} diff --git a/vendor/cweagans/composer-patches/composer.lock b/vendor/cweagans/composer-patches/composer.lock new file mode 100644 index 0000000000..2ca41b42d1 --- /dev/null +++ b/vendor/cweagans/composer-patches/composer.lock @@ -0,0 +1,1564 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "a2cd6826c202b7ebefe3050efc2a7b7f", + "content-hash": "0ed9361502c0f5f22a5b440c16640193", + "packages": [], + "packages-dev": [ + { + "name": "composer/composer", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "a54f84f05f915c6d42bed94de0cdcb4406a4707b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/f2d606ae0c705907d8bfa1c6f884bced1255b827", + "reference": "a54f84f05f915c6d42bed94de0cdcb4406a4707b", + "shasum": "" + }, + "require": { + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.0", + "justinrainbow/json-schema": "^1.4.4", + "php": ">=5.3.2", + "seld/cli-prompt": "~1.0", + "seld/jsonlint": "~1.0", + "seld/phar-utils": "~1.0", + "symfony/console": "~2.5", + "symfony/filesystem": "~2.5", + "symfony/finder": "~2.2", + "symfony/process": "~2.1" + }, + "require-dev": { + "phpunit/phpunit": "~4.5|^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0|~3.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives, and allows gzip compression of all internet traffic" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Composer": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "time": "2015-10-13 13:09:04" + }, + { + "name": "composer/semver", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com" + }, + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2015-09-21 09:42:36" + }, + { + "name": "composer/spdx-licenses", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "b2dbc76d1c3f81f33857cdd49c0be6ce7b87897d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/022fc25ca664f612b1e7007e0d87642ef489f000", + "reference": "b2dbc76d1c3f81f33857cdd49c0be6ce7b87897d", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "time": "2015-10-05 11:33:06" + }, + { + "name": "doctrine/instantiator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "justinrainbow/json-schema", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "a4bee9f4b344b66e0a0d96c7afae1e92edf385fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/a4bee9f4b344b66e0a0d96c7afae1e92edf385fe", + "reference": "a4bee9f4b344b66e0a0d96c7afae1e92edf385fe", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "json-schema/json-schema-test-suite": "1.1.0", + "phpdocumentor/phpdocumentor": "~2", + "phpunit/phpunit": "~3.7" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2015-09-08 22:28:04" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2015-02-03 12:10:50" + }, + { + "name": "phpspec/prophecy", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4f9b1eaf0a7da77c362f8d91cbc68ab1f4718d62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b02221e42163be673f9b44a0bc92a8b4907a7c6d", + "reference": "4f9b1eaf0a7da77c362f8d91cbc68ab1f4718d62", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2015-09-22 14:49:23" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.2.x-dev", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2015-10-06 15:47:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2015-06-21 13:08:43" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21 13:50:34" + }, + { + "name": "phpunit/php-timer", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2015-06-21 08:01:12" + }, + { + "name": "phpunit/php-token-stream", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "cab6c6fefee93d7b7c3a01292a0fe0884ea66644" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/cab6c6fefee93d7b7c3a01292a0fe0884ea66644", + "reference": "cab6c6fefee93d7b7c3a01292a0fe0884ea66644", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2015-09-23 14:46:55" + }, + { + "name": "phpunit/phpunit", + "version": "4.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "be067d6105286b74272facefc2697038f8807b77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/264188ddf4d3586c80ea615f8ec8eaea34e652a1", + "reference": "be067d6105286b74272facefc2697038f8807b77", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": ">=1.0.6", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.1|~3.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.8.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2015-10-14 13:49:40" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.x-dev", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2015-10-02 06:51:40" + }, + { + "name": "sebastian/comparator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-07-26 15:48:44" + }, + { + "name": "sebastian/diff", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "6899b3e33bfbd386d88b5eea5f65f563e8793051" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "6899b3e33bfbd386d88b5eea5f65f563e8793051", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-06-22 14:15:55" + }, + { + "name": "sebastian/environment", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", + "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2015-08-03 06:14:51" + }, + { + "name": "sebastian/exporter", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "f88f8936517d54ae6d589166810877fb2015d0a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/f88f8936517d54ae6d589166810877fb2015d0a2", + "reference": "f88f8936517d54ae6d589166810877fb2015d0a2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2015-08-09 04:23:41" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12 03:26:01" + }, + { + "name": "sebastian/recursion-context", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/7ff5b1b3dcc55b8ab8ae61ef99d4730940856ee7", + "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-06-21 08:04:50" + }, + { + "name": "sebastian/version", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2015-06-21 13:59:46" + }, + { + "name": "seld/cli-prompt", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/cli-prompt.git", + "reference": "fe114c7a6ac5cb0ce76932ae4017024d9842a49c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/b27db1514f7d7bb7a366ad95d4eb2b17140a0691", + "reference": "fe114c7a6ac5cb0ce76932ae4017024d9842a49c", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\CliPrompt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", + "keywords": [ + "cli", + "console", + "hidden", + "input", + "prompt" + ], + "time": "2015-04-30 20:24:49" + }, + { + "name": "seld/jsonlint", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "863ae85c6d3ef60ca49cb12bd051c4a0648c40c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/863ae85c6d3ef60ca49cb12bd051c4a0648c40c4", + "reference": "863ae85c6d3ef60ca49cb12bd051c4a0648c40c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2015-01-04 21:18:15" + }, + { + "name": "seld/phar-utils", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phra" + ], + "time": "2015-10-13 18:44:15" + }, + { + "name": "symfony/console", + "version": "2.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "89a795226477f66745e8ea10415e769304114920" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/56cc5caf051189720b8de974e4746090aaa10d44", + "reference": "89a795226477f66745e8ea10415e769304114920", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2015-10-12 10:31:17" + }, + { + "name": "symfony/filesystem", + "version": "2.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "fc3fe52fef85e1f3e7775ffad92539e16c20e0af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/65cb36b6539b1d446527d60457248f30d045464d", + "reference": "fc3fe52fef85e1f3e7775ffad92539e16c20e0af", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2015-10-11 08:29:26" + }, + { + "name": "symfony/finder", + "version": "2.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "dcd5aaba34ca332abb7f33ec554ebd4d829cb202" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/877bb4b16ea573cc8c024e9590888fcf7eb7e0f7", + "reference": "dcd5aaba34ca332abb7f33ec554ebd4d829cb202", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2015-10-11 08:29:26" + }, + { + "name": "symfony/process", + "version": "2.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "4e1daf58b375ea7c506d525dc7801df1c9a6ebbd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe", + "reference": "4e1daf58b375ea7c506d525dc7801df1c9a6ebbd", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2015-10-11 08:29:26" + }, + { + "name": "symfony/yaml", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "8d32eb597b531eb915b4fee3dc582ade5ae1fe6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ab0314f7544d600ea7917f02cdad774358b81113", + "reference": "8d32eb597b531eb915b4fee3dc582ade5ae1fe6a", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2015-10-13 16:01:35" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.3.0" + }, + "platform-dev": [] +} diff --git a/vendor/cweagans/composer-patches/phpunit.xml.dist b/vendor/cweagans/composer-patches/phpunit.xml.dist new file mode 100644 index 0000000000..62409b3b43 --- /dev/null +++ b/vendor/cweagans/composer-patches/phpunit.xml.dist @@ -0,0 +1,18 @@ +<!--?xml version="1.0" encoding="UTF-8"?--> + +<phpunit colors="true" bootstrap="vendor/autoload.php"> + <testsuites> + <testsuite name="composer-patches"> + <directory>./tests/</directory> + </testsuite> + </testsuites> + <!-- Filter for coverage reports. --> + <filter> + <whitelist> + <directory>src/</directory> + </whitelist> + <blacklist> + <directory>vendor/</directory> + </blacklist> + </filter> +</phpunit> diff --git a/vendor/cweagans/composer-patches/src/PatchEvent.php b/vendor/cweagans/composer-patches/src/PatchEvent.php new file mode 100644 index 0000000000..31d36f89f5 --- /dev/null +++ b/vendor/cweagans/composer-patches/src/PatchEvent.php @@ -0,0 +1,70 @@ +<?php + +/** + * @file + * Dispatch events when patches are applied. + */ + +namespace cweagans\Composer; + +use Composer\EventDispatcher\Event; +use Composer\Package\PackageInterface; + +class PatchEvent extends Event { + + /** + * @var PackageInterface $package + */ + protected $package; + /** + * @var string $url + */ + protected $url; + /** + * @var string $description + */ + protected $description; + + /** + * Constructs a PatchEvent object. + * + * @param string $eventName + * @param PackageInterface $package + * @param string $url + * @param string $description + */ + public function __construct($eventName, PackageInterface $package, $url, $description) { + parent::__construct($eventName); + $this->package = $package; + $this->url = $url; + $this->description = $description; + } + + /** + * Returns the package that is patched. + * + * @return PackageInterface + */ + public function getPackage() { + return $this->package; + } + + /** + * Returns the url of the patch. + * + * @return string + */ + public function getUrl() { + return $this->url; + } + + /** + * Returns the description of the patch. + * + * @return string + */ + public function getDescription() { + return $this->description; + } + +} diff --git a/vendor/cweagans/composer-patches/src/PatchEvents.php b/vendor/cweagans/composer-patches/src/PatchEvents.php new file mode 100644 index 0000000000..ecee947682 --- /dev/null +++ b/vendor/cweagans/composer-patches/src/PatchEvents.php @@ -0,0 +1,30 @@ +<?php + +/** + * @file + * Dispatch events when patches are applied. + */ + +namespace cweagans\Composer; + +class PatchEvents { + + /** + * The PRE_PATCH_APPLY event occurs before a patch is applied. + * + * The event listener method receives a cweagans\Composer\PatchEvent instance. + * + * @var string + */ + const PRE_PATCH_APPLY = 'pre-patch-apply'; + + /** + * The POST_PATCH_APPLY event occurs after a patch is applied. + * + * The event listener method receives a cweagans\Composer\PatchEvent instance. + * + * @var string + */ + const POST_PATCH_APPLY = 'post-patch-apply'; + +} diff --git a/vendor/cweagans/composer-patches/src/Patches.php b/vendor/cweagans/composer-patches/src/Patches.php new file mode 100644 index 0000000000..31f5225ce7 --- /dev/null +++ b/vendor/cweagans/composer-patches/src/Patches.php @@ -0,0 +1,558 @@ +<?php + +/** + * @file + * Provides a way to patch Composer packages after installation. + */ + +namespace cweagans\Composer; + +use Composer\Composer; +use Composer\DependencyResolver\Operation\InstallOperation; +use Composer\DependencyResolver\Operation\UninstallOperation; +use Composer\DependencyResolver\Operation\UpdateOperation; +use Composer\DependencyResolver\Operation\OperationInterface; +use Composer\EventDispatcher\EventSubscriberInterface; +use Composer\IO\IOInterface; +use Composer\Package\AliasPackage; +use Composer\Package\PackageInterface; +use Composer\Plugin\PluginInterface; +use Composer\Installer\PackageEvents; +use Composer\Script\Event; +use Composer\Script\ScriptEvents; +use Composer\Installer\PackageEvent; +use Composer\Util\ProcessExecutor; +use Composer\Util\RemoteFilesystem; +use Symfony\Component\Process\Process; + +class Patches implements PluginInterface, EventSubscriberInterface { + + /** + * @var Composer $composer + */ + protected $composer; + /** + * @var IOInterface $io + */ + protected $io; + /** + * @var EventDispatcher $eventDispatcher + */ + protected $eventDispatcher; + /** + * @var ProcessExecutor $executor + */ + protected $executor; + /** + * @var array $patches + */ + protected $patches; + + /** + * Apply plugin modifications to composer + * + * @param Composer $composer + * @param IOInterface $io + */ + public function activate(Composer $composer, IOInterface $io) { + $this->composer = $composer; + $this->io = $io; + $this->eventDispatcher = $composer->getEventDispatcher(); + $this->executor = new ProcessExecutor($this->io); + $this->patches = array(); + $this->installedPatches = array(); + } + + /** + * Returns an array of event names this subscriber wants to listen to. + */ + public static function getSubscribedEvents() { + return array( + ScriptEvents::PRE_INSTALL_CMD => array('checkPatches'), + ScriptEvents::PRE_UPDATE_CMD => array('checkPatches'), + PackageEvents::PRE_PACKAGE_INSTALL => array('gatherPatches'), + PackageEvents::PRE_PACKAGE_UPDATE => array('gatherPatches'), + // The following is a higher weight for compatibility with + // https://github.com/AydinHassan/magento-core-composer-installer and more generally for compatibility with + // every Composer plugin which deploys downloaded packages to other locations. + // In such cases you want that those plugins deploy patched files so they have to run after + // the "composer-patches" plugin. + // @see: https://github.com/cweagans/composer-patches/pull/153 + PackageEvents::POST_PACKAGE_INSTALL => array('postInstall', 10), + PackageEvents::POST_PACKAGE_UPDATE => array('postInstall', 10), + ); + } + + /** + * Before running composer install, + * @param Event $event + */ + public function checkPatches(Event $event) { + if (!$this->isPatchingEnabled()) { + return; + } + + try { + $repositoryManager = $this->composer->getRepositoryManager(); + $localRepository = $repositoryManager->getLocalRepository(); + $installationManager = $this->composer->getInstallationManager(); + $packages = $localRepository->getPackages(); + + $extra = $this->composer->getPackage()->getExtra(); + $patches_ignore = isset($extra['patches-ignore']) ? $extra['patches-ignore'] : array(); + + $tmp_patches = $this->grabPatches(); + foreach ($packages as $package) { + $extra = $package->getExtra(); + if (isset($extra['patches'])) { + if (isset($patches_ignore[$package->getName()])) { + foreach ($patches_ignore[$package->getName()] as $package_name => $patches) { + if (isset($extra['patches'][$package_name])) { + $extra['patches'][$package_name] = array_diff($extra['patches'][$package_name], $patches); + } + } + } + $this->installedPatches[$package->getName()] = $extra['patches']; + } + $patches = isset($extra['patches']) ? $extra['patches'] : array(); + $tmp_patches = $this->arrayMergeRecursiveDistinct($tmp_patches, $patches); + } + + if ($tmp_patches == FALSE) { + $this->io->write('<info>No patches supplied.</info>'); + return; + } + + // Remove packages for which the patch set has changed. + foreach ($packages as $package) { + if (!($package instanceof AliasPackage)) { + $package_name = $package->getName(); + $extra = $package->getExtra(); + $has_patches = isset($tmp_patches[$package_name]); + $has_applied_patches = isset($extra['patches_applied']) && count($extra['patches_applied']) > 0; + if (($has_patches && !$has_applied_patches) + || (!$has_patches && $has_applied_patches) + || ($has_patches && $has_applied_patches && $tmp_patches[$package_name] !== $extra['patches_applied'])) { + $uninstallOperation = new UninstallOperation($package, 'Removing package so it can be re-installed and re-patched.'); + $this->io->write('<info>Removing package ' . $package_name . ' so that it can be re-installed and re-patched.</info>'); + $installationManager->uninstall($localRepository, $uninstallOperation); + } + } + } + } + // If the Locker isn't available, then we don't need to do this. + // It's the first time packages have been installed. + catch (\LogicException $e) { + return; + } + } + + /** + * Gather patches from dependencies and store them for later use. + * + * @param PackageEvent $event + */ + public function gatherPatches(PackageEvent $event) { + // If we've already done this, then don't do it again. + if (isset($this->patches['_patchesGathered'])) { + $this->io->write('<info>Patches already gathered. Skipping</info>', TRUE, IOInterface::VERBOSE); + return; + } + // If patching has been disabled, bail out here. + elseif (!$this->isPatchingEnabled()) { + $this->io->write('<info>Patching is disabled. Skipping.</info>', TRUE, IOInterface::VERBOSE); + return; + } + + $this->patches = $this->grabPatches(); + if (empty($this->patches)) { + $this->io->write('<info>No patches supplied.</info>'); + } + + $extra = $this->composer->getPackage()->getExtra(); + $patches_ignore = isset($extra['patches-ignore']) ? $extra['patches-ignore'] : array(); + + // Now add all the patches from dependencies that will be installed. + $operations = $event->getOperations(); + $this->io->write('<info>Gathering patches for dependencies. This might take a minute.</info>'); + foreach ($operations as $operation) { + if ($operation->getJobType() == 'install' || $operation->getJobType() == 'update') { + $package = $this->getPackageFromOperation($operation); + $extra = $package->getExtra(); + if (isset($extra['patches'])) { + if (isset($patches_ignore[$package->getName()])) { + foreach ($patches_ignore[$package->getName()] as $package_name => $patches) { + if (isset($extra['patches'][$package_name])) { + $extra['patches'][$package_name] = array_diff($extra['patches'][$package_name], $patches); + } + } + } + $this->patches = $this->arrayMergeRecursiveDistinct($this->patches, $extra['patches']); + } + // Unset installed patches for this package + if(isset($this->installedPatches[$package->getName()])) { + unset($this->installedPatches[$package->getName()]); + } + } + } + + // Merge installed patches from dependencies that did not receive an update. + foreach ($this->installedPatches as $patches) { + $this->patches = $this->arrayMergeRecursiveDistinct($this->patches, $patches); + } + + // If we're in verbose mode, list the projects we're going to patch. + if ($this->io->isVerbose()) { + foreach ($this->patches as $package => $patches) { + $number = count($patches); + $this->io->write('<info>Found ' . $number . ' patches for ' . $package . '.</info>'); + } + } + + // Make sure we don't gather patches again. Extra keys in $this->patches + // won't hurt anything, so we'll just stash it there. + $this->patches['_patchesGathered'] = TRUE; + } + + /** + * Get the patches from root composer or external file + * @return Patches + * @throws \Exception + */ + public function grabPatches() { + // First, try to get the patches from the root composer.json. + $extra = $this->composer->getPackage()->getExtra(); + if (isset($extra['patches'])) { + $this->io->write('<info>Gathering patches for root package.</info>'); + $patches = $extra['patches']; + return $patches; + } + // If it's not specified there, look for a patches-file definition. + elseif (isset($extra['patches-file'])) { + $this->io->write('<info>Gathering patches from patch file.</info>'); + $patches = file_get_contents($extra['patches-file']); + $patches = json_decode($patches, TRUE); + $error = json_last_error(); + if ($error != 0) { + switch ($error) { + case JSON_ERROR_DEPTH: + $msg = ' - Maximum stack depth exceeded'; + break; + case JSON_ERROR_STATE_MISMATCH: + $msg = ' - Underflow or the modes mismatch'; + break; + case JSON_ERROR_CTRL_CHAR: + $msg = ' - Unexpected control character found'; + break; + case JSON_ERROR_SYNTAX: + $msg = ' - Syntax error, malformed JSON'; + break; + case JSON_ERROR_UTF8: + $msg = ' - Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + default: + $msg = ' - Unknown error'; + break; + } + throw new \Exception('There was an error in the supplied patches file:' . $msg); + } + if (isset($patches['patches'])) { + $patches = $patches['patches']; + return $patches; + } + elseif(!$patches) { + throw new \Exception('There was an error in the supplied patch file'); + } + } + else { + return array(); + } + } + + /** + * @param PackageEvent $event + * @throws \Exception + */ + public function postInstall(PackageEvent $event) { + + // Check if we should exit in failure. + $extra = $this->composer->getPackage()->getExtra(); + $exitOnFailure = getenv('COMPOSER_EXIT_ON_PATCH_FAILURE') || !empty($extra['composer-exit-on-patch-failure']); + + // Get the package object for the current operation. + $operation = $event->getOperation(); + /** @var PackageInterface $package */ + $package = $this->getPackageFromOperation($operation); + $package_name = $package->getName(); + + if (!isset($this->patches[$package_name])) { + if ($this->io->isVerbose()) { + $this->io->write('<info>No patches found for ' . $package_name . '.</info>'); + } + return; + } + $this->io->write(' - Applying patches for <info>' . $package_name . '</info>'); + + // Get the install path from the package object. + $manager = $event->getComposer()->getInstallationManager(); + $install_path = $manager->getInstaller($package->getType())->getInstallPath($package); + + // Set up a downloader. + $downloader = new RemoteFilesystem($this->io, $this->composer->getConfig()); + + // Track applied patches in the package info in installed.json + $localRepository = $this->composer->getRepositoryManager()->getLocalRepository(); + $localPackage = $localRepository->findPackage($package_name, $package->getVersion()); + $extra = $localPackage->getExtra(); + $extra['patches_applied'] = array(); + + foreach ($this->patches[$package_name] as $description => $url) { + $this->io->write(' <info>' . $url . '</info> (<comment>' . $description. '</comment>)'); + try { + $this->eventDispatcher->dispatch(NULL, new PatchEvent(PatchEvents::PRE_PATCH_APPLY, $package, $url, $description)); + $this->getAndApplyPatch($downloader, $install_path, $url, $package); + $this->eventDispatcher->dispatch(NULL, new PatchEvent(PatchEvents::POST_PATCH_APPLY, $package, $url, $description)); + $extra['patches_applied'][$description] = $url; + } + catch (\Exception $e) { + $this->io->write(' <error>Could not apply patch! Skipping. The error was: ' . $e->getMessage() . '</error>'); + if ($exitOnFailure) { + throw new \Exception("Cannot apply patch $description ($url)!"); + } + } + } + $localPackage->setExtra($extra); + + $this->io->write(''); + $this->writePatchReport($this->patches[$package_name], $install_path); + } + + /** + * Get a Package object from an OperationInterface object. + * + * @param OperationInterface $operation + * @return PackageInterface + * @throws \Exception + */ + protected function getPackageFromOperation(OperationInterface $operation) { + if ($operation instanceof InstallOperation) { + $package = $operation->getPackage(); + } + elseif ($operation instanceof UpdateOperation) { + $package = $operation->getTargetPackage(); + } + else { + throw new \Exception('Unknown operation: ' . get_class($operation)); + } + + return $package; + } + + /** + * Apply a patch on code in the specified directory. + * + * @param RemoteFilesystem $downloader + * @param $install_path + * @param $patch_url + * @param PackageInterface $package + * @throws \Exception + */ + protected function getAndApplyPatch(RemoteFilesystem $downloader, $install_path, $patch_url, PackageInterface $package) { + + // Local patch file. + if (file_exists($patch_url)) { + $filename = realpath($patch_url); + } + else { + // Generate random (but not cryptographically so) filename. + $filename = uniqid(sys_get_temp_dir().'/') . ".patch"; + + // Download file from remote filesystem to this location. + $hostname = parse_url($patch_url, PHP_URL_HOST); + + try { + $downloader->copy($hostname, $patch_url, $filename, false); + } catch (\Exception $e) { + // In case of an exception, retry once as the download might + // have failed due to intermittent network issues. + $downloader->copy($hostname, $patch_url, $filename, false); + } + } + + // The order here is intentional. p1 is most likely to apply with git apply. + // p0 is next likely. p2 is extremely unlikely, but for some special cases, + // it might be useful. p4 is useful for Magento 2 patches + $patch_levels = array('-p1', '-p0', '-p2', '-p4'); + + // Check for specified patch level for this package. + $extra = $this->composer->getPackage()->getExtra(); + if (!empty($extra['patchLevel'][$package->getName()])){ + $patch_levels = array($extra['patchLevel'][$package->getName()]); + } + // Attempt to apply with git apply. + $patched = $this->applyPatchWithGit($install_path, $patch_levels, $filename); + + // In some rare cases, git will fail to apply a patch, fallback to using + // the 'patch' command. + if (!$patched) { + foreach ($patch_levels as $patch_level) { + // --no-backup-if-mismatch here is a hack that fixes some + // differences between how patch works on windows and unix. + if ($patched = $this->executeCommand("patch %s --no-backup-if-mismatch -d %s < %s", $patch_level, $install_path, $filename)) { + break; + } + } + } + + // Clean up the temporary patch file. + if (isset($hostname)) { + unlink($filename); + } + // If the patch *still* isn't applied, then give up and throw an Exception. + // Otherwise, let the user know it worked. + if (!$patched) { + throw new \Exception("Cannot apply patch $patch_url"); + } + } + + /** + * Checks if the root package enables patching. + * + * @return bool + * Whether patching is enabled. Defaults to TRUE. + */ + protected function isPatchingEnabled() { + $extra = $this->composer->getPackage()->getExtra(); + + if (empty($extra['patches']) && empty($extra['patches-ignore']) && !isset($extra['patches-file'])) { + // The root package has no patches of its own, so only allow patching if + // it has specifically opted in. + return isset($extra['enable-patching']) ? $extra['enable-patching'] : FALSE; + } + else { + return TRUE; + } + } + + /** + * Writes a patch report to the target directory. + * + * @param array $patches + * @param string $directory + */ + protected function writePatchReport($patches, $directory) { + $output = "This file was automatically generated by Composer Patches (https://github.com/cweagans/composer-patches)\n"; + $output .= "Patches applied to this directory:\n\n"; + foreach ($patches as $description => $url) { + $output .= $description . "\n"; + $output .= 'Source: ' . $url . "\n\n\n"; + } + file_put_contents($directory . "/PATCHES.txt", $output); + } + + /** + * Executes a shell command with escaping. + * + * @param string $cmd + * @return bool + */ + protected function executeCommand($cmd) { + // Shell-escape all arguments except the command. + $args = func_get_args(); + foreach ($args as $index => $arg) { + if ($index !== 0) { + $args[$index] = escapeshellarg($arg); + } + } + + // And replace the arguments. + $command = call_user_func_array('sprintf', $args); + $output = ''; + if ($this->io->isVerbose()) { + $this->io->write('<comment>' . $command . '</comment>'); + $io = $this->io; + $output = function ($type, $data) use ($io) { + if ($type == Process::ERR) { + $io->write('<error>' . $data . '</error>'); + } + else { + $io->write('<comment>' . $data . '</comment>'); + } + }; + } + return ($this->executor->execute($command, $output) == 0); + } + + /** + * Recursively merge arrays without changing data types of values. + * + * Does not change the data types of the values in the arrays. Matching keys' + * values in the second array overwrite those in the first array, as is the + * case with array_merge. + * + * @param array $array1 + * The first array. + * @param array $array2 + * The second array. + * @return array + * The merged array. + * + * @see http://php.net/manual/en/function.array-merge-recursive.php#92195 + */ + protected function arrayMergeRecursiveDistinct(array $array1, array $array2) { + $merged = $array1; + + foreach ($array2 as $key => &$value) { + if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) { + $merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value); + } + else { + $merged[$key] = $value; + } + } + + return $merged; + } + + /** + * Attempts to apply a patch with git apply. + * + * @param $install_path + * @param $patch_levels + * @param $filename + * + * @return bool + * TRUE if patch was applied, FALSE otherwise. + */ + protected function applyPatchWithGit($install_path, $patch_levels, $filename) { + // Do not use git apply unless the install path is itself a git repo + // @see https://stackoverflow.com/a/27283285 + if (!is_dir($install_path . '/.git')) { + return FALSE; + } + + $patched = FALSE; + foreach ($patch_levels as $patch_level) { + if ($this->io->isVerbose()) { + $comment = 'Testing ability to patch with git apply.'; + $comment .= ' This command may produce errors that can be safely ignored.'; + $this->io->write('<comment>' . $comment . '</comment>'); + } + $checked = $this->executeCommand('git -C %s apply --check -v %s %s', $install_path, $patch_level, $filename); + $output = $this->executor->getErrorOutput(); + if (substr($output, 0, 7) == 'Skipped') { + // Git will indicate success but silently skip patches in some scenarios. + // + // @see https://github.com/cweagans/composer-patches/pull/165 + $checked = FALSE; + } + if ($checked) { + // Apply the first successful style. + $patched = $this->executeCommand('git -C %s apply %s %s', $install_path, $patch_level, $filename); + break; + } + } + return $patched; + } + +} diff --git a/vendor/cweagans/composer-patches/tests/PatchEventTest.php b/vendor/cweagans/composer-patches/tests/PatchEventTest.php new file mode 100644 index 0000000000..0f6adb7a39 --- /dev/null +++ b/vendor/cweagans/composer-patches/tests/PatchEventTest.php @@ -0,0 +1,39 @@ +<?php + +/** + * @file + * Tests event dispatching. + */ + +namespace cweagans\Composer\Tests; + +use cweagans\Composer\PatchEvent; +use cweagans\Composer\PatchEvents; +use Composer\Package\PackageInterface; + +class PatchEventTest extends \PHPUnit_Framework_TestCase { + + /** + * Tests all the getters. + * + * @dataProvider patchEventDataProvider + */ + public function testGetters($event_name, PackageInterface $package, $url, $description) { + $patch_event = new PatchEvent($event_name, $package, $url, $description); + $this->assertEquals($event_name, $patch_event->getName()); + $this->assertEquals($package, $patch_event->getPackage()); + $this->assertEquals($url, $patch_event->getUrl()); + $this->assertEquals($description, $patch_event->getDescription()); + } + + public function patchEventDataProvider() { + $prophecy = $this->prophesize('Composer\Package\PackageInterface'); + $package = $prophecy->reveal(); + + return array( + array(PatchEvents::PRE_PATCH_APPLY, $package, 'https://www.drupal.org', 'A test patch'), + array(PatchEvents::POST_PATCH_APPLY, $package, 'https://www.drupal.org', 'A test patch'), + ); + } + +} diff --git a/vendor/tecnickcom/tcpdf/PATCHES.txt b/vendor/tecnickcom/tcpdf/PATCHES.txt new file mode 100644 index 0000000000..187d5efd41 --- /dev/null +++ b/vendor/tecnickcom/tcpdf/PATCHES.txt @@ -0,0 +1,7 @@ +This file was automatically generated by Composer Patches (https://github.com/cweagans/composer-patches) +Patches applied to this directory: + +PR #137 +Source: https://github.com/tecnickcom/TCPDF/commit/0c73a9c580246b6f4e2eea196f0e4759f79ad632.patch + + diff --git a/vendor/tecnickcom/tcpdf/tcpdf.php b/vendor/tecnickcom/tcpdf/tcpdf.php index 0ee30bc0d1..4dedf41ff2 100644 --- a/vendor/tecnickcom/tcpdf/tcpdf.php +++ b/vendor/tecnickcom/tcpdf/tcpdf.php @@ -4715,14 +4715,14 @@ class TCPDF { * Defines the page and position a link points to. * @param $link (int) The link identifier returned by AddLink() * @param $y (float) Ordinate of target position; -1 indicates the current position. The default value is 0 (top of page) - * @param $page (int) Number of target page; -1 indicates the current page (default value). If you prefix a page number with the * character, then this page will not be changed when adding/deleting/moving pages. + * @param $page (int|string) Number of target page; -1 indicates the current page (default value). If you prefix a page number with the * character, then this page will not be changed when adding/deleting/moving pages. * @public * @since 1.5 * @see AddLink() */ public function SetLink($link, $y=0, $page=-1) { $fixed = false; - if (!empty($page) AND ($page[0] == '*')) { + if (!empty($page) AND is_string($page) AND ($page[0] == '*')) { $page = intval(substr($page, 1)); // this page number will not be changed when moving/add/deleting pages $fixed = true; |
