├── .php_cs ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── composer.json ├── composer.lock └── src ├── Asplode.php ├── Error ├── AbstractErrorException.php ├── ErrorException.php ├── ErrorExceptionInterface.php ├── FatalErrorException.php ├── FatalErrorExceptionInterface.php └── NonFatalErrorExceptionInterface.php ├── ErrorHandler.php ├── ErrorHandlerInterface.php ├── Exception ├── AlreadyInstalledException.php ├── AsplodeExceptionInterface.php ├── ErrorHandlingConfigurationException.php └── NotInstalledException.php ├── FatalErrorHandler.php ├── FatalErrorHandlerInterface.php └── HandlerStack ├── AbstractHandlerStack.php ├── ErrorHandlerStack.php ├── ExceptionHandlerStack.php └── HandlerStackInterface.php /.php_cs: -------------------------------------------------------------------------------- 1 | in(__DIR__) 5 | ->exclude( 6 | array( 7 | 'artifacts', 8 | 'vendor', 9 | ) 10 | ); 11 | 12 | return Symfony\CS\Config\Config::create() 13 | ->level(Symfony\CS\FixerInterface::PSR2_LEVEL) 14 | ->fixers( 15 | array( 16 | // symfony 17 | 'blankline_after_open_tag', 18 | 'duplicate_semicolon', 19 | 'extra_empty_lines', 20 | 'include', 21 | 'join_function', 22 | 'list_commas', 23 | 'multiline_array_trailing_comma', 24 | 'namespace_no_leading_whitespace', 25 | 'new_with_braces', 26 | 'no_blank_lines_after_class_opening', 27 | 'no_empty_lines_after_phpdocs', 28 | 'object_operator', 29 | 'operators_spaces', 30 | 'phpdoc_indent', 31 | 'phpdoc_params', 32 | 'phpdoc_short_description', 33 | 'phpdoc_to_comment', 34 | 'phpdoc_trim', 35 | 'phpdoc_type_to_var', 36 | 'phpdoc_var_without_name', 37 | 'pre_increment', 38 | 'remove_leading_slash_use', 39 | 'remove_lines_between_uses', 40 | 'return', 41 | 'self_accessor', 42 | 'single_array_no_trailing_comma', 43 | 'single_blank_line_before_namespace', 44 | 'single_quote', 45 | 'spaces_before_semicolon', 46 | 'spaces_cast', 47 | 'standardize_not_equal', 48 | 'ternary_spaces', 49 | 'trim_array_spaces', 50 | 'unary_operators_spaces', 51 | 'unused_use', 52 | 'whitespacy_lines', 53 | 54 | // contrib 55 | 'concat_with_spaces', 56 | 'multiline_spaces_before_semicolon', 57 | 'ordered_use', 58 | ) 59 | ) 60 | ->finder($finder); 61 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Asplode changelog 2 | 3 | ## 2.2.0 (2016-04-19) 4 | 5 | - **[IMPROVED]** Increased the amount of memory reserved by the fatal error 6 | handler, to improve the chances of catching memory exhausted fatals. 7 | 8 | ## 2.1.0 (2015-12-11) 9 | 10 | - **[IMPROVED]** Error exceptions use file and line from the original error, and 11 | trim *Asplode* internals from the stack trace (#15). 12 | 13 | [#15]: https://github.com/eloquent/asplode/issues/15 14 | 15 | ## 2.0.1 (2014-10-29) 16 | 17 | - **[IMPROVED]** Support for [Isolator] 3. 18 | 19 | [isolator]: https://github.com/IcecaveStudios/isolator 20 | 21 | ## 2.0.0 (2014-01-25) 22 | 23 | - **[BC BREAK]** Complete re-write 24 | - **[NEW]** Fatal error handling ([#10]) 25 | - **[IMPROVED]** Easier installation via static methods 26 | - **[FIXED]** No longer throws exceptions for deprecation errors ([#9]) 27 | - **[FIXED]** Correctly handles '@' supression ([#7]) 28 | 29 | [#7]: https://github.com/eloquent/asplode/issues/7 30 | [#9]: https://github.com/eloquent/asplode/issues/9 31 | [#10]: https://github.com/eloquent/asplode/issues/10 32 | 33 | ## 1.1.1 (2013-08-01) 34 | 35 | - **[MAINTENANCE]** General repository maintenance. 36 | 37 | ## 1.1.0 (2013-06-11) 38 | 39 | - **[NEW]** Added utility method for asserting correct error handler 40 | configuration ([#5]) 41 | - **[NEW]** Added utility methods for managing the error handler stack 42 | - **[NEW]** Added utility method for invoking a callback without any error 43 | handlers 44 | - **[NEW]** API documentation added 45 | - **[IMPROVED]** Uninstall will only throw a not installed exception if the 46 | current instance is the top-most handler in the stack 47 | - **[IMPROVED]** Install will only throw an already installed exception if the 48 | current instance is the top-most handler in the stack 49 | - **[FIXED]** Uninstall can no longer remove unrelated error handlers ([#6]) 50 | 51 | [#5]: https://github.com/eloquent/asplode/issues/5 52 | [#6]: https://github.com/eloquent/asplode/issues/6 53 | 54 | ## 1.0.5 (2013-03-04) 55 | 56 | - **[NEW]** [Archer] integration 57 | - **[NEW]** Implemented changelog 58 | 59 | [archer]: https://github.com/IcecaveStudios/archer 60 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | **Asplode** is open source software; contributions from the community are 4 | encouraged. Please take a moment to read these guidelines before submitting 5 | changes. 6 | 7 | ## Code style 8 | 9 | All PHP code must adhere to the [PSR-2] standards. 10 | 11 | [psr-2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md 12 | 13 | ## Branching and pull requests 14 | 15 | As a guideline, please follow this process: 16 | 17 | 1. [Fork the repository]. 18 | 2. Create a topic branch for the change, branching from **develop** 19 | (`git checkout -b branch-name develop`). 20 | 3. Make the relevant changes. 21 | 4. [Squash] commits if necessary (`git rebase -i develop`). 22 | 5. Submit a pull request to the **develop** branch. 23 | 24 | [fork the repository]: https://help.github.com/articles/fork-a-repo 25 | [squash]: http://git-scm.com/book/en/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages 26 | 27 | ## Tests and API documentation 28 | 29 | This project uses [Archer] for testing, and API documentation generation: 30 | 31 | - Run the tests with `vendor/bin/archer t path/to/tests`, or simply 32 | `vendor/bin/archer` to run the entire suite. 33 | - Generate a coverage report with `vendor/bin/archer c path/to/tests`, or simply 34 | `vendor/bin/archer c` to generate coverage for the entire suite. Add `-o` to 35 | open the report in your browser. 36 | - Generate API documentation with `vendor/bin/archer d`. Serve with 37 | `php -S localhost:8000 -t artifacts/documentation/api/`, and open your browser 38 | to [http://localhost:8000/]. 39 | 40 | For more detailed usage, see the [Archer documentation]. 41 | 42 | [archer]: https://github.com/IcecaveStudios/archer 43 | [archer documentation]: https://github.com/IcecaveStudios/archer 44 | [http://localhost:8000/]: http://localhost:8000/ 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2016 Erin Millard 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Asplode 2 | 3 | *Drop-in exception-based error handling for PHP.* 4 | 5 | [![Current version image][version-image]][current version] 6 | [![Current build status image][build-image]][current build status] 7 | [![Current coverage status image][coverage-image]][current coverage status] 8 | 9 | [build-image]: http://img.shields.io/travis/eloquent/asplode/develop.svg?style=flat-square "Current build status for the develop branch" 10 | [coverage-image]: https://img.shields.io/codecov/c/github/eloquent/asplode/develop.svg?style=flat-square "Current test coverage for the develop branch" 11 | [current build status]: https://travis-ci.org/eloquent/asplode 12 | [current coverage status]: https://codecov.io/github/eloquent/asplode 13 | [current version]: https://packagist.org/packages/eloquent/asplode 14 | [version-image]: https://img.shields.io/packagist/v/eloquent/asplode.svg?style=flat-square "This project uses semantic versioning" 15 | 16 | ## Installation and documentation 17 | 18 | - Available as [Composer] package [eloquent/asplode]. 19 | - [API documentation] available. 20 | 21 | [api documentation]: http://lqnt.co/asplode/artifacts/documentation/api/ 22 | [composer]: http://getcomposer.org/ 23 | [eloquent/asplode]: https://packagist.org/packages/eloquent/asplode 24 | 25 | ## Usage 26 | 27 | The *Asplode* error handler can be installed with a single statement: 28 | 29 | ```php 30 | Eloquent\Asplode\Asplode::install(); 31 | ``` 32 | 33 | ## What does *Asplode* do? 34 | 35 | *Asplode* is a very simple PHP [error handler] implementation that throws 36 | [ErrorException] exceptions instead of using the default PHP error handling 37 | behaviour. This means that all non-fatal runtime errors are presented to the 38 | developer in the form of an exception. It also means that any unhandled errors 39 | are delivered to a single point: the global exception handler. 40 | 41 | [error handler]: http://php.net/set_error_handler 42 | [errorexception]: http://php.net/ErrorException 43 | 44 | ## Why use *Asplode*? 45 | 46 | Developers need the ability to decide how their code behaves when an error 47 | occurs. Exceptions offer the only truly consistent way to report and recover 48 | from errors in PHP. 49 | 50 | This method of handling errors has proven to be extremely effective. Similar 51 | strategies are used in major PHP frameworks such as [Laravel]. *Asplode* is a 52 | standalone implementation that can be used for any project. 53 | 54 | [laravel]: http://laravel.com/ 55 | 56 | ## Fatal error handling 57 | 58 | While it's not feasible to *recover* from fatal PHP errors, it is possible to 59 | *report* fatal errors in the same manner as uncaught exceptions. 60 | 61 | With *Asplode*, fatal errors cause a synthesized exception representing the 62 | fatal error to be passed to the global exception handler. This allows developers 63 | to gracefully inform the user of fatal errors just before the PHP interpreter is 64 | shut down. 65 | 66 | The *Asplode* fatal error handler is installed by default, but is only activated 67 | if a global exception handler is installed. 68 | 69 | ```php 70 | set_exception_handler( 71 | function (Exception $e) { 72 | echo $e->getMessage(); 73 | } 74 | ); 75 | 76 | Eloquent\Asplode\Asplode::install(); 77 | ``` 78 | 79 | To use *Asplode* without the fatal error handler, use 80 | `Asplode::installErrorHandler()` instead of `Asplode::install()`. To use only 81 | the fatal error handler, use `Asplode::installFatalHandler()`. 82 | 83 | Note that attempting to autoload files in the shutdown phase of PHP may be 84 | probelmatic; and as such, custom exception handlers should explicitly load their 85 | dependencies where possible. 86 | 87 | ## Asserting that the current error handler is compatible 88 | 89 | Code that assumes the use of *Asplode* may not work as expected unless the right 90 | type of error handler is installed. For example, code expecting to catch an 91 | `ErrorException` on failure will have unpredictable results if the installed 92 | error handler does not throw `ErrorException` instances. 93 | 94 | To ensure that a correctly configured error handler is installed, *Asplode* 95 | provides the `Asplode::assertCompatibleHandler()` method. 96 | 97 | ```php 98 | use Eloquent\Asplode\Asplode; 99 | use Eloquent\Asplode\Exception\ErrorHandlingConfigurationException; 100 | 101 | try { 102 | Asplode::assertCompatibleHandler(); 103 | } catch (ErrorHandlingConfigurationException $e) { 104 | // handle appropriately 105 | } 106 | ``` 107 | 108 | A *compatible* error handler is any handler that throws `ErrorException` 109 | exceptions. It does not need to be the implementation provided by *Asplode*. 110 | 111 | ## Managing PHP's handler stacks 112 | 113 | PHP's error and exception handlers approximate the behaviour of a [stack]. 114 | However, the interface for manipulating the stack is limited, and quite frankly, 115 | poorly implemented. 116 | 117 | *Asplode* includes two classes to aid in management of these stacks, 118 | [ErrorHandlerStack] and [ExceptionHandlerStack]. Both implement 119 | [HandlerStackInterface] which provides a familiar interface for working with 120 | stacks. These classes do not require the use of the *Asplode* handler; they can 121 | be used in a standalone manner to manage the handler stacks. 122 | 123 | [errorhandlerstack]: http://lqnt.co/asplode/artifacts/documentation/api/Eloquent/Asplode/HandlerStack/ErrorHandlerStack.html 124 | [exceptionhandlerstack]: http://lqnt.co/asplode/artifacts/documentation/api/Eloquent/Asplode/HandlerStack/ExceptionHandlerStack.html 125 | [handlerstackinterface]: http://lqnt.co/asplode/artifacts/documentation/api/Eloquent/Asplode/HandlerStack/HandlerStackInterface.html 126 | [stack]: http://en.wikipedia.org/wiki/Stack_(abstract_data_type) 127 | 128 | ## Migrating existing code to work with Asplode 129 | 130 | When the *Asplode* error handler is installed, the [error_reporting] setting 131 | will no longer have any effect. Notices, warnings, and errors will all result in 132 | an exception being thrown. Deprecation notices will not throw an exception, but 133 | will still be logged provided that PHP is configured to do so. 134 | 135 | Code that has been written to handle legacy-style PHP errors will most likely 136 | need to be re-written. As an example, this type of logic: 137 | 138 | ```php 139 | $fp = fopen('/path/to/foo', 'r'); // this throws a PHP warning if the file is not found 140 | 141 | if ($fp === false) { 142 | // handle error opening file 143 | } 144 | ``` 145 | 146 | would need to be rewritten to to handle exceptions: 147 | 148 | ```php 149 | try { 150 | $fp = fopen('/path/to/foo', 'r'); 151 | } catch (ErrorException $e) { 152 | // handle error opening file 153 | } 154 | ``` 155 | 156 | It's important to note that PHP can be very inconsistent in the way it reports 157 | error conditions. Some functions will return a boolean false to indicate an 158 | error has occurred; others may require the developer to call additional 159 | functions to check for errors; and others still may exhibit entirely 160 | non-standard behaviour. 161 | 162 | *Asplode* does not free the developer from the responsibility of reading the PHP 163 | documentation, or making sure that they account for all possible error 164 | conditions. 165 | 166 | [error_reporting]: http://php.net/error_reporting 167 | 168 | ## Executing legacy code 169 | 170 | Sometimes working with code that uses bad practices is unavoidable. A legacy PHP 171 | library might be perfectly functional and useful, but it may not anticipate 172 | exceptions being thrown when an error occurs. 173 | 174 | *Asplode*'s exception and error handler stacks both implement an `executeWith()` 175 | method that allows code to be executed with a different handler than the one 176 | currently installed. This method pops all current handlers off the stack 177 | temporarily, installs the specified handler (if one is provided) and executes 178 | the supplied callback. The original handler is restored after the callback is 179 | executed. 180 | 181 | ```php 182 | use Eloquent\Asplode\HandlerStack\ErrorHandlerStack; 183 | 184 | $stack = new ErrorHandlerStack; 185 | 186 | $result = $stack->executeWith( 187 | function () { 188 | // this code will be executed under the default handler 189 | } 190 | ); 191 | 192 | $result = $stack->executeWith( 193 | function () { 194 | // this code will be executed under the supplied handler 195 | }, 196 | 'errorHandlerFunctionName' 197 | ); 198 | 199 | $result = $stack->executeWith( 200 | function () { 201 | // this code will be executed under the supplied handler 202 | }, 203 | function ($severity, $message, $path, $lineNumber) { 204 | // handle the error 205 | } 206 | ); 207 | ``` 208 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eloquent/asplode", 3 | "description": "Drop-in exception-based error handling for PHP.", 4 | "keywords": ["error", "handling", "handler", "exception", "errorexception", "fault", "failure"], 5 | "homepage": "https://github.com/eloquent/asplode", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Erin Millard", 10 | "email": "ezzatron@gmail.com", 11 | "homepage": "http://ezzatron.com/" 12 | } 13 | ], 14 | "require": { 15 | "php": ">=5.3", 16 | "icecave/isolator": "~2|~3" 17 | }, 18 | "require-dev": { 19 | "eloquent/phony": "dev-develop", 20 | "icecave/archer": "dev-develop", 21 | "phpunit/phpunit": "^4", 22 | "sami/sami": "^3" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Eloquent\\Asplode\\": "src" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "51e1283c07bdd0c59a7fd194d0d36258", 8 | "content-hash": "3ddce2a1096b3e7e1764c71a1bb22b7b", 9 | "packages": [ 10 | { 11 | "name": "icecave/isolator", 12 | "version": "3.0.3", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/IcecaveStudios/isolator.git", 16 | "reference": "8fad9e64c393238b01b359e01bd7f25dcdb818e4" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/IcecaveStudios/isolator/zipball/8fad9e64c393238b01b359e01bd7f25dcdb818e4", 21 | "reference": "8fad9e64c393238b01b359e01bd7f25dcdb818e4", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": ">=5.3" 26 | }, 27 | "require-dev": { 28 | "icecave/archer": "~1" 29 | }, 30 | "type": "library", 31 | "extra": { 32 | "branch-alias": { 33 | "dev-develop": "3.0.x-dev" 34 | } 35 | }, 36 | "autoload": { 37 | "psr-4": { 38 | "Icecave\\Isolator\\": "src" 39 | }, 40 | "files": [ 41 | "src/register-autoloader.php" 42 | ] 43 | }, 44 | "notification-url": "https://packagist.org/downloads/", 45 | "license": [ 46 | "MIT" 47 | ], 48 | "authors": [ 49 | { 50 | "name": "James Harris", 51 | "email": "james.harris@icecave.com.au", 52 | "homepage": "https://github.com/jmalloc" 53 | } 54 | ], 55 | "description": "Dependency injection for global functions.", 56 | "homepage": "https://github.com/IcecaveStudios/isolator", 57 | "keywords": [ 58 | "Double", 59 | "fake", 60 | "mock", 61 | "phpunit", 62 | "stub", 63 | "test", 64 | "unit" 65 | ], 66 | "time": "2015-03-27 05:04:19" 67 | } 68 | ], 69 | "packages-dev": [ 70 | { 71 | "name": "doctrine/instantiator", 72 | "version": "1.0.5", 73 | "source": { 74 | "type": "git", 75 | "url": "https://github.com/doctrine/instantiator.git", 76 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 77 | }, 78 | "dist": { 79 | "type": "zip", 80 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 81 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 82 | "shasum": "" 83 | }, 84 | "require": { 85 | "php": ">=5.3,<8.0-DEV" 86 | }, 87 | "require-dev": { 88 | "athletic/athletic": "~0.1.8", 89 | "ext-pdo": "*", 90 | "ext-phar": "*", 91 | "phpunit/phpunit": "~4.0", 92 | "squizlabs/php_codesniffer": "~2.0" 93 | }, 94 | "type": "library", 95 | "extra": { 96 | "branch-alias": { 97 | "dev-master": "1.0.x-dev" 98 | } 99 | }, 100 | "autoload": { 101 | "psr-4": { 102 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 103 | } 104 | }, 105 | "notification-url": "https://packagist.org/downloads/", 106 | "license": [ 107 | "MIT" 108 | ], 109 | "authors": [ 110 | { 111 | "name": "Marco Pivetta", 112 | "email": "ocramius@gmail.com", 113 | "homepage": "http://ocramius.github.com/" 114 | } 115 | ], 116 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 117 | "homepage": "https://github.com/doctrine/instantiator", 118 | "keywords": [ 119 | "constructor", 120 | "instantiate" 121 | ], 122 | "time": "2015-06-14 21:17:01" 123 | }, 124 | { 125 | "name": "eloquent/phony", 126 | "version": "dev-develop", 127 | "source": { 128 | "type": "git", 129 | "url": "https://github.com/eloquent/phony.git", 130 | "reference": "b1b7cf4a3658a1a0a91077c78e4e07c9d22f872f" 131 | }, 132 | "dist": { 133 | "type": "zip", 134 | "url": "https://api.github.com/repos/eloquent/phony/zipball/b1b7cf4a3658a1a0a91077c78e4e07c9d22f872f", 135 | "reference": "b1b7cf4a3658a1a0a91077c78e4e07c9d22f872f", 136 | "shasum": "" 137 | }, 138 | "require": { 139 | "php": ">=5.3" 140 | }, 141 | "require-dev": { 142 | "athletic/athletic": "^0.1", 143 | "counterpart/counterpart": "^1", 144 | "danielstjules/pho": "^1", 145 | "eloquent/asplode": "^2", 146 | "hamcrest/hamcrest-php": "^1", 147 | "icecave/archer": "dev-develop", 148 | "icecave/isolator": "^3", 149 | "mockery/mockery": "^0", 150 | "peridot-php/leo": "^1", 151 | "peridot-php/peridot": "^1", 152 | "phake/phake": "^2", 153 | "phpspec/prophecy": "^1", 154 | "phpunit/php-code-coverage": "^2", 155 | "phpunit/phpunit": "^4", 156 | "sami/sami": "^2", 157 | "sebastian/comparator": "^1", 158 | "simpletest/simpletest": "dev-master" 159 | }, 160 | "type": "library", 161 | "extra": { 162 | "branch-alias": { 163 | "dev-develop": "0.6.x-dev" 164 | } 165 | }, 166 | "autoload": { 167 | "psr-4": { 168 | "Eloquent\\Phony\\": "src" 169 | }, 170 | "files": [ 171 | "src/functions.php", 172 | "src/Pho/functions.php", 173 | "src/Phpunit/functions.php", 174 | "src/Simpletest/functions.php" 175 | ] 176 | }, 177 | "notification-url": "https://packagist.org/downloads/", 178 | "license": [ 179 | "MIT" 180 | ], 181 | "authors": [ 182 | { 183 | "name": "Erin Millard", 184 | "email": "ezzatron@gmail.com", 185 | "homepage": "http://ezzatron.com/" 186 | } 187 | ], 188 | "description": "Mocks, stubs, and spies for PHP.", 189 | "homepage": "https://github.com/eloquent/phony", 190 | "keywords": [ 191 | "Double", 192 | "Dummy", 193 | "fake", 194 | "mock", 195 | "mocking", 196 | "spy", 197 | "stub", 198 | "stubbing", 199 | "test" 200 | ], 201 | "time": "2015-12-10 00:04:37" 202 | }, 203 | { 204 | "name": "icecave/archer", 205 | "version": "dev-develop", 206 | "source": { 207 | "type": "git", 208 | "url": "https://github.com/IcecaveStudios/archer.git", 209 | "reference": "8a140d4838d5920ed49dc9c5fa300016cc85109b" 210 | }, 211 | "dist": { 212 | "type": "zip", 213 | "url": "https://api.github.com/repos/IcecaveStudios/archer/zipball/8a140d4838d5920ed49dc9c5fa300016cc85109b", 214 | "reference": "8a140d4838d5920ed49dc9c5fa300016cc85109b", 215 | "shasum": "" 216 | }, 217 | "require": { 218 | "php": ">=5.3", 219 | "symfony/console": "^2", 220 | "symfony/process": "^2" 221 | }, 222 | "require-dev": { 223 | "eloquent/liberator": "^2", 224 | "eloquent/phony": "^0.5", 225 | "phpunit/phpunit": "^4", 226 | "sami/sami": "^3" 227 | }, 228 | "suggest": { 229 | "ext-openssl": "OpenSSL is required to encrypt GitHub OAuth tokens for artifact publication." 230 | }, 231 | "bin": [ 232 | "bin/archer", 233 | "bin/woodhouse" 234 | ], 235 | "type": "library", 236 | "extra": { 237 | "branch-alias": { 238 | "dev-develop": "1.3.x-dev" 239 | } 240 | }, 241 | "autoload": { 242 | "psr-4": { 243 | "Icecave\\Archer\\": "src" 244 | } 245 | }, 246 | "notification-url": "https://packagist.org/downloads/", 247 | "license": [ 248 | "MIT" 249 | ], 250 | "authors": [ 251 | { 252 | "name": "Erin Millard", 253 | "email": "ezzatron@gmail.com", 254 | "homepage": "http://ezzatron.com/" 255 | }, 256 | { 257 | "name": "James Harris", 258 | "email": "james.harris@icecave.com.au", 259 | "homepage": "https://github.com/jmalloc" 260 | } 261 | ], 262 | "description": "Testing, CI and documentation of PHP projects by convention.", 263 | "homepage": "https://github.com/IcecaveStudios/archer", 264 | "keywords": [ 265 | "api", 266 | "artifacts", 267 | "convention", 268 | "coverage", 269 | "documentation", 270 | "phake", 271 | "phpunit", 272 | "project", 273 | "test", 274 | "testing", 275 | "unit" 276 | ], 277 | "time": "2015-10-26 00:32:44" 278 | }, 279 | { 280 | "name": "michelf/php-markdown", 281 | "version": "1.5.0", 282 | "source": { 283 | "type": "git", 284 | "url": "https://github.com/michelf/php-markdown.git", 285 | "reference": "e1aabe18173231ebcefc90e615565742fc1c7fd9" 286 | }, 287 | "dist": { 288 | "type": "zip", 289 | "url": "https://api.github.com/repos/michelf/php-markdown/zipball/e1aabe18173231ebcefc90e615565742fc1c7fd9", 290 | "reference": "e1aabe18173231ebcefc90e615565742fc1c7fd9", 291 | "shasum": "" 292 | }, 293 | "require": { 294 | "php": ">=5.3.0" 295 | }, 296 | "type": "library", 297 | "extra": { 298 | "branch-alias": { 299 | "dev-lib": "1.4.x-dev" 300 | } 301 | }, 302 | "autoload": { 303 | "psr-0": { 304 | "Michelf": "" 305 | } 306 | }, 307 | "notification-url": "https://packagist.org/downloads/", 308 | "license": [ 309 | "BSD-3-Clause" 310 | ], 311 | "authors": [ 312 | { 313 | "name": "John Gruber", 314 | "homepage": "http://daringfireball.net/" 315 | }, 316 | { 317 | "name": "Michel Fortin", 318 | "email": "michel.fortin@michelf.ca", 319 | "homepage": "https://michelf.ca/", 320 | "role": "Developer" 321 | } 322 | ], 323 | "description": "PHP Markdown", 324 | "homepage": "https://michelf.ca/projects/php-markdown/", 325 | "keywords": [ 326 | "markdown" 327 | ], 328 | "time": "2015-03-01 12:03:08" 329 | }, 330 | { 331 | "name": "nikic/php-parser", 332 | "version": "v1.4.1", 333 | "source": { 334 | "type": "git", 335 | "url": "https://github.com/nikic/PHP-Parser.git", 336 | "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51" 337 | }, 338 | "dist": { 339 | "type": "zip", 340 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", 341 | "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", 342 | "shasum": "" 343 | }, 344 | "require": { 345 | "ext-tokenizer": "*", 346 | "php": ">=5.3" 347 | }, 348 | "type": "library", 349 | "extra": { 350 | "branch-alias": { 351 | "dev-master": "1.4-dev" 352 | } 353 | }, 354 | "autoload": { 355 | "files": [ 356 | "lib/bootstrap.php" 357 | ] 358 | }, 359 | "notification-url": "https://packagist.org/downloads/", 360 | "license": [ 361 | "BSD-3-Clause" 362 | ], 363 | "authors": [ 364 | { 365 | "name": "Nikita Popov" 366 | } 367 | ], 368 | "description": "A PHP parser written in PHP", 369 | "keywords": [ 370 | "parser", 371 | "php" 372 | ], 373 | "time": "2015-09-19 14:15:08" 374 | }, 375 | { 376 | "name": "phpdocumentor/reflection-docblock", 377 | "version": "2.0.4", 378 | "source": { 379 | "type": "git", 380 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 381 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" 382 | }, 383 | "dist": { 384 | "type": "zip", 385 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", 386 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", 387 | "shasum": "" 388 | }, 389 | "require": { 390 | "php": ">=5.3.3" 391 | }, 392 | "require-dev": { 393 | "phpunit/phpunit": "~4.0" 394 | }, 395 | "suggest": { 396 | "dflydev/markdown": "~1.0", 397 | "erusev/parsedown": "~1.0" 398 | }, 399 | "type": "library", 400 | "extra": { 401 | "branch-alias": { 402 | "dev-master": "2.0.x-dev" 403 | } 404 | }, 405 | "autoload": { 406 | "psr-0": { 407 | "phpDocumentor": [ 408 | "src/" 409 | ] 410 | } 411 | }, 412 | "notification-url": "https://packagist.org/downloads/", 413 | "license": [ 414 | "MIT" 415 | ], 416 | "authors": [ 417 | { 418 | "name": "Mike van Riel", 419 | "email": "mike.vanriel@naenius.com" 420 | } 421 | ], 422 | "time": "2015-02-03 12:10:50" 423 | }, 424 | { 425 | "name": "phpspec/prophecy", 426 | "version": "v1.5.0", 427 | "source": { 428 | "type": "git", 429 | "url": "https://github.com/phpspec/prophecy.git", 430 | "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" 431 | }, 432 | "dist": { 433 | "type": "zip", 434 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", 435 | "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", 436 | "shasum": "" 437 | }, 438 | "require": { 439 | "doctrine/instantiator": "^1.0.2", 440 | "phpdocumentor/reflection-docblock": "~2.0", 441 | "sebastian/comparator": "~1.1" 442 | }, 443 | "require-dev": { 444 | "phpspec/phpspec": "~2.0" 445 | }, 446 | "type": "library", 447 | "extra": { 448 | "branch-alias": { 449 | "dev-master": "1.4.x-dev" 450 | } 451 | }, 452 | "autoload": { 453 | "psr-0": { 454 | "Prophecy\\": "src/" 455 | } 456 | }, 457 | "notification-url": "https://packagist.org/downloads/", 458 | "license": [ 459 | "MIT" 460 | ], 461 | "authors": [ 462 | { 463 | "name": "Konstantin Kudryashov", 464 | "email": "ever.zet@gmail.com", 465 | "homepage": "http://everzet.com" 466 | }, 467 | { 468 | "name": "Marcello Duarte", 469 | "email": "marcello.duarte@gmail.com" 470 | } 471 | ], 472 | "description": "Highly opinionated mocking framework for PHP 5.3+", 473 | "homepage": "https://github.com/phpspec/prophecy", 474 | "keywords": [ 475 | "Double", 476 | "Dummy", 477 | "fake", 478 | "mock", 479 | "spy", 480 | "stub" 481 | ], 482 | "time": "2015-08-13 10:07:40" 483 | }, 484 | { 485 | "name": "phpunit/php-code-coverage", 486 | "version": "2.2.4", 487 | "source": { 488 | "type": "git", 489 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 490 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" 491 | }, 492 | "dist": { 493 | "type": "zip", 494 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", 495 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", 496 | "shasum": "" 497 | }, 498 | "require": { 499 | "php": ">=5.3.3", 500 | "phpunit/php-file-iterator": "~1.3", 501 | "phpunit/php-text-template": "~1.2", 502 | "phpunit/php-token-stream": "~1.3", 503 | "sebastian/environment": "^1.3.2", 504 | "sebastian/version": "~1.0" 505 | }, 506 | "require-dev": { 507 | "ext-xdebug": ">=2.1.4", 508 | "phpunit/phpunit": "~4" 509 | }, 510 | "suggest": { 511 | "ext-dom": "*", 512 | "ext-xdebug": ">=2.2.1", 513 | "ext-xmlwriter": "*" 514 | }, 515 | "type": "library", 516 | "extra": { 517 | "branch-alias": { 518 | "dev-master": "2.2.x-dev" 519 | } 520 | }, 521 | "autoload": { 522 | "classmap": [ 523 | "src/" 524 | ] 525 | }, 526 | "notification-url": "https://packagist.org/downloads/", 527 | "license": [ 528 | "BSD-3-Clause" 529 | ], 530 | "authors": [ 531 | { 532 | "name": "Sebastian Bergmann", 533 | "email": "sb@sebastian-bergmann.de", 534 | "role": "lead" 535 | } 536 | ], 537 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 538 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 539 | "keywords": [ 540 | "coverage", 541 | "testing", 542 | "xunit" 543 | ], 544 | "time": "2015-10-06 15:47:00" 545 | }, 546 | { 547 | "name": "phpunit/php-file-iterator", 548 | "version": "1.4.1", 549 | "source": { 550 | "type": "git", 551 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 552 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" 553 | }, 554 | "dist": { 555 | "type": "zip", 556 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 557 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 558 | "shasum": "" 559 | }, 560 | "require": { 561 | "php": ">=5.3.3" 562 | }, 563 | "type": "library", 564 | "extra": { 565 | "branch-alias": { 566 | "dev-master": "1.4.x-dev" 567 | } 568 | }, 569 | "autoload": { 570 | "classmap": [ 571 | "src/" 572 | ] 573 | }, 574 | "notification-url": "https://packagist.org/downloads/", 575 | "license": [ 576 | "BSD-3-Clause" 577 | ], 578 | "authors": [ 579 | { 580 | "name": "Sebastian Bergmann", 581 | "email": "sb@sebastian-bergmann.de", 582 | "role": "lead" 583 | } 584 | ], 585 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 586 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 587 | "keywords": [ 588 | "filesystem", 589 | "iterator" 590 | ], 591 | "time": "2015-06-21 13:08:43" 592 | }, 593 | { 594 | "name": "phpunit/php-text-template", 595 | "version": "1.2.1", 596 | "source": { 597 | "type": "git", 598 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 599 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 600 | }, 601 | "dist": { 602 | "type": "zip", 603 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 604 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 605 | "shasum": "" 606 | }, 607 | "require": { 608 | "php": ">=5.3.3" 609 | }, 610 | "type": "library", 611 | "autoload": { 612 | "classmap": [ 613 | "src/" 614 | ] 615 | }, 616 | "notification-url": "https://packagist.org/downloads/", 617 | "license": [ 618 | "BSD-3-Clause" 619 | ], 620 | "authors": [ 621 | { 622 | "name": "Sebastian Bergmann", 623 | "email": "sebastian@phpunit.de", 624 | "role": "lead" 625 | } 626 | ], 627 | "description": "Simple template engine.", 628 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 629 | "keywords": [ 630 | "template" 631 | ], 632 | "time": "2015-06-21 13:50:34" 633 | }, 634 | { 635 | "name": "phpunit/php-timer", 636 | "version": "1.0.7", 637 | "source": { 638 | "type": "git", 639 | "url": "https://github.com/sebastianbergmann/php-timer.git", 640 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" 641 | }, 642 | "dist": { 643 | "type": "zip", 644 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", 645 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", 646 | "shasum": "" 647 | }, 648 | "require": { 649 | "php": ">=5.3.3" 650 | }, 651 | "type": "library", 652 | "autoload": { 653 | "classmap": [ 654 | "src/" 655 | ] 656 | }, 657 | "notification-url": "https://packagist.org/downloads/", 658 | "license": [ 659 | "BSD-3-Clause" 660 | ], 661 | "authors": [ 662 | { 663 | "name": "Sebastian Bergmann", 664 | "email": "sb@sebastian-bergmann.de", 665 | "role": "lead" 666 | } 667 | ], 668 | "description": "Utility class for timing", 669 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 670 | "keywords": [ 671 | "timer" 672 | ], 673 | "time": "2015-06-21 08:01:12" 674 | }, 675 | { 676 | "name": "phpunit/php-token-stream", 677 | "version": "1.4.8", 678 | "source": { 679 | "type": "git", 680 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 681 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" 682 | }, 683 | "dist": { 684 | "type": "zip", 685 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 686 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 687 | "shasum": "" 688 | }, 689 | "require": { 690 | "ext-tokenizer": "*", 691 | "php": ">=5.3.3" 692 | }, 693 | "require-dev": { 694 | "phpunit/phpunit": "~4.2" 695 | }, 696 | "type": "library", 697 | "extra": { 698 | "branch-alias": { 699 | "dev-master": "1.4-dev" 700 | } 701 | }, 702 | "autoload": { 703 | "classmap": [ 704 | "src/" 705 | ] 706 | }, 707 | "notification-url": "https://packagist.org/downloads/", 708 | "license": [ 709 | "BSD-3-Clause" 710 | ], 711 | "authors": [ 712 | { 713 | "name": "Sebastian Bergmann", 714 | "email": "sebastian@phpunit.de" 715 | } 716 | ], 717 | "description": "Wrapper around PHP's tokenizer extension.", 718 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 719 | "keywords": [ 720 | "tokenizer" 721 | ], 722 | "time": "2015-09-15 10:49:45" 723 | }, 724 | { 725 | "name": "phpunit/phpunit", 726 | "version": "4.8.20", 727 | "source": { 728 | "type": "git", 729 | "url": "https://github.com/sebastianbergmann/phpunit.git", 730 | "reference": "7438c43bc2bbb2febe1723eb595b1c49283a26ad" 731 | }, 732 | "dist": { 733 | "type": "zip", 734 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7438c43bc2bbb2febe1723eb595b1c49283a26ad", 735 | "reference": "7438c43bc2bbb2febe1723eb595b1c49283a26ad", 736 | "shasum": "" 737 | }, 738 | "require": { 739 | "ext-dom": "*", 740 | "ext-json": "*", 741 | "ext-pcre": "*", 742 | "ext-reflection": "*", 743 | "ext-spl": "*", 744 | "php": "~5.3.3|~5.4|~5.5|~5.6", 745 | "phpspec/prophecy": "^1.3.1", 746 | "phpunit/php-code-coverage": "~2.1", 747 | "phpunit/php-file-iterator": "~1.4", 748 | "phpunit/php-text-template": "~1.2", 749 | "phpunit/php-timer": ">=1.0.6", 750 | "phpunit/phpunit-mock-objects": "~2.3", 751 | "sebastian/comparator": "~1.1", 752 | "sebastian/diff": "~1.2", 753 | "sebastian/environment": "~1.3", 754 | "sebastian/exporter": "~1.2", 755 | "sebastian/global-state": "~1.0", 756 | "sebastian/version": "~1.0", 757 | "symfony/yaml": "~2.1|~3.0" 758 | }, 759 | "suggest": { 760 | "phpunit/php-invoker": "~1.1" 761 | }, 762 | "bin": [ 763 | "phpunit" 764 | ], 765 | "type": "library", 766 | "extra": { 767 | "branch-alias": { 768 | "dev-master": "4.8.x-dev" 769 | } 770 | }, 771 | "autoload": { 772 | "classmap": [ 773 | "src/" 774 | ] 775 | }, 776 | "notification-url": "https://packagist.org/downloads/", 777 | "license": [ 778 | "BSD-3-Clause" 779 | ], 780 | "authors": [ 781 | { 782 | "name": "Sebastian Bergmann", 783 | "email": "sebastian@phpunit.de", 784 | "role": "lead" 785 | } 786 | ], 787 | "description": "The PHP Unit Testing framework.", 788 | "homepage": "https://phpunit.de/", 789 | "keywords": [ 790 | "phpunit", 791 | "testing", 792 | "xunit" 793 | ], 794 | "time": "2015-12-10 07:48:52" 795 | }, 796 | { 797 | "name": "phpunit/phpunit-mock-objects", 798 | "version": "2.3.8", 799 | "source": { 800 | "type": "git", 801 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 802 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" 803 | }, 804 | "dist": { 805 | "type": "zip", 806 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", 807 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", 808 | "shasum": "" 809 | }, 810 | "require": { 811 | "doctrine/instantiator": "^1.0.2", 812 | "php": ">=5.3.3", 813 | "phpunit/php-text-template": "~1.2", 814 | "sebastian/exporter": "~1.2" 815 | }, 816 | "require-dev": { 817 | "phpunit/phpunit": "~4.4" 818 | }, 819 | "suggest": { 820 | "ext-soap": "*" 821 | }, 822 | "type": "library", 823 | "extra": { 824 | "branch-alias": { 825 | "dev-master": "2.3.x-dev" 826 | } 827 | }, 828 | "autoload": { 829 | "classmap": [ 830 | "src/" 831 | ] 832 | }, 833 | "notification-url": "https://packagist.org/downloads/", 834 | "license": [ 835 | "BSD-3-Clause" 836 | ], 837 | "authors": [ 838 | { 839 | "name": "Sebastian Bergmann", 840 | "email": "sb@sebastian-bergmann.de", 841 | "role": "lead" 842 | } 843 | ], 844 | "description": "Mock Object library for PHPUnit", 845 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 846 | "keywords": [ 847 | "mock", 848 | "xunit" 849 | ], 850 | "time": "2015-10-02 06:51:40" 851 | }, 852 | { 853 | "name": "pimple/pimple", 854 | "version": "v3.0.2", 855 | "source": { 856 | "type": "git", 857 | "url": "https://github.com/silexphp/Pimple.git", 858 | "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a" 859 | }, 860 | "dist": { 861 | "type": "zip", 862 | "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a", 863 | "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a", 864 | "shasum": "" 865 | }, 866 | "require": { 867 | "php": ">=5.3.0" 868 | }, 869 | "type": "library", 870 | "extra": { 871 | "branch-alias": { 872 | "dev-master": "3.0.x-dev" 873 | } 874 | }, 875 | "autoload": { 876 | "psr-0": { 877 | "Pimple": "src/" 878 | } 879 | }, 880 | "notification-url": "https://packagist.org/downloads/", 881 | "license": [ 882 | "MIT" 883 | ], 884 | "authors": [ 885 | { 886 | "name": "Fabien Potencier", 887 | "email": "fabien@symfony.com" 888 | } 889 | ], 890 | "description": "Pimple, a simple Dependency Injection Container", 891 | "homepage": "http://pimple.sensiolabs.org", 892 | "keywords": [ 893 | "container", 894 | "dependency injection" 895 | ], 896 | "time": "2015-09-11 15:10:35" 897 | }, 898 | { 899 | "name": "sami/sami", 900 | "version": "v3.1.0", 901 | "source": { 902 | "type": "git", 903 | "url": "https://github.com/FriendsOfPHP/Sami.git", 904 | "reference": "504f99a1783e2e0e8817a57be946f7c699b83163" 905 | }, 906 | "dist": { 907 | "type": "zip", 908 | "url": "https://api.github.com/repos/FriendsOfPHP/Sami/zipball/504f99a1783e2e0e8817a57be946f7c699b83163", 909 | "reference": "504f99a1783e2e0e8817a57be946f7c699b83163", 910 | "shasum": "" 911 | }, 912 | "require": { 913 | "michelf/php-markdown": "~1.3", 914 | "nikic/php-parser": "~1.0", 915 | "php": ">=5.3.9", 916 | "phpdocumentor/reflection-docblock": "~2.0", 917 | "pimple/pimple": "~3.0", 918 | "symfony/console": "~2.1", 919 | "symfony/filesystem": "~2.1", 920 | "symfony/finder": "~2.1", 921 | "symfony/process": "~2.1", 922 | "symfony/yaml": "~2.1", 923 | "twig/twig": "~1.20|~2.0" 924 | }, 925 | "bin": [ 926 | "sami.php" 927 | ], 928 | "type": "application", 929 | "extra": { 930 | "branch-alias": { 931 | "dev-master": "3.0-dev" 932 | } 933 | }, 934 | "autoload": { 935 | "psr-4": { 936 | "Sami\\": "Sami/" 937 | } 938 | }, 939 | "notification-url": "https://packagist.org/downloads/", 940 | "license": [ 941 | "MIT" 942 | ], 943 | "authors": [ 944 | { 945 | "name": "Fabien Potencier", 946 | "email": "fabien@symfony.com" 947 | } 948 | ], 949 | "description": "Sami, an API documentation generator", 950 | "homepage": "http://sami.sensiolabs.org", 951 | "keywords": [ 952 | "phpdoc" 953 | ], 954 | "time": "2015-08-30 14:15:00" 955 | }, 956 | { 957 | "name": "sebastian/comparator", 958 | "version": "1.2.0", 959 | "source": { 960 | "type": "git", 961 | "url": "https://github.com/sebastianbergmann/comparator.git", 962 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" 963 | }, 964 | "dist": { 965 | "type": "zip", 966 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", 967 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", 968 | "shasum": "" 969 | }, 970 | "require": { 971 | "php": ">=5.3.3", 972 | "sebastian/diff": "~1.2", 973 | "sebastian/exporter": "~1.2" 974 | }, 975 | "require-dev": { 976 | "phpunit/phpunit": "~4.4" 977 | }, 978 | "type": "library", 979 | "extra": { 980 | "branch-alias": { 981 | "dev-master": "1.2.x-dev" 982 | } 983 | }, 984 | "autoload": { 985 | "classmap": [ 986 | "src/" 987 | ] 988 | }, 989 | "notification-url": "https://packagist.org/downloads/", 990 | "license": [ 991 | "BSD-3-Clause" 992 | ], 993 | "authors": [ 994 | { 995 | "name": "Jeff Welch", 996 | "email": "whatthejeff@gmail.com" 997 | }, 998 | { 999 | "name": "Volker Dusch", 1000 | "email": "github@wallbash.com" 1001 | }, 1002 | { 1003 | "name": "Bernhard Schussek", 1004 | "email": "bschussek@2bepublished.at" 1005 | }, 1006 | { 1007 | "name": "Sebastian Bergmann", 1008 | "email": "sebastian@phpunit.de" 1009 | } 1010 | ], 1011 | "description": "Provides the functionality to compare PHP values for equality", 1012 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1013 | "keywords": [ 1014 | "comparator", 1015 | "compare", 1016 | "equality" 1017 | ], 1018 | "time": "2015-07-26 15:48:44" 1019 | }, 1020 | { 1021 | "name": "sebastian/diff", 1022 | "version": "1.4.1", 1023 | "source": { 1024 | "type": "git", 1025 | "url": "https://github.com/sebastianbergmann/diff.git", 1026 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" 1027 | }, 1028 | "dist": { 1029 | "type": "zip", 1030 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", 1031 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", 1032 | "shasum": "" 1033 | }, 1034 | "require": { 1035 | "php": ">=5.3.3" 1036 | }, 1037 | "require-dev": { 1038 | "phpunit/phpunit": "~4.8" 1039 | }, 1040 | "type": "library", 1041 | "extra": { 1042 | "branch-alias": { 1043 | "dev-master": "1.4-dev" 1044 | } 1045 | }, 1046 | "autoload": { 1047 | "classmap": [ 1048 | "src/" 1049 | ] 1050 | }, 1051 | "notification-url": "https://packagist.org/downloads/", 1052 | "license": [ 1053 | "BSD-3-Clause" 1054 | ], 1055 | "authors": [ 1056 | { 1057 | "name": "Kore Nordmann", 1058 | "email": "mail@kore-nordmann.de" 1059 | }, 1060 | { 1061 | "name": "Sebastian Bergmann", 1062 | "email": "sebastian@phpunit.de" 1063 | } 1064 | ], 1065 | "description": "Diff implementation", 1066 | "homepage": "https://github.com/sebastianbergmann/diff", 1067 | "keywords": [ 1068 | "diff" 1069 | ], 1070 | "time": "2015-12-08 07:14:41" 1071 | }, 1072 | { 1073 | "name": "sebastian/environment", 1074 | "version": "1.3.3", 1075 | "source": { 1076 | "type": "git", 1077 | "url": "https://github.com/sebastianbergmann/environment.git", 1078 | "reference": "6e7133793a8e5a5714a551a8324337374be209df" 1079 | }, 1080 | "dist": { 1081 | "type": "zip", 1082 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df", 1083 | "reference": "6e7133793a8e5a5714a551a8324337374be209df", 1084 | "shasum": "" 1085 | }, 1086 | "require": { 1087 | "php": ">=5.3.3" 1088 | }, 1089 | "require-dev": { 1090 | "phpunit/phpunit": "~4.4" 1091 | }, 1092 | "type": "library", 1093 | "extra": { 1094 | "branch-alias": { 1095 | "dev-master": "1.3.x-dev" 1096 | } 1097 | }, 1098 | "autoload": { 1099 | "classmap": [ 1100 | "src/" 1101 | ] 1102 | }, 1103 | "notification-url": "https://packagist.org/downloads/", 1104 | "license": [ 1105 | "BSD-3-Clause" 1106 | ], 1107 | "authors": [ 1108 | { 1109 | "name": "Sebastian Bergmann", 1110 | "email": "sebastian@phpunit.de" 1111 | } 1112 | ], 1113 | "description": "Provides functionality to handle HHVM/PHP environments", 1114 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1115 | "keywords": [ 1116 | "Xdebug", 1117 | "environment", 1118 | "hhvm" 1119 | ], 1120 | "time": "2015-12-02 08:37:27" 1121 | }, 1122 | { 1123 | "name": "sebastian/exporter", 1124 | "version": "1.2.1", 1125 | "source": { 1126 | "type": "git", 1127 | "url": "https://github.com/sebastianbergmann/exporter.git", 1128 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e" 1129 | }, 1130 | "dist": { 1131 | "type": "zip", 1132 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", 1133 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e", 1134 | "shasum": "" 1135 | }, 1136 | "require": { 1137 | "php": ">=5.3.3", 1138 | "sebastian/recursion-context": "~1.0" 1139 | }, 1140 | "require-dev": { 1141 | "phpunit/phpunit": "~4.4" 1142 | }, 1143 | "type": "library", 1144 | "extra": { 1145 | "branch-alias": { 1146 | "dev-master": "1.2.x-dev" 1147 | } 1148 | }, 1149 | "autoload": { 1150 | "classmap": [ 1151 | "src/" 1152 | ] 1153 | }, 1154 | "notification-url": "https://packagist.org/downloads/", 1155 | "license": [ 1156 | "BSD-3-Clause" 1157 | ], 1158 | "authors": [ 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 | "name": "Sebastian Bergmann", 1173 | "email": "sebastian@phpunit.de" 1174 | }, 1175 | { 1176 | "name": "Adam Harvey", 1177 | "email": "aharvey@php.net" 1178 | } 1179 | ], 1180 | "description": "Provides the functionality to export PHP variables for visualization", 1181 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1182 | "keywords": [ 1183 | "export", 1184 | "exporter" 1185 | ], 1186 | "time": "2015-06-21 07:55:53" 1187 | }, 1188 | { 1189 | "name": "sebastian/global-state", 1190 | "version": "1.1.1", 1191 | "source": { 1192 | "type": "git", 1193 | "url": "https://github.com/sebastianbergmann/global-state.git", 1194 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1195 | }, 1196 | "dist": { 1197 | "type": "zip", 1198 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1199 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1200 | "shasum": "" 1201 | }, 1202 | "require": { 1203 | "php": ">=5.3.3" 1204 | }, 1205 | "require-dev": { 1206 | "phpunit/phpunit": "~4.2" 1207 | }, 1208 | "suggest": { 1209 | "ext-uopz": "*" 1210 | }, 1211 | "type": "library", 1212 | "extra": { 1213 | "branch-alias": { 1214 | "dev-master": "1.0-dev" 1215 | } 1216 | }, 1217 | "autoload": { 1218 | "classmap": [ 1219 | "src/" 1220 | ] 1221 | }, 1222 | "notification-url": "https://packagist.org/downloads/", 1223 | "license": [ 1224 | "BSD-3-Clause" 1225 | ], 1226 | "authors": [ 1227 | { 1228 | "name": "Sebastian Bergmann", 1229 | "email": "sebastian@phpunit.de" 1230 | } 1231 | ], 1232 | "description": "Snapshotting of global state", 1233 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1234 | "keywords": [ 1235 | "global state" 1236 | ], 1237 | "time": "2015-10-12 03:26:01" 1238 | }, 1239 | { 1240 | "name": "sebastian/recursion-context", 1241 | "version": "1.0.2", 1242 | "source": { 1243 | "type": "git", 1244 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1245 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791" 1246 | }, 1247 | "dist": { 1248 | "type": "zip", 1249 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", 1250 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791", 1251 | "shasum": "" 1252 | }, 1253 | "require": { 1254 | "php": ">=5.3.3" 1255 | }, 1256 | "require-dev": { 1257 | "phpunit/phpunit": "~4.4" 1258 | }, 1259 | "type": "library", 1260 | "extra": { 1261 | "branch-alias": { 1262 | "dev-master": "1.0.x-dev" 1263 | } 1264 | }, 1265 | "autoload": { 1266 | "classmap": [ 1267 | "src/" 1268 | ] 1269 | }, 1270 | "notification-url": "https://packagist.org/downloads/", 1271 | "license": [ 1272 | "BSD-3-Clause" 1273 | ], 1274 | "authors": [ 1275 | { 1276 | "name": "Jeff Welch", 1277 | "email": "whatthejeff@gmail.com" 1278 | }, 1279 | { 1280 | "name": "Sebastian Bergmann", 1281 | "email": "sebastian@phpunit.de" 1282 | }, 1283 | { 1284 | "name": "Adam Harvey", 1285 | "email": "aharvey@php.net" 1286 | } 1287 | ], 1288 | "description": "Provides functionality to recursively process PHP variables", 1289 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1290 | "time": "2015-11-11 19:50:13" 1291 | }, 1292 | { 1293 | "name": "sebastian/version", 1294 | "version": "1.0.6", 1295 | "source": { 1296 | "type": "git", 1297 | "url": "https://github.com/sebastianbergmann/version.git", 1298 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 1299 | }, 1300 | "dist": { 1301 | "type": "zip", 1302 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1303 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1304 | "shasum": "" 1305 | }, 1306 | "type": "library", 1307 | "autoload": { 1308 | "classmap": [ 1309 | "src/" 1310 | ] 1311 | }, 1312 | "notification-url": "https://packagist.org/downloads/", 1313 | "license": [ 1314 | "BSD-3-Clause" 1315 | ], 1316 | "authors": [ 1317 | { 1318 | "name": "Sebastian Bergmann", 1319 | "email": "sebastian@phpunit.de", 1320 | "role": "lead" 1321 | } 1322 | ], 1323 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1324 | "homepage": "https://github.com/sebastianbergmann/version", 1325 | "time": "2015-06-21 13:59:46" 1326 | }, 1327 | { 1328 | "name": "symfony/console", 1329 | "version": "v2.8.0", 1330 | "source": { 1331 | "type": "git", 1332 | "url": "https://github.com/symfony/console.git", 1333 | "reference": "d232bfc100dfd32b18ccbcab4bcc8f28697b7e41" 1334 | }, 1335 | "dist": { 1336 | "type": "zip", 1337 | "url": "https://api.github.com/repos/symfony/console/zipball/d232bfc100dfd32b18ccbcab4bcc8f28697b7e41", 1338 | "reference": "d232bfc100dfd32b18ccbcab4bcc8f28697b7e41", 1339 | "shasum": "" 1340 | }, 1341 | "require": { 1342 | "php": ">=5.3.9", 1343 | "symfony/polyfill-mbstring": "~1.0" 1344 | }, 1345 | "require-dev": { 1346 | "psr/log": "~1.0", 1347 | "symfony/event-dispatcher": "~2.1|~3.0.0", 1348 | "symfony/process": "~2.1|~3.0.0" 1349 | }, 1350 | "suggest": { 1351 | "psr/log": "For using the console logger", 1352 | "symfony/event-dispatcher": "", 1353 | "symfony/process": "" 1354 | }, 1355 | "type": "library", 1356 | "extra": { 1357 | "branch-alias": { 1358 | "dev-master": "2.8-dev" 1359 | } 1360 | }, 1361 | "autoload": { 1362 | "psr-4": { 1363 | "Symfony\\Component\\Console\\": "" 1364 | }, 1365 | "exclude-from-classmap": [ 1366 | "/Tests/" 1367 | ] 1368 | }, 1369 | "notification-url": "https://packagist.org/downloads/", 1370 | "license": [ 1371 | "MIT" 1372 | ], 1373 | "authors": [ 1374 | { 1375 | "name": "Fabien Potencier", 1376 | "email": "fabien@symfony.com" 1377 | }, 1378 | { 1379 | "name": "Symfony Community", 1380 | "homepage": "https://symfony.com/contributors" 1381 | } 1382 | ], 1383 | "description": "Symfony Console Component", 1384 | "homepage": "https://symfony.com", 1385 | "time": "2015-11-30 12:35:10" 1386 | }, 1387 | { 1388 | "name": "symfony/filesystem", 1389 | "version": "v2.8.0", 1390 | "source": { 1391 | "type": "git", 1392 | "url": "https://github.com/symfony/filesystem.git", 1393 | "reference": "3e661a0d521ac67496515fa6e6704bd61bcfff60" 1394 | }, 1395 | "dist": { 1396 | "type": "zip", 1397 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/3e661a0d521ac67496515fa6e6704bd61bcfff60", 1398 | "reference": "3e661a0d521ac67496515fa6e6704bd61bcfff60", 1399 | "shasum": "" 1400 | }, 1401 | "require": { 1402 | "php": ">=5.3.9" 1403 | }, 1404 | "type": "library", 1405 | "extra": { 1406 | "branch-alias": { 1407 | "dev-master": "2.8-dev" 1408 | } 1409 | }, 1410 | "autoload": { 1411 | "psr-4": { 1412 | "Symfony\\Component\\Filesystem\\": "" 1413 | }, 1414 | "exclude-from-classmap": [ 1415 | "/Tests/" 1416 | ] 1417 | }, 1418 | "notification-url": "https://packagist.org/downloads/", 1419 | "license": [ 1420 | "MIT" 1421 | ], 1422 | "authors": [ 1423 | { 1424 | "name": "Fabien Potencier", 1425 | "email": "fabien@symfony.com" 1426 | }, 1427 | { 1428 | "name": "Symfony Community", 1429 | "homepage": "https://symfony.com/contributors" 1430 | } 1431 | ], 1432 | "description": "Symfony Filesystem Component", 1433 | "homepage": "https://symfony.com", 1434 | "time": "2015-11-23 10:19:46" 1435 | }, 1436 | { 1437 | "name": "symfony/finder", 1438 | "version": "v2.8.0", 1439 | "source": { 1440 | "type": "git", 1441 | "url": "https://github.com/symfony/finder.git", 1442 | "reference": "ead9b07af4ba77b6507bee697396a5c79e633f08" 1443 | }, 1444 | "dist": { 1445 | "type": "zip", 1446 | "url": "https://api.github.com/repos/symfony/finder/zipball/ead9b07af4ba77b6507bee697396a5c79e633f08", 1447 | "reference": "ead9b07af4ba77b6507bee697396a5c79e633f08", 1448 | "shasum": "" 1449 | }, 1450 | "require": { 1451 | "php": ">=5.3.9" 1452 | }, 1453 | "type": "library", 1454 | "extra": { 1455 | "branch-alias": { 1456 | "dev-master": "2.8-dev" 1457 | } 1458 | }, 1459 | "autoload": { 1460 | "psr-4": { 1461 | "Symfony\\Component\\Finder\\": "" 1462 | }, 1463 | "exclude-from-classmap": [ 1464 | "/Tests/" 1465 | ] 1466 | }, 1467 | "notification-url": "https://packagist.org/downloads/", 1468 | "license": [ 1469 | "MIT" 1470 | ], 1471 | "authors": [ 1472 | { 1473 | "name": "Fabien Potencier", 1474 | "email": "fabien@symfony.com" 1475 | }, 1476 | { 1477 | "name": "Symfony Community", 1478 | "homepage": "https://symfony.com/contributors" 1479 | } 1480 | ], 1481 | "description": "Symfony Finder Component", 1482 | "homepage": "https://symfony.com", 1483 | "time": "2015-10-30 20:15:42" 1484 | }, 1485 | { 1486 | "name": "symfony/polyfill-mbstring", 1487 | "version": "v1.0.0", 1488 | "source": { 1489 | "type": "git", 1490 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1491 | "reference": "0b6a8940385311a24e060ec1fe35680e17c74497" 1492 | }, 1493 | "dist": { 1494 | "type": "zip", 1495 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0b6a8940385311a24e060ec1fe35680e17c74497", 1496 | "reference": "0b6a8940385311a24e060ec1fe35680e17c74497", 1497 | "shasum": "" 1498 | }, 1499 | "require": { 1500 | "php": ">=5.3.3" 1501 | }, 1502 | "type": "library", 1503 | "extra": { 1504 | "branch-alias": { 1505 | "dev-master": "1.0-dev" 1506 | } 1507 | }, 1508 | "autoload": { 1509 | "psr-4": { 1510 | "Symfony\\Polyfill\\Mbstring\\": "" 1511 | }, 1512 | "files": [ 1513 | "bootstrap.php" 1514 | ] 1515 | }, 1516 | "notification-url": "https://packagist.org/downloads/", 1517 | "license": [ 1518 | "MIT" 1519 | ], 1520 | "authors": [ 1521 | { 1522 | "name": "Nicolas Grekas", 1523 | "email": "p@tchwork.com" 1524 | }, 1525 | { 1526 | "name": "Symfony Community", 1527 | "homepage": "https://symfony.com/contributors" 1528 | } 1529 | ], 1530 | "description": "Symfony polyfill for the Mbstring extension", 1531 | "homepage": "https://symfony.com", 1532 | "keywords": [ 1533 | "compatibility", 1534 | "mbstring", 1535 | "polyfill", 1536 | "portable", 1537 | "shim" 1538 | ], 1539 | "time": "2015-11-04 20:28:58" 1540 | }, 1541 | { 1542 | "name": "symfony/process", 1543 | "version": "v2.8.0", 1544 | "source": { 1545 | "type": "git", 1546 | "url": "https://github.com/symfony/process.git", 1547 | "reference": "1b988a88e3551102f3c2d9e1d47a18c3a78d6312" 1548 | }, 1549 | "dist": { 1550 | "type": "zip", 1551 | "url": "https://api.github.com/repos/symfony/process/zipball/1b988a88e3551102f3c2d9e1d47a18c3a78d6312", 1552 | "reference": "1b988a88e3551102f3c2d9e1d47a18c3a78d6312", 1553 | "shasum": "" 1554 | }, 1555 | "require": { 1556 | "php": ">=5.3.9" 1557 | }, 1558 | "type": "library", 1559 | "extra": { 1560 | "branch-alias": { 1561 | "dev-master": "2.8-dev" 1562 | } 1563 | }, 1564 | "autoload": { 1565 | "psr-4": { 1566 | "Symfony\\Component\\Process\\": "" 1567 | }, 1568 | "exclude-from-classmap": [ 1569 | "/Tests/" 1570 | ] 1571 | }, 1572 | "notification-url": "https://packagist.org/downloads/", 1573 | "license": [ 1574 | "MIT" 1575 | ], 1576 | "authors": [ 1577 | { 1578 | "name": "Fabien Potencier", 1579 | "email": "fabien@symfony.com" 1580 | }, 1581 | { 1582 | "name": "Symfony Community", 1583 | "homepage": "https://symfony.com/contributors" 1584 | } 1585 | ], 1586 | "description": "Symfony Process Component", 1587 | "homepage": "https://symfony.com", 1588 | "time": "2015-11-30 12:35:10" 1589 | }, 1590 | { 1591 | "name": "symfony/yaml", 1592 | "version": "v2.8.0", 1593 | "source": { 1594 | "type": "git", 1595 | "url": "https://github.com/symfony/yaml.git", 1596 | "reference": "f79824187de95064a2f5038904c4d7f0227fedb5" 1597 | }, 1598 | "dist": { 1599 | "type": "zip", 1600 | "url": "https://api.github.com/repos/symfony/yaml/zipball/f79824187de95064a2f5038904c4d7f0227fedb5", 1601 | "reference": "f79824187de95064a2f5038904c4d7f0227fedb5", 1602 | "shasum": "" 1603 | }, 1604 | "require": { 1605 | "php": ">=5.3.9" 1606 | }, 1607 | "type": "library", 1608 | "extra": { 1609 | "branch-alias": { 1610 | "dev-master": "2.8-dev" 1611 | } 1612 | }, 1613 | "autoload": { 1614 | "psr-4": { 1615 | "Symfony\\Component\\Yaml\\": "" 1616 | }, 1617 | "exclude-from-classmap": [ 1618 | "/Tests/" 1619 | ] 1620 | }, 1621 | "notification-url": "https://packagist.org/downloads/", 1622 | "license": [ 1623 | "MIT" 1624 | ], 1625 | "authors": [ 1626 | { 1627 | "name": "Fabien Potencier", 1628 | "email": "fabien@symfony.com" 1629 | }, 1630 | { 1631 | "name": "Symfony Community", 1632 | "homepage": "https://symfony.com/contributors" 1633 | } 1634 | ], 1635 | "description": "Symfony Yaml Component", 1636 | "homepage": "https://symfony.com", 1637 | "time": "2015-11-30 12:35:10" 1638 | }, 1639 | { 1640 | "name": "twig/twig", 1641 | "version": "v1.23.1", 1642 | "source": { 1643 | "type": "git", 1644 | "url": "https://github.com/twigphp/Twig.git", 1645 | "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6" 1646 | }, 1647 | "dist": { 1648 | "type": "zip", 1649 | "url": "https://api.github.com/repos/twigphp/Twig/zipball/d9b6333ae8dd2c8e3fd256e127548def0bc614c6", 1650 | "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6", 1651 | "shasum": "" 1652 | }, 1653 | "require": { 1654 | "php": ">=5.2.7" 1655 | }, 1656 | "require-dev": { 1657 | "symfony/debug": "~2.7", 1658 | "symfony/phpunit-bridge": "~2.7" 1659 | }, 1660 | "type": "library", 1661 | "extra": { 1662 | "branch-alias": { 1663 | "dev-master": "1.23-dev" 1664 | } 1665 | }, 1666 | "autoload": { 1667 | "psr-0": { 1668 | "Twig_": "lib/" 1669 | } 1670 | }, 1671 | "notification-url": "https://packagist.org/downloads/", 1672 | "license": [ 1673 | "BSD-3-Clause" 1674 | ], 1675 | "authors": [ 1676 | { 1677 | "name": "Fabien Potencier", 1678 | "email": "fabien@symfony.com", 1679 | "homepage": "http://fabien.potencier.org", 1680 | "role": "Lead Developer" 1681 | }, 1682 | { 1683 | "name": "Armin Ronacher", 1684 | "email": "armin.ronacher@active-4.com", 1685 | "role": "Project Founder" 1686 | }, 1687 | { 1688 | "name": "Twig Team", 1689 | "homepage": "http://twig.sensiolabs.org/contributors", 1690 | "role": "Contributors" 1691 | } 1692 | ], 1693 | "description": "Twig, the flexible, fast, and secure template language for PHP", 1694 | "homepage": "http://twig.sensiolabs.org", 1695 | "keywords": [ 1696 | "templating" 1697 | ], 1698 | "time": "2015-11-05 12:49:06" 1699 | } 1700 | ], 1701 | "aliases": [], 1702 | "minimum-stability": "stable", 1703 | "stability-flags": { 1704 | "eloquent/phony": 20, 1705 | "icecave/archer": 20 1706 | }, 1707 | "prefer-stable": false, 1708 | "prefer-lowest": false, 1709 | "platform": { 1710 | "php": ">=5.3" 1711 | }, 1712 | "platform-dev": [] 1713 | } 1714 | -------------------------------------------------------------------------------- /src/Asplode.php: -------------------------------------------------------------------------------- 1 | A tuple containing the installed error handler and fatal error handler. 31 | * @throws ErrorHandlingConfigurationException If the error reporting level is incorrectly configured. 32 | */ 33 | public static function install( 34 | $reservedMemory = 1048576, 35 | Isolator $isolator = null 36 | ) { 37 | $fatalHandler = static::installFatalHandler($reservedMemory, $isolator); 38 | 39 | return array(static::installErrorHandler($isolator), $fatalHandler); 40 | } 41 | 42 | /** 43 | * Installs a new error handler. 44 | * 45 | * @param Isolator|null $isolator The isolator to use. 46 | * 47 | * @return ErrorHandlerInterface The installed error handler. 48 | * @throws ErrorHandlingConfigurationException If the error reporting level is incorrectly configured. 49 | */ 50 | public static function installErrorHandler(Isolator $isolator = null) 51 | { 52 | $handler = new ErrorHandler(null, $isolator); 53 | $handler->install(); 54 | 55 | return $handler; 56 | } 57 | 58 | /** 59 | * Installs a new fatal error handler. 60 | * 61 | * This handler will, on shutdown, detect any installed exception handler, 62 | * and pass an exception representing any fatal errors to said handler. 63 | * 64 | * @param integer $reservedMemory The amount of memory to reserve for fatal error handling. 65 | * @param Isolator|null $isolator The isolator to use. 66 | * 67 | * @return FatalErrorHandlerInterface The installed fatal error handler. 68 | */ 69 | public static function installFatalHandler( 70 | $reservedMemory = 1048576, 71 | Isolator $isolator = null 72 | ) { 73 | $handler = new FatalErrorHandler(null, $isolator); 74 | $handler->install($reservedMemory); 75 | 76 | return $handler; 77 | } 78 | 79 | /** 80 | * Asserts that an error handling is configured in a way that is compatible 81 | * with code expecting error exceptions. 82 | * 83 | * @param Isolator|null $isolator The isolator to use. 84 | * 85 | * @throws ErrorHandlingConfigurationException If error handling is not configured correctly. 86 | */ 87 | public static function assertCompatibleHandler(Isolator $isolator = null) 88 | { 89 | $isolator = Isolator::get($isolator); 90 | $message = 'Error handling is incorrectly configured.'; 91 | 92 | try { 93 | $isolator->trigger_error($message, E_USER_NOTICE); 94 | } catch (ErrorException $e) { 95 | if ( 96 | $e->getMessage() === $message && 97 | $e->getSeverity() === E_USER_NOTICE 98 | ) { 99 | return; 100 | } 101 | } 102 | 103 | throw new ErrorHandlingConfigurationException(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Error/AbstractErrorException.php: -------------------------------------------------------------------------------- 1 | getProperty('file'); 52 | $fileProperty->setAccessible(true); 53 | $lineProperty = $reflector->getProperty('line'); 54 | $lineProperty->setAccessible(true); 55 | $traceProperty = $reflector->getProperty('trace'); 56 | $traceProperty->setAccessible(true); 57 | 58 | $fileProperty->setValue($this, $path); 59 | $lineProperty->setValue($this, $lineNumber); 60 | 61 | $trace = $this->getTrace(); 62 | 63 | foreach ($trace as $index => $call) { 64 | if ( 65 | isset($call['class']) && 66 | 0 === strpos($call['class'], 'Eloquent\Asplode\\') 67 | ) { 68 | unset($trace[$index]); 69 | } 70 | } 71 | 72 | $traceProperty->setValue($this, $trace); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Error/ErrorException.php: -------------------------------------------------------------------------------- 1 | isolator = Isolator::get($isolator); 39 | 40 | if (null === $stack) { 41 | $stack = new ErrorHandlerStack($isolator); 42 | } 43 | 44 | $this->setFallbackHandler(); 45 | $this->stack = $stack; 46 | } 47 | 48 | /** 49 | * Get the error handler stack. 50 | * 51 | * @return HandlerStack\HandlerStackInterface The error handler stack. 52 | */ 53 | public function stack() 54 | { 55 | return $this->stack; 56 | } 57 | 58 | /** 59 | * Set an error handler to use as a fallback for errors that are not handled 60 | * by Asplode. 61 | * 62 | * Errors not handled by Asplode include deprecation messages, and '@' 63 | * suppressed errors. 64 | * 65 | * @param callable|null $fallbackHandler The fallback handler to use, or null to use the default PHP handler. 66 | */ 67 | public function setFallbackHandler($fallbackHandler = null) 68 | { 69 | if (null === $fallbackHandler) { 70 | $fallbackHandler = function () { 71 | return false; 72 | }; 73 | } 74 | 75 | $this->fallbackHandler = $fallbackHandler; 76 | } 77 | 78 | /** 79 | * Get the error handler used as a fallback for errors that are not handled 80 | * by Asplode. 81 | * 82 | * @return callable The fallback error handler. 83 | */ 84 | public function fallbackHandler() 85 | { 86 | return $this->fallbackHandler; 87 | } 88 | 89 | /** 90 | * Installs this error handler. 91 | * 92 | * @throws AlreadyInstalledException If this error handler is already the top-most handler on the stack. 93 | * @throws ErrorHandlingConfigurationException If the error reporting level is incorrectly configured. 94 | */ 95 | public function install() 96 | { 97 | if (0 === $this->isolator->error_reporting()) { 98 | throw new ErrorHandlingConfigurationException(); 99 | } 100 | 101 | if ($this->isInstalled()) { 102 | throw new AlreadyInstalledException(); 103 | } 104 | 105 | $this->stack->push($this); 106 | } 107 | 108 | /** 109 | * Uninstalls this error handler. 110 | * 111 | * @throws NotInstalledException If this error handler is not the top-most handler on the stack. 112 | */ 113 | public function uninstall() 114 | { 115 | $handler = $this->stack->pop(); 116 | 117 | if ($handler !== $this) { 118 | if (null !== $handler) { 119 | $this->stack->push($handler); 120 | } 121 | 122 | throw new NotInstalledException(); 123 | } 124 | } 125 | 126 | /** 127 | * Returns true if this error handler is the top-most handler on the stack. 128 | * 129 | * @return boolean True if this error handler is the top-most handler on the stack. 130 | */ 131 | public function isInstalled() 132 | { 133 | return $this->stack->handler() === $this; 134 | } 135 | 136 | /** 137 | * Handles a PHP error. 138 | * 139 | * @param integer $severity The severity of the error. 140 | * @param string $message The error message. 141 | * @param string $filename The filename in which the error was raised. 142 | * @param integer $lineno The line number in which the error was raised. 143 | * 144 | * @return boolean False if the error is a deprecation message, or '@' suppression is in use. 145 | * @throws NonFatalErrorExceptionInterface Representing the error, unless the error is a deprecation message, or '@' suppression is in use. 146 | */ 147 | public function handle($severity, $message, $filename, $lineno) 148 | { 149 | if ( 150 | E_DEPRECATED === $severity || 151 | E_USER_DEPRECATED === $severity || 152 | 0 === $this->isolator->error_reporting() 153 | ) { 154 | $fallbackHandler = $this->fallbackHandler(); 155 | 156 | return $fallbackHandler($severity, $message, $filename, $lineno); 157 | } 158 | 159 | throw new ErrorException($message, $severity, $filename, $lineno); 160 | } 161 | 162 | /** 163 | * Handles a PHP error. 164 | * 165 | * @param integer $severity The severity of the error. 166 | * @param string $message The error message. 167 | * @param string $filename The filename in which the error was raised. 168 | * @param integer $lineno The line number in which the error was raised. 169 | * 170 | * @return boolean False if the error is a deprecation message, or '@' suppression is in use. 171 | * @throws NonFatalErrorExceptionInterface Representing the error, unless the error is a deprecation message, or '@' suppression is in use. 172 | */ 173 | public function __invoke($severity, $message, $filename, $lineno) 174 | { 175 | return $this->handle($severity, $message, $filename, $lineno); 176 | } 177 | 178 | private $stack; 179 | private $fallbackHandler; 180 | private $isolator; 181 | } 182 | -------------------------------------------------------------------------------- /src/ErrorHandlerInterface.php: -------------------------------------------------------------------------------- 1 | isolator = Isolator::get($isolator); 37 | 38 | if (null === $stack) { 39 | $stack = new ExceptionHandlerStack($isolator); 40 | } 41 | 42 | $this->stack = $stack; 43 | $this->isRegistered = false; 44 | $this->isEnabled = false; 45 | } 46 | 47 | /** 48 | * Get the exception handler stack. 49 | * 50 | * @return HandlerStackInterface The exception handler stack. 51 | */ 52 | public function stack() 53 | { 54 | return $this->stack; 55 | } 56 | 57 | /** 58 | * Installs this fatal error handler. 59 | * 60 | * @param integer $reservedMemory The amount of memory to reserve for fatal error handling. 61 | * 62 | * @throws AlreadyInstalledException If this fatal error handler is already installed. 63 | */ 64 | public function install($reservedMemory = 1048576) 65 | { 66 | if ($this->isEnabled) { 67 | throw new AlreadyInstalledException(); 68 | } 69 | 70 | if (!$this->isRegistered) { 71 | $this->reservedMemory = 72 | $this->isolator->str_repeat(' ', $reservedMemory); 73 | $this->isolator 74 | ->class_exists('Eloquent\Asplode\Error\FatalErrorException'); 75 | $this->isolator->register_shutdown_function($this); 76 | $this->isRegistered = true; 77 | } 78 | 79 | $this->isEnabled = true; 80 | } 81 | 82 | /** 83 | * Uninstalls this fatal error handler. 84 | * 85 | * @throws NotInstalledException If this fatal error handler is not installed. 86 | */ 87 | public function uninstall() 88 | { 89 | if (!$this->isEnabled) { 90 | throw new NotInstalledException(); 91 | } 92 | 93 | $this->isEnabled = false; 94 | } 95 | 96 | /** 97 | * Returns true if this fatal error handler is installed. 98 | * 99 | * @return boolean True if this fatal error handler is installed. 100 | */ 101 | public function isInstalled() 102 | { 103 | return $this->isRegistered && $this->isEnabled; 104 | } 105 | 106 | /** 107 | * Handles PHP shutdown, and produces exceptions for any detected fatal 108 | * error. 109 | * 110 | * This function will not actually throw any exceptions. If an installed 111 | * exception handler is detected, it will create an exception representing 112 | * the fatal error, and pass it to the installed exception handler. 113 | */ 114 | public function handle() 115 | { 116 | if (!$this->isEnabled) { 117 | return; 118 | } 119 | 120 | $this->reservedMemory = ''; 121 | $error = $this->isolator->error_get_last(); 122 | 123 | if (null === $error) { 124 | return; 125 | } 126 | 127 | $handler = $this->stack->handler(); 128 | 129 | if (null === $handler) { 130 | return; 131 | } 132 | 133 | $handler( 134 | new FatalErrorException( 135 | $error['message'], 136 | $error['type'], 137 | $error['file'], 138 | $error['line'] 139 | ) 140 | ); 141 | } 142 | 143 | /** 144 | * Handles PHP shutdown, and produces exceptions for any detected fatal 145 | * error. 146 | * 147 | * This function will not actually throw any exceptions. If an installed 148 | * exception handler is detected, it will create an exception representing 149 | * the fatal error, and pass it to the installed exception handler. 150 | */ 151 | public function __invoke() 152 | { 153 | $this->handle(); 154 | } 155 | 156 | private $stack; 157 | private $isolator; 158 | private $isRegistered; 159 | private $isEnabled; 160 | private $reservedMemory; 161 | } 162 | -------------------------------------------------------------------------------- /src/FatalErrorHandlerInterface.php: -------------------------------------------------------------------------------- 1 | isolator = Isolator::get($isolator); 30 | } 31 | 32 | /** 33 | * Gets the current handler without removing it from the stack. 34 | * 35 | * @return callable|null The current handler. 36 | */ 37 | public function handler() 38 | { 39 | $handler = $this->pop(); 40 | 41 | if (null !== $handler) { 42 | $this->push($handler); 43 | } 44 | 45 | return $handler; 46 | } 47 | 48 | /** 49 | * Gets the current handler stack without changing the stack. 50 | * 51 | * @return array The current handler stack. 52 | */ 53 | public function handlerStack() 54 | { 55 | $this->pushAll($handlers = $this->clear()); 56 | 57 | return $handlers; 58 | } 59 | 60 | /** 61 | * Pushes multiple handlers on to the stack. 62 | * 63 | * @param array $handlers The handlers to push on to the stack. 64 | */ 65 | public function pushAll(array $handlers) 66 | { 67 | array_map(array($this, 'push'), $handlers); 68 | } 69 | 70 | /** 71 | * Removes all handlers from the stack. 72 | * 73 | * @return array The removed handlers. 74 | */ 75 | public function clear() 76 | { 77 | $handlers = array(); 78 | 79 | while (null !== ($handler = $this->pop())) { 80 | $handlers[] = $handler; 81 | } 82 | 83 | return $handlers; 84 | } 85 | 86 | /** 87 | * Restores a stack of handlers. 88 | * 89 | * @param array $handlers The handlers to restore. 90 | */ 91 | public function restore(array $handlers) 92 | { 93 | $this->clear(); 94 | $this->pushAll($handlers); 95 | } 96 | 97 | /** 98 | * Temporarily bypass the current handler stack and execute a callable with 99 | * the supplied handler. 100 | * 101 | * This method is useful for executing PHP code that relies upon handling 102 | * techniques that are incompatible with Asplode 103 | * 104 | * @param callable $callable The callable to invoke. 105 | * @param callable|null $handler The handler to use. 106 | * 107 | * @return mixed The result of the callable's invocation. 108 | * @throws Exception If the callable throws an exception. 109 | */ 110 | public function executeWith($callable, $handler = null) 111 | { 112 | $handlers = $this->clear(); 113 | 114 | if (null !== $handler) { 115 | $this->push($handler); 116 | } 117 | 118 | $error = null; 119 | 120 | try { 121 | $result = $callable(); 122 | } catch (Exception $error) { 123 | // re-thrown after handlers are restored 124 | } 125 | 126 | $this->restore($handlers); 127 | 128 | if (null !== $error) { 129 | throw $error; 130 | } 131 | 132 | return $result; 133 | } 134 | 135 | protected $isolator; 136 | } 137 | -------------------------------------------------------------------------------- /src/HandlerStack/ErrorHandlerStack.php: -------------------------------------------------------------------------------- 1 | isolator->set_error_handler($handler); 29 | } 30 | 31 | /** 32 | * Pops a handler off the stack. 33 | * 34 | * @return callable|null The handler that was removed from the stack, or null if the stack is empty. 35 | */ 36 | public function pop() 37 | { 38 | $handler = $this->isolator->set_error_handler(function () {}); 39 | 40 | if (null !== $handler) { 41 | $this->isolator->restore_error_handler(); 42 | } 43 | 44 | $this->isolator->restore_error_handler(); 45 | 46 | return $handler; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/HandlerStack/ExceptionHandlerStack.php: -------------------------------------------------------------------------------- 1 | isolator->set_exception_handler($handler); 29 | } 30 | 31 | /** 32 | * Pops a handler off the stack. 33 | * 34 | * @return callable|null The handler that was removed from the stack, or null if the stack is empty. 35 | */ 36 | public function pop() 37 | { 38 | $handler = $this->isolator->set_exception_handler(function () {}); 39 | if (null !== $handler) { 40 | $this->isolator->restore_exception_handler(); 41 | } 42 | 43 | $this->isolator->restore_exception_handler(); 44 | 45 | return $handler; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/HandlerStack/HandlerStackInterface.php: -------------------------------------------------------------------------------- 1 | The current handler stack. 30 | */ 31 | public function handlerStack(); 32 | 33 | /** 34 | * Pushes a handler on to the stack. 35 | * 36 | * @param callable $handler The handler to push on to the stack. 37 | */ 38 | public function push($handler); 39 | 40 | /** 41 | * Pushes multiple handlers on to the stack. 42 | * 43 | * @param array $handlers The handlers to push on to the stack. 44 | */ 45 | public function pushAll(array $handlers); 46 | 47 | /** 48 | * Pops a handler off the stack. 49 | * 50 | * @return callable|null The handler that was removed from the stack, or null if the stack is empty. 51 | */ 52 | public function pop(); 53 | 54 | /** 55 | * Removes all handlers from the stack. 56 | * 57 | * @return array The removed handlers. 58 | */ 59 | public function clear(); 60 | 61 | /** 62 | * Restores a stack of handlers. 63 | * 64 | * @param array $handlers The handlers to restore. 65 | */ 66 | public function restore(array $handlers); 67 | 68 | /** 69 | * Temporarily bypass the current handler stack and execute a callable with 70 | * the supplied handler. 71 | * 72 | * This method is useful for executing PHP code that relies upon handling 73 | * techniques that are incompatible with Asplode 74 | * 75 | * @param callable $callable The callable to invoke. 76 | * @param callable|null $handler The handler to use. 77 | * 78 | * @return mixed The result of the callable's invocation. 79 | * @throws Exception If the callable throws an exception. 80 | */ 81 | public function executeWith($callable, $handler = null); 82 | } 83 | --------------------------------------------------------------------------------