permit fun with spaces

This commit is contained in:
Gnieark 2018-03-26 21:57:35 +02:00
parent 4e3f67c36c
commit 00ee751d6f
9459 changed files with 1138605 additions and 7 deletions

View File

@ -7,6 +7,7 @@
* @category Template * @category Template
* @package TplBlock * @package TplBlock
* @author gnieark <gnieark@tinad.fr> * @author gnieark <gnieark@tinad.fr>
* @link https://blog-du-grouik.tinad.fr
* @license GNU General Public License V3 * @license GNU General Public License V3
* @link https://github.com/gnieark/tplBlock/ * @link https://github.com/gnieark/tplBlock/
*/ */
@ -28,28 +29,28 @@ class TplBlock
* *
* @var string * @var string
*/ */
const BLOCKSTARTSTART = '<!-- BEGIN '; const BLOCKSTARTSTART = '<!--\s+BEGIN\s+';
/** /**
* The string ending a block start. * The string ending a block start.
* *
* @var string * @var string
*/ */
const BLOCKSTARTEND = ' -->'; const BLOCKSTARTEND = '\s+-->';
/** /**
* The string starting a block end. * The string starting a block end.
* *
* @var string * @var string
*/ */
const BLOCKENDSTART = '<!-- END '; const BLOCKENDSTART = '<!--\s+END\s+';
/** /**
* The string ending a block end. * The string ending a block end.
* *
* @var string * @var string
*/ */
const BLOCKENDEND = ' -->'; const BLOCKENDEND = '\s+-->';
/** /**
* The string starting an enclosure. * The string starting an enclosure.
@ -214,7 +215,7 @@ class TplBlock
* @return string message * @return string message
*/ */
public function checkConsistency($str){ public function checkConsistency($str){
return 1; return 1;
} }

4143
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
hello {{title}} {{name}} {{firstname}} hello {{title}} {{name}} {{firstname}}
The first primes numbers are: The first primes numbers are:
<!-- BEGIN primes --> <!-- BEGIN primes -->
- {{primes.number}} - {{primes.number}}
<!-- END primes --> <!-- END primes -->
Lets list all divisors of: Lets list all divisors of:

View File

@ -116,6 +116,33 @@ class TplBlockTest extends TestCase
$this->assertFalse(strpos("WONT", $actual)); $this->assertFalse(strpos("WONT", $actual));
} }
/**
* Test blocs with tabs spaces etc..
*
* @return void
*/
public function testBlocsWithsWeirdSpaces()
{
$model = "
Bhah blah wpooie456
<!-- BEGIN bloc -->
have to be shown
<!-- END bloc -->
<!-- BEGIN blocTwo -->
WONT to be shown
<!-- END blocTwo -->
";
$template = new TplBlock();
$actual = $template
->addSubBlock(new TplBlock("bloc"))
->applyTplStr($model);
$this->assertContains("have", $actual);
$this->assertFalse(strpos("WONT", $actual));
}
/** /**
* Test if error on blocks names WTF. * Test if error on blocks names WTF.
* *

7
vendor/autoload.php vendored Normal file
View File

@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit0e1e438512d55b8565ec2867ac0ed110::getLoader();

1
vendor/bin/jsonlint vendored Symbolic link
View File

@ -0,0 +1 @@
../seld/jsonlint/bin/jsonlint

1
vendor/bin/pdepend vendored Symbolic link
View File

@ -0,0 +1 @@
../pdepend/pdepend/src/bin/pdepend

1
vendor/bin/phpcbf vendored Symbolic link
View File

@ -0,0 +1 @@
../gamegos/php-code-sniffer/bin/phpcbf

1
vendor/bin/phpcs vendored Symbolic link
View File

@ -0,0 +1 @@
../gamegos/php-code-sniffer/bin/phpcs

1
vendor/bin/phpcs-pre-commit vendored Symbolic link
View File

@ -0,0 +1 @@
../gamegos/php-code-sniffer/bin/phpcs-pre-commit

1
vendor/bin/phpdoc vendored Symbolic link
View File

@ -0,0 +1 @@
../phpdocumentor/phpdocumentor/bin/phpdoc

1
vendor/bin/phpdoc.php vendored Symbolic link
View File

@ -0,0 +1 @@
../phpdocumentor/phpdocumentor/bin/phpdoc.php

1
vendor/bin/phpmd vendored Symbolic link
View File

@ -0,0 +1 @@
../phpmd/phpmd/src/bin/phpmd

1
vendor/bin/phpunit vendored Symbolic link
View File

@ -0,0 +1 @@
../phpunit/phpunit/phpunit

1
vendor/bin/validate-json vendored Symbolic link
View File

@ -0,0 +1 @@
../justinrainbow/json-schema/bin/validate-json

7
vendor/cilex/cilex/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
vendor
phpunit.xml
cilex.phar
.idea
composer.phar
.vagrant
docs/.build

View File

@ -0,0 +1,32 @@
group { "puppet":
ensure => "present",
}
node default {
exec { "apt-get update":
command => "/usr/bin/apt-get update"
}
package{["git", "python-setuptools", "wget", "make", "texlive-latex-recommended", "texlive-latex-extra", "texlive-fonts-recommended", "openjdk-6-jre", "php5-cli", "php5-xdebug"]:
ensure => present,
require => Exec["apt-get update"]
}
exec { "sudo easy_install -U sphinx":
command => "/usr/bin/sudo /usr/bin/easy_install -U sphinx",
require => [ Package["python-setuptools"] ],
timeout => 0
}
exec { "get-composer":
command => "/usr/bin/wget -N http://getcomposer.org/composer.phar",
require => Package["wget"],
cwd => "/vagrant"
}
exec { "composer-install":
command => "/usr/bin/php composer.phar install --dev",
require => Exec["get-composer"],
cwd => "/vagrant"
}
}

13
vendor/cilex/cilex/.travis.yml vendored Normal file
View File

@ -0,0 +1,13 @@
language: php
php:
- 5.3
- 5.4
before_script:
- composer install
script: phpunit --coverage-text
notifications:
email:
- mike.vanriel@naenius.com

19
vendor/cilex/cilex/LICENSE vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2012 Mike van Riel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

70
vendor/cilex/cilex/README.md vendored Normal file
View File

@ -0,0 +1,70 @@
Cilex, a simple Command Line Interface framework
================================================
Cilex is a simple command line application framework to develop simple tools
based on [Symfony2][1] components:
```php
<?php
require_once __DIR__.'/cilex.phar';
$app = new \Cilex\Application('Cilex');
$app->command(new \Cilex\Command\GreetCommand());
$app->run();
```
Cilex works with PHP 5.3.3 or later and is heavily inspired on the [Silex][2]
web micro-framework by Fabien Potencier.
## Installation
1. `git clone` _this_ repository.
2. Download composer: `curl -s https://getcomposer.org/installer | php`
3. Install Cilex' dependencies: `php composer.phar install`
4. Create the phar: `php ./compile`
<!--
## More Information
Read the [documentation][4] for more information.
-->
## Usage
- Download composer: `curl -s https://getcomposer.org/installer | php`
- Add to your dependencies: `php composer.phar require cilex/cilex dev-master`
- Update the dependencies
- Create a `run.php` file
```php
<?php
if (!$loader = include __DIR__.'/vendor/autoload.php') {
die('You must set up the project dependencies.');
}
$app = new \Cilex\Application('Cilex');
$app->command(new \Cilex\Command\GreetCommand());
$app->run();
```
- `php run.php`
- enjoy a lot.
## License
Cilex is licensed under the MIT license.
[1]: http://symfony.com
[2]: http://silex.sensiolabs.org
[3]: http://cilex.github.com/get/cilex.phar
[4]: http://cilex.github.com/documentation
## FAQ
Q: How do I pass configuration into the application?
A: You can do this by adding the following line, where $configPath is the path to the configuration file you want to use:
```php
$app->register(new \Cilex\Provider\ConfigServiceProvider(), array('config.path' => $configPath));
```
The formats currently supported are: YAML, XML and JSON

13
vendor/cilex/cilex/Vagrantfile vendored Normal file
View File

@ -0,0 +1,13 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant::Config.run do |config|
config.vm.box = "precise64"
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
config.vm.provision :puppet do |puppet|
puppet.manifests_path = ".puppet/manifests"
puppet.manifest_file = "manifest.pp"
puppet.options = [ '--verbose' ]
end
end

13
vendor/cilex/cilex/bin/compile vendored Normal file
View File

@ -0,0 +1,13 @@
#!/usr/bin/env php
<?php
$autoload = __DIR__ . '/../vendor/autoload.php';
if (!file_exists($autoload)) {
echo "Please run `php composer.phar install` first." . PHP_EOL;
exit(1);
}
require_once $autoload;
use Cilex\Compiler;
$compiler = new Compiler();
$compiler->compile();

32
vendor/cilex/cilex/composer.json vendored Normal file
View File

@ -0,0 +1,32 @@
{
"name": "cilex/cilex",
"description": "The PHP micro-framework for Command line tools based on the Symfony2 Components",
"keywords": ["microframework","cli"],
"homepage": "http://cilex.github.com",
"license": "MIT",
"autoload":{
"psr-0":{ "Cilex": "src/" }
},
"authors":[
{ "name": "Mike van Riel", "email": "mike.vanriel@naenius.com" }
],
"require":{
"php": ">=5.3.3",
"pimple/pimple": "~1.0",
"symfony/process": "~2.1",
"symfony/finder": "~2.1",
"cilex/console-service-provider": "1.*"
},
"require-dev":{
"symfony/validator": "~2.1",
"phpunit/phpunit": "3.7.*"
},
"suggest":{
"monolog/monolog": ">=1.0.0",
"symfony/yaml": ">=1.0.0",
"symfony/validator": ">=1.0.0"
},
"extra":{
"branch-alias": { "dev-master": "1.0-dev" }
}
}

884
vendor/cilex/cilex/composer.lock generated vendored Normal file
View File

@ -0,0 +1,884 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "028ed7b39a4c2a5ccba9e34589868ee4",
"packages": [
{
"name": "cilex/console-service-provider",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/Cilex/console-service-provider.git",
"reference": "1.0.0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Cilex/console-service-provider/zipball/1.0.0",
"reference": "1.0.0",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"pimple/pimple": "1.*@dev",
"symfony/console": "~2.1"
},
"require-dev": {
"cilex/cilex": "1.*@dev",
"silex/silex": "1.*@dev"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-0": {
"Cilex\\Provider\\Console": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Beau Simensen",
"email": "beau@dflydev.com",
"homepage": "http://beausimensen.com"
},
{
"name": "Mike van Riel",
"email": "mike.vanriel@naenius.com"
}
],
"description": "Console Service Provider",
"keywords": [
"cilex",
"console",
"pimple",
"service-provider",
"silex"
],
"time": "2012-12-19 10:50:58"
},
{
"name": "pimple/pimple",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/fabpot/Pimple.git",
"reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fabpot/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d",
"reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-0": {
"Pimple": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
}
],
"description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
"homepage": "http://pimple.sensiolabs.org",
"keywords": [
"container",
"dependency injection"
],
"time": "2013-11-22 08:30:29"
},
{
"name": "symfony/console",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
"reference": "940f217cbc3c8a33e5403e7c595495c4884400fe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/940f217cbc3c8a33e5403e7c595495c4884400fe",
"reference": "940f217cbc3c8a33e5403e7c595495c4884400fe",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/event-dispatcher": "~2.1"
},
"suggest": {
"symfony/event-dispatcher": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Console\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com",
"time": "2014-02-11 13:52:09"
},
{
"name": "symfony/finder",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Finder",
"source": {
"type": "git",
"url": "https://github.com/symfony/Finder.git",
"reference": "b6735d1fc16da13c4c7dddfe78366a4a098cf011"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Finder/zipball/b6735d1fc16da13c4c7dddfe78366a4a098cf011",
"reference": "b6735d1fc16da13c4c7dddfe78366a4a098cf011",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Finder\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Finder Component",
"homepage": "http://symfony.com",
"time": "2014-01-07 13:28:54"
},
{
"name": "symfony/process",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Process",
"source": {
"type": "git",
"url": "https://github.com/symfony/Process.git",
"reference": "c175448bac997556f8ab972908a4e14c7291fb03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Process/zipball/c175448bac997556f8ab972908a4e14c7291fb03",
"reference": "c175448bac997556f8ab972908a4e14c7291fb03",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Process\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Process Component",
"homepage": "http://symfony.com",
"time": "2014-02-11 13:52:09"
}
],
"packages-dev": [
{
"name": "phpunit/php-code-coverage",
"version": "1.2.17",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "6ef2bf3a1c47eca07ea95f0d8a902a6340390b34"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6ef2bf3a1c47eca07ea95f0d8a902a6340390b34",
"reference": "6ef2bf3a1c47eca07ea95f0d8a902a6340390b34",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"phpunit/php-file-iterator": ">=1.3.0@stable",
"phpunit/php-text-template": ">=1.2.0@stable",
"phpunit/php-token-stream": ">=1.1.3@stable"
},
"require-dev": {
"phpunit/phpunit": "3.7.*@dev"
},
"suggest": {
"ext-dom": "*",
"ext-xdebug": ">=2.0.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"classmap": [
"PHP/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"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": "2014-03-28 10:53:45"
},
{
"name": "phpunit/php-file-iterator",
"version": "1.3.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
"reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"File/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"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": "2013-10-10 15:34:57"
},
{
"name": "phpunit/php-text-template",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-text-template.git",
"reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
"reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"Text/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Simple template engine.",
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
"keywords": [
"template"
],
"time": "2014-01-30 17:20:04"
},
{
"name": "phpunit/php-timer",
"version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
"reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
"reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"PHP/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"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": "2013-08-02 07:42:54"
},
{
"name": "phpunit/php-token-stream",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32",
"reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
}
},
"autoload": {
"classmap": [
"PHP/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Wrapper around PHP's tokenizer extension.",
"homepage": "https://github.com/sebastianbergmann/php-token-stream/",
"keywords": [
"tokenizer"
],
"time": "2014-03-03 05:10:30"
},
{
"name": "phpunit/phpunit",
"version": "3.7.34",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "248d6ce95e6ca7f0e3135252c0b984bbe1f52f19"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/248d6ce95e6ca7f0e3135252c0b984bbe1f52f19",
"reference": "248d6ce95e6ca7f0e3135252c0b984bbe1f52f19",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-pcre": "*",
"ext-reflection": "*",
"ext-spl": "*",
"php": ">=5.3.3",
"phpunit/php-code-coverage": "~1.2",
"phpunit/php-file-iterator": "~1.3",
"phpunit/php-text-template": "~1.1",
"phpunit/php-timer": "~1.0",
"phpunit/phpunit-mock-objects": "~1.2",
"symfony/yaml": "~2.0"
},
"require-dev": {
"pear-pear.php.net/pear": "1.9.4"
},
"suggest": {
"ext-json": "*",
"ext-simplexml": "*",
"ext-tokenizer": "*",
"phpunit/php-invoker": "~1.1"
},
"bin": [
"composer/bin/phpunit"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.7.x-dev"
}
},
"autoload": {
"classmap": [
"PHPUnit/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
"",
"../../symfony/yaml/"
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "The PHP Unit Testing framework.",
"homepage": "http://www.phpunit.de/",
"keywords": [
"phpunit",
"testing",
"xunit"
],
"time": "2014-03-28 11:04:36"
},
{
"name": "phpunit/phpunit-mock-objects",
"version": "1.2.3",
"source": {
"type": "git",
"url": "git://github.com/sebastianbergmann/phpunit-mock-objects.git",
"reference": "1.2.3"
},
"dist": {
"type": "zip",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects/archive/1.2.3.zip",
"reference": "1.2.3",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"phpunit/php-text-template": ">=1.1.1@stable"
},
"suggest": {
"ext-soap": "*"
},
"type": "library",
"autoload": {
"classmap": [
"PHPUnit/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"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": "2013-01-13 10:24:48"
},
{
"name": "symfony/property-access",
"version": "v2.4.2",
"target-dir": "Symfony/Component/PropertyAccess",
"source": {
"type": "git",
"url": "https://github.com/symfony/PropertyAccess.git",
"reference": "37fe0c2dc494b47db4b0850e9dcba3a27cc45c0c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/PropertyAccess/zipball/37fe0c2dc494b47db4b0850e9dcba3a27cc45c0c",
"reference": "37fe0c2dc494b47db4b0850e9dcba3a27cc45c0c",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\PropertyAccess\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony PropertyAccess Component",
"homepage": "http://symfony.com",
"keywords": [
"access",
"array",
"extraction",
"index",
"injection",
"object",
"property",
"property path",
"reflection"
],
"time": "2014-02-11 15:39:28"
},
{
"name": "symfony/translation",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Translation",
"source": {
"type": "git",
"url": "https://github.com/symfony/Translation.git",
"reference": "b00fd07417e493e08488e87bcebeb9681fc7323b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Translation/zipball/b00fd07417e493e08488e87bcebeb9681fc7323b",
"reference": "b00fd07417e493e08488e87bcebeb9681fc7323b",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/config": "~2.0",
"symfony/yaml": "~2.2"
},
"suggest": {
"symfony/config": "",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Translation\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Translation Component",
"homepage": "http://symfony.com",
"time": "2014-02-03 17:15:33"
},
{
"name": "symfony/validator",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Validator",
"source": {
"type": "git",
"url": "https://github.com/symfony/Validator.git",
"reference": "64d7a54f97a5f53a98864a7461822e341f9416b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Validator/zipball/64d7a54f97a5f53a98864a7461822e341f9416b5",
"reference": "64d7a54f97a5f53a98864a7461822e341f9416b5",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/property-access": "~2.2",
"symfony/translation": "~2.0"
},
"require-dev": {
"doctrine/annotations": "~1.0",
"doctrine/cache": "~1.0",
"symfony/config": "~2.2",
"symfony/http-foundation": "~2.1",
"symfony/intl": "~2.3",
"symfony/yaml": "~2.0"
},
"suggest": {
"doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
"doctrine/cache": "For using the default cached annotation reader",
"symfony/config": "",
"symfony/http-foundation": "",
"symfony/intl": "",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Validator\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Validator Component",
"homepage": "http://symfony.com",
"time": "2014-02-11 13:52:09"
},
{
"name": "symfony/yaml",
"version": "v2.4.2",
"target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
"reference": "bb6ddaf8956139d1b8c360b4b713ed0138e876b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/bb6ddaf8956139d1b8c360b4b713ed0138e876b3",
"reference": "bb6ddaf8956139d1b8c360b4b713ed0138e876b3",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Yaml\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
"time": "2014-01-07 13:28:54"
}
],
"aliases": [
],
"minimum-stability": "stable",
"stability-flags": [
],
"platform": {
"php": ">=5.3.3"
},
"platform-dev": [
]
}

BIN
vendor/cilex/cilex/docs/.static/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

153
vendor/cilex/cilex/docs/Makefile vendored Normal file
View File

@ -0,0 +1,153 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = .build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Cilex.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Cilex.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/Cilex"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Cilex"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

45
vendor/cilex/cilex/docs/conf.py vendored Normal file
View File

@ -0,0 +1,45 @@
import sys, os
templates_path = ['.templates']
source_suffix = '.rst'
master_doc = 'index'
project = u'Cilex'
copyright = u'2013, Mike van Riel'
version = '1.0'
release = '1.0.0-alpha1'
pygments_style = 'sphinx'
html_theme = 'agogo'
html_static_path = ['.static']
htmlhelp_basename = 'Cilexdoc'
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
'papersize': 'a4paper',
'pointsize': '10pt',
}
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'Cilex.tex', u'Cilex Documentation', u'Mike van Riel', 'manual'),
]
latex_logo = '.static/logo.png'
# -- Options for manual page output --------------------------------------------
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'cilex', u'Cilex Documentation', [u'Mike van Riel'], 1)
]
# -- Options for Texinfo output ------------------------------------------------
# (source start file, target name, title, author, dir menu entry, description,
# category)
texinfo_documents = [
('index', 'Cilex', u'Cilex Documentation', u'Mike van Riel', 'Cilex', 'One line description of project.',
'Miscellaneous'),
]

9
vendor/cilex/cilex/docs/index.rst vendored Normal file
View File

@ -0,0 +1,9 @@
Cilex' documentation
====================
Contents:
.. toctree::
:maxdepth: 2
usage

82
vendor/cilex/cilex/docs/usage.rst vendored Normal file
View File

@ -0,0 +1,82 @@
Usage
=====
Installation
------------
The easiest way to get started is to use Composer_ using the following steps:
1. Create a file name ``composer.json`` with the following contents:
.. code-block:: json
{
"require": {
"cilex/cilex": "1.0.*@dev"
}
}
2. Download Composer_ and install the project
.. code-block:: bash
$ curl -s http://getcomposer.org/installer | php
$ php composer.phar install
Upgrading
---------
Cilex can be upgraded using Composer_ by calling the update command:
.. code-block:: bash
$ php composer.phar update
Bootstrap
---------
The simplest example of a Cilex application is by including the autoloader, instantiating the Cilex application class
and calling the ``run`` method. The following example demonstrates this principle:
.. code-block:: php
<?php
// application.php
require_once __DIR__ . '/vendor/autoload.php';
$app = new \Cilex\Application('NameOfMyApplication');
// list of commands
$app->run();
Calling your new application is as simple as the following line:
.. code-block:: bash
$ php application.php
Even without actual commands you are greeted with an informative description what to do next:
.. code-block:: bash
NameOfMyApplication version
Usage:
[options] command [arguments]
Options:
--help -h Display this help message.
--quiet -q Do not output any message.
--verbose -v Increase verbosity of messages.
--version -V Display this application version.
--ansi Force ANSI output.
--no-ansi Disable ANSI output.
--no-interaction -n Do not ask any interactive question.
Available commands:
help Displays help for a command
list Lists commands
.. _Composer: http://getcomposer.org

6
vendor/cilex/cilex/example.php vendored Normal file
View File

@ -0,0 +1,6 @@
<?php
require_once __DIR__ . '/vendor/autoload.php';
$app = new \Cilex\Application('Cilex');
//$app->command(new \Cilex\Command\GreetCommand());
$app->run();

19
vendor/cilex/cilex/phpunit.xml.dist vendored Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="Cilex Test Suite">
<directory>./tests/Cilex/</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@ -0,0 +1,111 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex;
use \Symfony\Component\Console;
use \Cilex\Provider\Console\ConsoleServiceProvider;
/**
* The Cilex framework class.
*
* @author Mike van Riel <mike.vanriel@naenius.com>
*
* @api
*/
class Application extends \Pimple
{
/**
* Version number for Cilex
*/
const VERSION = '1.0.0';
/**
* Registers the autoloader and necessary components.
*
* @param string $name Name for this application.
* @param string|null $version Version number for this application.
*/
public function __construct($name, $version = null, array $values = array())
{
parent::__construct();
$consoleConfig = array('console.name' => $name);
if (null !== $version) {
$consoleConfig['console.version'] = $version;
}
$this->register(new ConsoleServiceProvider(), $consoleConfig);
foreach ($values as $key => $value) {
$this[$key] = $value;
}
}
/**
* Executes this application.
*
* @param bool $interactive runs in an interactive shell if true.
*
* @return void
*/
public function run($interactive = false)
{
$app = $this['console'];
if ($interactive) {
$app = new Console\Shell($app);
}
$app->run();
}
/**
* Adds a command object.
*
* If a command with the same name already exists, it will be overridden.
*
* @param \Cilex\Command\Command $command A Command object
*
* @api
*
* @return void
*/
public function command(Console\Command\Command $command)
{
$this['console']->add($command);
}
/**
* Registers a service provider.
*
* @param \Cilex\ServiceProviderInterface|\Silex\ServiceProviderInterface $provider
* A ServiceProviderInterface instance
* @param mixed[] $values
* An array of values that customizes the provider
*
* @return void
*/
public function register($provider, array $values = array())
{
if ((!$provider instanceof \Cilex\ServiceProviderInterface)
&& (!$provider instanceof \Silex\ServiceProviderInterface)
) {
throw new \InvalidArgumentException(
'Extensions should implement either Cilex or Silex\' ServiceProviderInterface'
);
}
$provider->register($this);
foreach ($values as $key => $value) {
$this[$key] = $value;
}
}
}

View File

@ -0,0 +1,55 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Command;
use \Symfony\Component\Console;
/**
* Base class for Cilex commands.
*
* @author Mike van Riel <mike.vanriel@naenius.com>
*
* @api
*/
abstract class Command extends Console\Command\Command
{
/**
* Returns the application container.
*
* @return \Cilex\Application
*/
public function getContainer()
{
return $this->getApplication()->getContainer();
}
/**
* Returns a service contained in the application container or null if none
* is found with that name.
*
* This is a convenience method used to retrieve an element from the
* Application container without having to assign the results of the
* getContainer() method in every call.
*
* @param string $name Name of the service
*
* @see self::getContainer()
*
* @api
*
* @return \stdClass|null
*/
public function getService($name)
{
return $this->getApplication()->getService($name);
}
}

View File

@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command as BaseCommand;
/**
* Example command for testing purposes.
*/
class DemoInfoCommand extends BaseCommand
{
protected function configure()
{
$this
->setName('demo:info')
->setDescription('Get Application Information');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// This is a contrived example to show accessing services
// from the container without needing the command itself
// to extend from anything but Symfony Console's base Command.
$app = $this->getApplication()->getService('console');
$output->writeln('Name: ' . $app->getName());
$output->writeln('Version: ' . $app->getVersion());
}
}

View File

@ -0,0 +1,47 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Example command for testing purposes.
*/
class GreetCommand extends Command
{
protected function configure()
{
$this
->setName('demo:greet')
->setDescription('Greet someone')
->addArgument('name', InputArgument::OPTIONAL, 'Who do you want to greet?')
->addOption('yell', null, InputOption::VALUE_NONE, 'If set, the task will yell in uppercase letters');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$text = 'Hello';
$name = $input->getArgument('name');
if ($name) {
$text .= ' '.$name;
}
if ($input->getOption('yell')) {
$text = strtoupper($text);
}
$output->writeln($text);
}
}

View File

@ -0,0 +1,184 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Process\Process;
/**
* The Compiler class compiles the Cilex framework.
*
* This is an adapted version of the Silex\Compiler class.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Mike van Riel <mike.vanriel@naenius.com>
*/
class Compiler
{
protected $version;
/**
* Compiles the Cilex source code into one single Phar file.
*
* @param string $pharFile Name of the output Phar file
*/
public function compile($pharFile = 'cilex.phar')
{
if (file_exists($pharFile)) {
unlink($pharFile);
}
$process = new Process('git log --pretty="%h %ci" -n1 HEAD');
if ($process->run() > 0) {
throw new \RuntimeException('The git binary cannot be found.');
}
$this->version = trim($process->getOutput());
$phar = new \Phar($pharFile, 0, 'cilex.phar');
$phar->setSignatureAlgorithm(\Phar::SHA1);
$phar->startBuffering();
$finder = new Finder();
$finder->files()
->ignoreVCS(true)
->name('*.php')
->notName('Compiler.php')
->in(__DIR__.'/..')
->in(__DIR__.'/../../vendor/pimple/pimple/lib')
->in(__DIR__.'/../../vendor/cilex/console-service-provider')
->in(__DIR__.'/../../vendor/symfony/console/Symfony/Component/Console');
foreach ($finder as $file) {
$this->addFile($phar, $file);
}
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../LICENSE'), false);
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/autoload.php'));
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/ClassLoader.php'));
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_real.php'));
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_namespaces.php'));
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_classmap.php'));
// Stubs
$phar->setStub($this->getStub());
$phar->stopBuffering();
// $phar->compressFiles(\Phar::GZ);
unset($phar);
}
protected function addFile(\Phar $phar, \splFileInfo $file, $strip = true)
{
$path = str_replace(dirname(dirname(__DIR__)).DIRECTORY_SEPARATOR, '', $file->getRealPath());
$content = file_get_contents($file);
if ($strip) {
$content = self::stripWhitespace($content);
}
$content = str_replace('@package_version@', $this->version, $content);
$phar->addFromString($path, $content);
}
protected function getStub()
{
return <<<'EOF'
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Phar::mapPhar('cilex.phar');
require_once 'phar://cilex.phar/vendor/autoload.php';
if ('cli' === php_sapi_name() && basename(__FILE__) === basename($_SERVER['argv'][0]) && isset($_SERVER['argv'][1])) {
switch ($_SERVER['argv'][1]) {
case 'update':
$remoteFilename = 'http://cilex.github.com/get/cilex.phar';
$localFilename = __DIR__.'/cilex.phar';
file_put_contents($localFilename, file_get_contents($remoteFilename));
break;
case 'check':
$latest = trim(file_get_contents('http://cilex.github.com/get/version'));
if ($latest != Cilex\Application::VERSION) {
printf("A newer Cilex version is available (%s).\n", $latest);
} else {
print("You are using the latest Cilex version.\n");
}
break;
case 'version':
printf("Cilex version %s\n", Cilex\Application::VERSION);
break;
default:
printf("Unknown command '%s' (available commands: version, check, and update).\n", $_SERVER['argv'][1]);
}
exit(0);
}
__HALT_COMPILER();
EOF;
}
/**
* Removes whitespace from a PHP source string while preserving line numbers.
*
* Based on Kernel::stripComments(), but keeps line numbers intact.
*
* @param string $source A PHP string
*
* @return string The PHP string with the whitespace removed
*/
public static function stripWhitespace($source)
{
if (!function_exists('token_get_all')) {
return $source;
}
$output = '';
foreach (token_get_all($source) as $token) {
if (is_string($token)) {
$output .= $token;
} elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
$output .= str_repeat("\n", substr_count($token[1], "\n"));
} elseif (T_WHITESPACE === $token[0]) {
// reduce wide spaces
$whitespace = preg_replace('{[ \t]+}', ' ', $token[1]);
// normalize newlines to \n
$whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace);
// trim leading spaces
$whitespace = preg_replace('{\n +}', "\n", $whitespace);
$output .= $whitespace;
} else {
$output .= $token[1];
}
}
return $output;
}
}

View File

@ -0,0 +1,68 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Provider;
use Cilex\Application;
use Cilex\ServiceProviderInterface;
use Symfony\Component\Yaml;
class ConfigServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['config'] = $app->share(
function () use ($app) {
if (!file_exists($app['config.path'])) {
throw new \InvalidArgumentException(
$app['config.path'] . ' is not a valid path to the '
.'configuration'
);
}
$fullpath = explode('.', $app['config.path']);
switch (strtolower(end($fullpath))) {
case 'php':
$result = include($app['config.path']);
break;
case 'yml':
$parser = new Yaml\Parser();
$result = new \ArrayObject(
$parser->parse(file_get_contents($app['config.path']))
);
break;
case 'xml':
$result = simplexml_load_file($app['config.path']);
break;
case 'json':
$result = json_decode(file_get_contents($app['config.path']));
if (null == $result) {
throw new \InvalidArgumentException(
'Unable to decode the configuration file: ' . $app['config.path']
);
}
break;
default:
throw new \InvalidArgumentException(
'Unable to load configuration; the provided file extension was not recognized. '
.'Only yml, xml or json allowed'
);
break;
}
return $result;
}
);
}
}

View File

@ -0,0 +1,148 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Provider;
use Cilex\Application;
use Cilex\ServiceProviderInterface;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Configuration;
use Doctrine\Common\EventManager;
/**
* Doctrine DBAL Provider.
*
* This Service Provider is an adaptation of the DoctrineServiceProvider for
* Silex written by Fabien Potencier.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Mike van Riel <mike.vanriel@naenius.com>
*/
class DoctrineServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['db.default_options'] = array(
'driver' => 'pdo_mysql',
'dbname' => null,
'host' => 'localhost',
'user' => 'root',
'password' => null,
);
$app['dbs.options.initializer'] = $app->protect(
function () use ($app) {
static $initialized = false;
if ($initialized) {
return;
}
$initialized = true;
if (!isset($app['dbs.options'])) {
$app['dbs.options'] = array('default' => isset($app['db.options']) ? $app['db.options'] : array());
}
$tmp = $app['dbs.options'];
foreach ($tmp as $name => &$options) {
$options = array_replace($app['db.default_options'], $options);
if (!isset($app['dbs.default'])) {
$app['dbs.default'] = $name;
}
}
$app['dbs.options'] = $tmp;
}
);
$app['dbs'] = $app->share(
function () use ($app) {
$app['dbs.options.initializer']();
$dbs = new \Pimple();
foreach ($app['dbs.options'] as $name => $options) {
if ($app['dbs.default'] === $name) {
// we use shortcuts here in case the default has been overriden
$config = $app['db.config'];
$manager = $app['db.event_manager'];
} else {
$config = $app['dbs.config'][$name];
$manager = $app['dbs.event_manager'][$name];
}
$dbs[$name] = DriverManager::getConnection($options, $config, $manager);
}
return $dbs;
}
);
$app['dbs.config'] = $app->share(
function () use ($app) {
$app['dbs.options.initializer']();
$configs = new \Pimple();
foreach ($app['dbs.options'] as $name => $options) {
$configs[$name] = new Configuration();
}
return $configs;
}
);
$app['dbs.event_manager'] = $app->share(
function () use ($app) {
$app['dbs.options.initializer']();
$managers = new \Pimple();
foreach ($app['dbs.options'] as $name => $options) {
$managers[$name] = new EventManager();
}
return $managers;
}
);
// shortcuts for the "first" DB
$app['db'] = $app->share(
function () use ($app) {
$dbs = $app['dbs'];
return $dbs[$app['dbs.default']];
}
);
$app['db.config'] = $app->share(
function () use ($app) {
$dbs = $app['dbs.config'];
return $dbs[$app['dbs.default']];
}
);
$app['db.event_manager'] = $app->share(
function () use ($app) {
$dbs = $app['dbs.event_manager'];
return $dbs[$app['dbs.default']];
}
);
if (isset($app['db.dbal.class_path'])) {
$app['autoloader']->registerNamespace('Doctrine\\DBAL', $app['db.dbal.class_path']);
}
if (isset($app['db.common.class_path'])) {
$app['autoloader']->registerNamespace('Doctrine\\Common', $app['db.common.class_path']);
}
}
}

View File

@ -0,0 +1,62 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Provider;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Cilex\Application;
use Cilex\ServiceProviderInterface;
/**
* Monolog Provider.
*
* This class is an adaptation of the Silex MonologServiceProvider written by
* Fabien Potencier.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Mike van Riel <mike.vanvriel@naenius.com>
*/
class MonologServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['monolog'] = $app->share(
function () use ($app) {
$log = new Logger(isset($app['monolog.name']) ? $app['monolog.name'] : 'myapp');
$app['monolog.configure']($log);
return $log;
}
);
$app['monolog.configure'] = $app->protect(
function ($log) use ($app) {
$log->pushHandler($app['monolog.handler']);
}
);
$app['monolog.handler'] = function () use ($app) {
return new StreamHandler($app['monolog.logfile'], $app['monolog.level']);
};
if (!isset($app['monolog.level'])) {
$app['monolog.level'] = function () {
return Logger::DEBUG;
};
}
if (isset($app['monolog.class_path'])) {
$app['autoloader']->registerNamespace('Monolog', $app['monolog.class_path']);
}
}
}

View File

@ -0,0 +1,72 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Provider;
use Cilex\Application;
use Cilex\ServiceProviderInterface;
use Symfony\Component\Validator\Validator;
use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
use Symfony\Component\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\DefaultTranslator;
/**
* Symfony Validator component Provider.
*
* This class is an adaptation of the Silex MonologServiceProvider written by
* Fabien Potencier.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Mike van Riel <mike.vanvriel@naenius.com>
*/
class ValidatorServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['validator'] = $app->share(
function () use ($app) {
return new Validator(
$app['validator.mapping.class_metadata_factory'],
$app['validator.validator_factory'],
$app['validator.default_translator']
);
}
);
$app['validator.mapping.class_metadata_factory'] = $app->share(
function () use ($app) {
return new ClassMetadataFactory(new StaticMethodLoader());
}
);
$app['validator.validator_factory'] = $app->share(
function () {
return new ConstraintValidatorFactory();
}
);
$app['validator.default_translator'] = $app->share(
function () {
if (!class_exists('Symfony\\Component\\Validator\\DefaultTranslator')){
return array();
}
return new DefaultTranslator();
}
);
if (isset($app['validator.class_path'])) {
$app['autoloader']->registerNamespace('Symfony\\Component\\Validator', $app['validator.class_path']);
}
}
}

View File

@ -0,0 +1,27 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex;
/**
* Interface that must implement all Cilex service providers.
*
* @author Mike van Riel <mike.vanriel@naenius.com>
*/
interface ServiceProviderInterface
{
/**
* Registers services on the given app.
*
* @param Application $app An Application instance
*/
public function register(Application $app);
}

View File

@ -0,0 +1,99 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Tests;
use \Cilex\Application;
/**
* Mock class used to test the register method.
*/
class ServiceProviderMock implements \Cilex\ServiceProviderInterface
{
/**
* Mock method to satisfy interface
*
* @param \Cilex\Application $app
*
* @return void
*/
function register(\Cilex\Application $app)
{
$app['mock.param'] = false;
$app['mock'] = $this;
}
}
/**
* Application test cases.
*
* @author Mike van Riel <mike.vanriel@naenius.com>
*/
class ApplicationTest extends \PHPUnit_Framework_TestCase
{
const NAME = 'Test';
const VERSION = '1.0.1';
/** @var \Cilex\Application */
protected $fixture = null;
/**
* Sets up the test fixture.
*/
public function setUp()
{
$this->fixture = new Application(self::NAME, self::VERSION);
}
/**
* Tests whether the constructor instantiates the correct dependencies and
* correctly sets the name on the Console's Application.
*/
public function testConstruct()
{
$this->assertInstanceOf(
'\\Symfony\\Component\\Console\\Application',
$this->fixture['console']
);
$this->assertEquals(self::NAME, $this->fixture['console']->getName());
$this->assertEquals(self::VERSION, $this->fixture['console']->getVersion());
}
/**
* Tests the command method to see if the command is properly set and the
* Cilex application is added as container.
*/
public function testCommand()
{
$this->assertFalse($this->fixture['console']->has('demo:greet'));
$this->fixture->command(new \Cilex\Command\GreetCommand());
$this->assertTrue($this->fixture['console']->has('demo:greet'));
$this->assertSame(
$this->fixture,
$this->fixture['console']->get('demo:greet')->getContainer()
);
}
/**
* Tests whether the register method applies the provided parameters to this
* application and correctly registers the ServiceProvider.
*/
public function testRegister()
{
$provider = new ServiceProviderMock();
$this->fixture->register($provider, array('mock.param' => true));
$this->assertTrue($this->fixture['mock.param']);
$this->assertSame($this->fixture['mock'], $provider);
}
}

View File

@ -0,0 +1,61 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Tests\Command;
use \Cilex\Command;
class CommandMock extends Command\Command {}
/**
* Command\Command test cases.
*
* @author Mike van Riel <mike.vanriel@naenius.com>
*/
class CommandTest extends \PHPUnit_Framework_TestCase
{
/** @var \Cilex\Command\Command */
protected $fixture = null;
/**
* Sets up the test fixture.
*/
public function setUp()
{
$this->fixture = new CommandMock('demo:test');
}
/**
* Tests the getContainer method.
*/
public function testContainer()
{
$app = new \Cilex\Application('Test');
$app->command($this->fixture);
$this->assertSame($app, $this->fixture->getContainer());
}
/**
* Tests whether the getService method correctly retrieves an element from
* the container.
*/
public function testGetService()
{
$app = new \Cilex\Application('Test');
$app->command($this->fixture);
$this->assertInstanceOf(
'\Symfony\Component\Console\Application',
$this->fixture->getService('console')
);
}
}

View File

@ -0,0 +1,136 @@
<?php
/**
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Ben Selby <benmatselby@gmail.com>
*/
namespace Cilex\Tests\Provider;
use Cilex\Application;
use Cilex\Provider\ConfigServiceProvider;
/**
* Test file for ConfigServiceProvider
*
* @author Ben Selby <benmatselby@gmail.com>
*/
class ConfigServiceProviderTest extends \PHPUnit_Framework_TestCase
{
/**
* Test that an exception is thrown if the config path is not present
* or valid
*
* @return void
*/
public function testRegisterWillThrowExceptionIfConfigPathIsNotThere()
{
$this->setExpectedException(
'InvalidArgumentException',
__DIR__.'/../../../data/unknownfile is not a valid path to the configuration'
);
$app = new Application('Test');
$app->register(
new ConfigServiceProvider(),
array(
'config.path' => __DIR__.'/../../../data/unknownfile'
)
);
$config = $app['config'];
}
/**
* Test that the config provider can parse a json
* configuration file
*
* @return void
*/
public function testRegisterCanParseAJsonConfigFile()
{
$app = new Application('Test');
$app->register(
new ConfigServiceProvider(),
array(
'config.path' => __DIR__.'/../../../data/config.json'
)
);
$config = $app['config'];
$this->assertEquals($config->key, 'value');
}
public function testCanParseAPhpConfigFile()
{
$app = new Application('Test');
$app->register(
new ConfigServiceProvider(),
array(
'config.path' => __DIR__.'/../../../data/config.php'
)
);
$config = $app['config'];
$this->assertEquals($config['key'], 'value');
}
/**
* Test that the config provider can throw an exception if
* the json configuration file is invalid
*
* @return void
*/
public function testRegisterThrowsExceptionInCaseOfInvalidJsonConfigFile()
{
$configPath = __DIR__.'/../../../data/config-invalid.json';
$this->setExpectedException(
'InvalidArgumentException',
'Unable to decode the configuration file: ' . $configPath
);
$app = new Application('Test');
$app->register(
new ConfigServiceProvider(),
array(
'config.path' => $configPath
)
);
$config = $app['config'];
}
/**
* Test that register will throw an exception if an unknown
* format is passed in
*
* @return void
*/
public function testRegisterThrowsExceptionIfAnUnknownFormatIsPassed()
{
$this->setExpectedException(
'InvalidArgumentException',
'Unable to load configuration; the provided file extension was not recognized. Only yml, xml or json allowed'
);
$app = new Application('Test');
$app->register(
new ConfigServiceProvider(),
array(
'config.path' => __DIR__.'/../../../data/config.unknownfiletype'
)
);
$config = $app['config'];
}
}

View File

@ -0,0 +1,52 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Tests\Provider;
use Cilex\Application;
use Cilex\Provider\ValidatorServiceProvider;
/**
* ValidatorServiceProvider.
*
* Originally provided with the Silex Framework; test has been adapted for Cilex.
*
* @author Javier Lopez <f12loalf@gmail.com>
* @author Mike van Riel <mike.vanriel@naenius.com>
*/
class ValidatorServiceProviderTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
if (!is_dir(__DIR__.'/../../../../vendor/symfony/validator/Symfony/Component/Validator')) {
$this->markTestSkipped('Validator submodule was not installed.');
}
}
public function testRegister()
{
$app = new Application('Test');
$app->register(new ValidatorServiceProvider(), array(
'validator.class_path' => __DIR__.'/../../../../vendor/Symfony/Component/Validator'
));
return $app;
}
/**
* @depends testRegister
*/
public function testValidatorServiceIsAValidator($app)
{
$this->assertInstanceOf('Symfony\Component\Validator\Validator', $app['validator']);
}
}

View File

@ -0,0 +1,4 @@
{
"key": "value"
"missing": "comma"
}

View File

@ -0,0 +1,3 @@
{
"key": "value"
}

View File

@ -0,0 +1,4 @@
<?php
return array(
'key' => 'value'
);

View File

View File

@ -0,0 +1,2 @@
vendor
.idea

View File

@ -0,0 +1,163 @@
Console Service Provider
========================
Provides [Console][symfony/console] as a service to [Pimple][pimple] applications.
Requirements
------------
* PHP 5.3+
* Symfony Console ~2.1
Installation
------------
Through [Composer][composer] as [cilex/console-service-provider][cilex/console-service-provider].
Usage
-----
### Pimple
```php
<?php
use Cilex\Provider\Console\BaseConsoleServiceProvider;
$app = new Pimple;
$app['console.name'] = 'MyApp';
$app['console.version'] = '1.0.5';
$consoleServiceProvider = new BaseConsoleServiceProvider;
$consoleServiceProvider->register($app);
$app['console']->run();
```
### Silex
To use the Console Service Provider in a Silex application register the
Console Service Provider Silex adapter.
```php
<?php
use Cilex\Provider\Console\Adapter\Silex\ConsoleServiceProvider;
use Silex\Application;
$app = new Application;
$app->register(new ConsoleServiceProvider(), array(
'console.name' => 'MyApp',
'console.version' => '1.0.5',
));
$app['console']->run();
```
### Cilex
The Console Service Provider is baked into the Cilex Application itself so
there is no need to register it manually.
```php
<?php
use Cilex\Application;
$app = new Application('MyApp', '1.0.5');
$app->run();
```
Configuration
-------------
### Parameters
* **console.name**:
Name for the console application.
* **console.version**:
Version for the console application.
* **console.class**:
Class for the console application to be created.
### Services
* **console**:
Console Application, instance `Symfony\Component\Console\Application`.
The Console Service Provider Application Class
----------------------------------------------
By default Console Service Provider will instantiate an instance of
`Cilex\Pimple\Provider\Console\Application`.
### Methods
#### getContainer() : \Pimple
Returns the Pimple container.
#### getService($name) : \stdClass|null
Returns a service contained in the application container or null if none
is found with that name. Convenience method to avoid repeated calls to
`getContainer()` or having to assign the container.
Accessing the Container and Services from Commands
--------------------------------------------------
Here are some examples of accessing the Container and Services from a Command:
```php
<?php
use Symfony\Component\Console\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SomeCommand extends Command
{
protected function configure()
{
// configure the command
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// Direct access to the Container.
$container = $this->getApplication()->getContainer();
// Direct access to a service.
$service = $this->getApplication->getService('some.service');
}
}
```
Future
------
In the event that Pimple Service Providers become a reality, `ConsoleServiceProvider`
will implement the appropriate interface. As soon as Cilex and Silex become Pimple
Service Provider aware, their respective adapter classes can be bypassed and the
core `ConsoleServiceProvider` can be used directly.
License
-------
MIT, see LICENSE.
[symfony/console]: http://symfony.com/doc/current/components/console/introduction.html
[pimple]: http://pimple.sensiolabs.org
[composer]: http://getcomposer.org
[cilex/console-service-provider]: https://packagist.org/packages/cilex/console-service-provider

View File

@ -0,0 +1,27 @@
{
"name": "cilex/console-service-provider",
"description": "Console Service Provider",
"keywords": ["pimple", "cilex", "silex", "console", "service-provider"],
"license": "MIT",
"authors": [
{ "name": "Mike van Riel", "email": "mike.vanriel@naenius.com" },
{ "name": "Beau Simensen", "email": "beau@dflydev.com" }
],
"require": {
"php": ">=5.3.3",
"pimple/pimple": "1.*@dev",
"symfony/console": "~2.1"
},
"require-dev": {
"cilex/cilex": "1.*@dev",
"silex/silex": "1.*@dev"
},
"autoload": {
"psr-0": { "Cilex\\Provider\\Console": "src" }
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
}
}

110
vendor/cilex/console-service-provider/composer.lock generated vendored Normal file
View File

@ -0,0 +1,110 @@
{
"hash": "52d1f50b5bb3e0f2626a352a0ed2a947",
"packages": [
{
"name": "pimple/pimple",
"version": "dev-master",
"source": {
"type": "git",
"url": "git://github.com/fabpot/Pimple.git",
"reference": "v1.0.1"
},
"dist": {
"type": "zip",
"url": "https://github.com/fabpot/Pimple/archive/v1.0.1.zip",
"reference": "v1.0.1",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2012-11-11 08:32:34",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"installation-source": "source",
"autoload": {
"psr-0": {
"Pimple": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
"homepage": "http://pimple.sensiolabs.org",
"keywords": [
"dependency injection",
"container"
]
},
{
"name": "symfony/console",
"version": "v2.1.4",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console",
"reference": "v2.1.4"
},
"dist": {
"type": "zip",
"url": "https://github.com/symfony/Console/archive/v2.1.4.zip",
"reference": "v2.1.4",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2012-11-09 08:52:51",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Console": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com"
}
],
"packages-dev": null,
"aliases": [
],
"minimum-stability": "stable",
"stability-flags": {
"pimple/pimple": 20,
"cilex/cilex": 20,
"silex/silex": 20
}
}

View File

@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Provider\Console\Adapter\Silex;
use Cilex\Provider\Console\BaseConsoleServiceProvider;
use Silex\Application;
use Silex\ServiceProviderInterface;
/**
* Silex Console Service Provider adapter
*
* @author Beau Simensen <beau@dflydev.com>
*/
class ConsoleServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}
*/
public function boot(Application $app)
{
}
/**
* {@inheritdoc}
*/
public function register(Application $app)
{
$serviceProvider = new BaseConsoleServiceProvider;
$serviceProvider->register($app);
}
}

View File

@ -0,0 +1,54 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Provider\Console;
/**
* Pimple Console Service Provider
*
* @author Beau Simensen <beau@dflydev.com>
*/
class BaseConsoleServiceProvider
{
/**
* {@inheritdoc}
*/
public function register(\Pimple $container)
{
foreach ($this->getDefaults() as $key => $value) {
if (!isset($container[$key])) {
$container[$key] = $value;
}
}
$container['console'] = $container->share(function() use ($container) {
$class = $container['console.class'];
$instance = new $class(
isset($container['console.name']) ? $container['console.name'] : '',
isset($container['console.version']) ? $container['console.version'] : null
);
if ($instance instanceof ContainerAwareApplication) {
$instance->setContainer($container);
}
return $instance;
});
}
protected function getDefaults()
{
return array(
'console.name' => 'Cilex Application',
'console.class' => 'Cilex\Provider\Console\ContainerAwareApplication',
);
}
}

View File

@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Provider\Console;
use Cilex\Application;
use Cilex\ServiceProviderInterface;
/**
* Cilex Console Service Provider
*
* @author Beau Simensen <beau@dflydev.com>
*/
class ConsoleServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}
*/
public function register(Application $app)
{
$serviceProvider = new BaseConsoleServiceProvider();
$serviceProvider->register($app);
}
}

View File

@ -0,0 +1,77 @@
<?php
/*
* This file is part of the Cilex framework.
*
* (c) Mike van Riel <mike.vanriel@naenius.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cilex\Provider\Console;
use Symfony\Component\Console\Application;
/**
* Cilex Pimple Console Application
*
* @author Beau Simensen <beau@dflydev.com>
*/
class ContainerAwareApplication extends Application
{
/** @var \Pimple */
private $container;
/**
* Constructor
*
* @param string $name The name of the application
* @param string $version The version of the application
*/
public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
{
parent::__construct($name, $version);
}
/**
* Sets a container instance onto this application.
*
* @param \Pimple $container
*
* @return void
*/
public function setContainer(\Pimple $container)
{
$this->container = $container;
}
/**
* Get the Container.
*
* @return \Pimple
*/
public function getContainer()
{
return $this->container;
}
/**
* Returns a service contained in the application container or null if none is found with that name.
*
* This is a convenience method used to retrieve an element from the Application container without having to assign
* the results of the getContainer() method in every call.
*
* @param string $name Name of the service.
*
* @see self::getContainer()
*
* @api
*
* @return mixed|null
*/
public function getService($name)
{
return isset($this->container[$name]) ? $this->container[$name] : null;
}
}

445
vendor/composer/ClassLoader.php vendored Normal file
View File

@ -0,0 +1,445 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
if (isset($this->prefixDirsPsr4[$search])) {
foreach ($this->prefixDirsPsr4[$search] as $dir) {
$length = $this->prefixLengthsPsr4[$first][$search];
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

56
vendor/composer/LICENSE vendored Normal file
View File

@ -0,0 +1,56 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Composer
Upstream-Contact: Jordi Boggiano <j.boggiano@seld.be>
Source: https://github.com/composer/composer
Files: *
Copyright: 2016, Nils Adermann <naderman@naderman.de>
2016, Jordi Boggiano <j.boggiano@seld.be>
License: Expat
Files: src/Composer/Util/TlsHelper.php
Copyright: 2016, Nils Adermann <naderman@naderman.de>
2016, Jordi Boggiano <j.boggiano@seld.be>
2013, Evan Coury <me@evancoury.com>
License: Expat and BSD-2-Clause
License: BSD-2-Clause
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
.
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
.
* 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.
.
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 OWNER 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.
License: Expat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

4788
vendor/composer/autoload_classmap.php vendored Normal file

File diff suppressed because it is too large Load Diff

14
vendor/composer/autoload_files.php vendored Normal file
View File

@ -0,0 +1,14 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'fe1bcd0336136e435eaf197895daf81a' => $vendorDir . '/nikic/php-parser/lib/bootstrap.php',
'742b7e606e92b28dd726e835467f413a' => $vendorDir . '/herrera-io/json/src/lib/json_version.php',
'6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
'f0e9d233388e461ee3c460665eb265f0' => $vendorDir . '/herrera-io/phar-update/src/lib/constants.php',
);

27
vendor/composer/autoload_namespaces.php vendored Normal file
View File

@ -0,0 +1,27 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'phpDocumentor' => array($vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/reflection/src', $vendorDir . '/phpdocumentor/reflection/tests/unit', $vendorDir . '/phpdocumentor/reflection/tests/mocks', $vendorDir . '/phpdocumentor/fileset/src', $vendorDir . '/phpdocumentor/fileset/tests/unit', $vendorDir . '/phpdocumentor/graphviz/src', $vendorDir . '/phpdocumentor/graphviz/tests/unit', $vendorDir . '/phpdocumentor/phpdocumentor/src', $vendorDir . '/phpdocumentor/phpdocumentor/tests/unit'),
'Twig_' => array($vendorDir . '/twig/twig/lib'),
'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src'),
'Pimple' => array($vendorDir . '/pimple/pimple/lib'),
'PhpOption\\' => array($vendorDir . '/phpoption/phpoption/src'),
'PhpCollection' => array($vendorDir . '/phpcollection/phpcollection/src'),
'Parsedown' => array($vendorDir . '/erusev/parsedown'),
'PHPMD\\' => array($vendorDir . '/phpmd/phpmd/src/main/php'),
'Metadata\\' => array($vendorDir . '/jms/metadata/src'),
'KevinGH\\Version' => array($vendorDir . '/kherge/version/src/lib'),
'JMS\\Serializer' => array($vendorDir . '/jms/serializer/src'),
'JMS\\' => array($vendorDir . '/jms/parser-lib/src'),
'Herrera\\Phar\\Update' => array($vendorDir . '/herrera-io/phar-update/src/lib'),
'Herrera\\Json' => array($vendorDir . '/herrera-io/json/src/lib'),
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib'),
'Cilex\\Provider\\Console' => array($vendorDir . '/cilex/console-service-provider/src'),
'Cilex\\Provider' => array($vendorDir . '/phpdocumentor/phpdocumentor/src'),
'Cilex' => array($vendorDir . '/cilex/cilex/src'),
);

44
vendor/composer/autoload_psr4.php vendored Normal file
View File

@ -0,0 +1,44 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Zend\\Stdlib\\' => array($vendorDir . '/zendframework/zend-stdlib/src'),
'Zend\\ServiceManager\\' => array($vendorDir . '/zendframework/zend-servicemanager/src'),
'Zend\\Serializer\\' => array($vendorDir . '/zendframework/zend-serializer/src'),
'Zend\\Json\\' => array($vendorDir . '/zendframework/zend-json/src'),
'Zend\\I18n\\' => array($vendorDir . '/zendframework/zend-i18n/src'),
'Zend\\Hydrator\\' => array($vendorDir . '/zendframework/zend-hydrator/src'),
'Zend\\Filter\\' => array($vendorDir . '/zendframework/zend-filter/src'),
'Zend\\EventManager\\' => array($vendorDir . '/zendframework/zend-eventmanager/src'),
'Zend\\Config\\' => array($vendorDir . '/zendframework/zend-config/src'),
'Zend\\Cache\\' => array($vendorDir . '/zendframework/zend-cache/src'),
'Twig\\' => array($vendorDir . '/twig/twig/src'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
'Symfony\\Component\\Validator\\' => array($vendorDir . '/symfony/validator'),
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
'Symfony\\Component\\Stopwatch\\' => array($vendorDir . '/symfony/stopwatch'),
'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Symfony\\Component\\DependencyInjection\\' => array($vendorDir . '/symfony/dependency-injection'),
'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
'Symfony\\Component\\Config\\' => array($vendorDir . '/symfony/config'),
'Seld\\JsonLint\\' => array($vendorDir . '/seld/jsonlint/src/Seld/JsonLint'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
'PDepend\\' => array($vendorDir . '/pdepend/pdepend/src/main/php/PDepend'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'),
'Interop\\Container\\' => array($vendorDir . '/container-interop/container-interop/src/Interop/Container'),
'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
'Doctrine\\Common\\Annotations\\' => array($vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations'),
'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
'' => array($vendorDir . '/gamegos/php-code-sniffer/src'),
);

70
vendor/composer/autoload_real.php vendored Normal file
View File

@ -0,0 +1,70 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit0e1e438512d55b8565ec2867ac0ed110
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit0e1e438512d55b8565ec2867ac0ed110', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit0e1e438512d55b8565ec2867ac0ed110', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit0e1e438512d55b8565ec2867ac0ed110::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit0e1e438512d55b8565ec2867ac0ed110::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire0e1e438512d55b8565ec2867ac0ed110($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire0e1e438512d55b8565ec2867ac0ed110($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

5125
vendor/composer/autoload_static.php vendored Normal file

File diff suppressed because it is too large Load Diff

4277
vendor/composer/installed.json vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
composer.lock
composer.phar
/vendor/

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 container-interop
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,148 @@
# Container Interoperability
[![Latest Stable Version](https://poser.pugx.org/container-interop/container-interop/v/stable.png)](https://packagist.org/packages/container-interop/container-interop)
[![Total Downloads](https://poser.pugx.org/container-interop/container-interop/downloads.svg)](https://packagist.org/packages/container-interop/container-interop)
## Deprecation warning!
Starting Feb. 13th 2017, container-interop is officially deprecated in favor of [PSR-11](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md).
Container-interop has been the test-bed of PSR-11. From v1.2, container-interop directly extends PSR-11 interfaces.
Therefore, all containers implementing container-interop are now *de-facto* compatible with PSR-11.
- Projects implementing container-interop interfaces are encouraged to directly implement PSR-11 interfaces instead.
- Projects consuming container-interop interfaces are very strongly encouraged to directly type-hint on PSR-11 interfaces, in order to be compatible with PSR-11 containers that are not compatible with container-interop.
Regarding the delegate lookup feature, that is present in container-interop and not in PSR-11, the feature is actually a design pattern. It is therefore not deprecated. Documentation regarding this design pattern will be migrated from this repository into a separate website in the future.
## About
*container-interop* tries to identify and standardize features in *container* objects (service locators,
dependency injection containers, etc.) to achieve interoperability.
Through discussions and trials, we try to create a standard, made of common interfaces but also recommendations.
If PHP projects that provide container implementations begin to adopt these common standards, then PHP
applications and projects that use containers can depend on the common interfaces instead of specific
implementations. This facilitates a high-level of interoperability and flexibility that allows users to consume
*any* container implementation that can be adapted to these interfaces.
The work done in this project is not officially endorsed by the [PHP-FIG](http://www.php-fig.org/), but it is being
worked on by members of PHP-FIG and other good developers. We adhere to the spirit and ideals of PHP-FIG, and hope
this project will pave the way for one or more future PSRs.
## Installation
You can install this package through Composer:
```json
composer require container-interop/container-interop
```
The packages adheres to the [SemVer](http://semver.org/) specification, and there will be full backward compatibility
between minor versions.
## Standards
### Available
- [`ContainerInterface`](src/Interop/Container/ContainerInterface.php).
[Description](docs/ContainerInterface.md) [Meta Document](docs/ContainerInterface-meta.md).
Describes the interface of a container that exposes methods to read its entries.
- [*Delegate lookup feature*](docs/Delegate-lookup.md).
[Meta Document](docs/Delegate-lookup-meta.md).
Describes the ability for a container to delegate the lookup of its dependencies to a third-party container. This
feature lets several containers work together in a single application.
### Proposed
View open [request for comments](https://github.com/container-interop/container-interop/labels/RFC)
## Compatible projects
### Projects implementing `ContainerInterface`
- [Acclimate](https://github.com/jeremeamia/acclimate-container): Adapters for
Aura.Di, Laravel, Nette DI, Pimple, Symfony DI, ZF2 Service manager, ZF2
Dependency injection and any container using `ArrayAccess`
- [Aura.Di](https://github.com/auraphp/Aura.Di)
- [auryn-container-interop](https://github.com/elazar/auryn-container-interop)
- [Burlap](https://github.com/codeeverything/burlap)
- [Chernozem](https://github.com/pyrsmk/Chernozem)
- [Data Manager](https://github.com/chrismichaels84/data-manager)
- [Disco](https://github.com/bitexpert/disco)
- [InDI](https://github.com/idealogica/indi)
- [League/Container](http://container.thephpleague.com/)
- [Mouf](http://mouf-php.com)
- [Njasm Container](https://github.com/njasm/container)
- [PHP-DI](http://php-di.org)
- [Picotainer](https://github.com/thecodingmachine/picotainer)
- [PimpleInterop](https://github.com/moufmouf/pimple-interop)
- [Pimple3-ContainerInterop](https://github.com/Sam-Burns/pimple3-containerinterop) (using Pimple v3)
- [SitePoint Container](https://github.com/sitepoint/Container)
- [Thruster Container](https://github.com/ThrusterIO/container) (PHP7 only)
- [Ultra-Lite Container](https://github.com/ultra-lite/container)
- [Unbox](https://github.com/mindplay-dk/unbox)
- [XStatic](https://github.com/jeremeamia/xstatic)
- [Zend\ServiceManager](https://github.com/zendframework/zend-servicemanager)
- [Zit](https://github.com/inxilpro/Zit)
### Projects implementing the *delegate lookup* feature
- [Aura.Di](https://github.com/auraphp/Aura.Di)
- [Burlap](https://github.com/codeeverything/burlap)
- [Chernozem](https://github.com/pyrsmk/Chernozem)
- [InDI](https://github.com/idealogica/indi)
- [League/Container](http://container.thephpleague.com/)
- [Mouf](http://mouf-php.com)
- [Picotainer](https://github.com/thecodingmachine/picotainer)
- [PHP-DI](http://php-di.org)
- [PimpleInterop](https://github.com/moufmouf/pimple-interop)
- [Ultra-Lite Container](https://github.com/ultra-lite/container)
### Middlewares implementing `ContainerInterface`
- [Alias-Container](https://github.com/thecodingmachine/alias-container): add
aliases support to any container
- [Prefixer-Container](https://github.com/thecodingmachine/prefixer-container):
dynamically prefix identifiers
- [Lazy-Container](https://github.com/snapshotpl/lazy-container): lazy services
### Projects using `ContainerInterface`
The list below contains only a sample of all the projects consuming `ContainerInterface`. For a more complete list have a look [here](http://packanalyst.com/class?q=Interop%5CContainer%5CContainerInterface).
| | Downloads |
| --- | --- |
| [Adroit](https://github.com/bitexpert/adroit) | ![](https://img.shields.io/packagist/dt/bitexpert/adroit.svg) |
| [Behat](https://github.com/Behat/Behat/pull/974) | ![](https://img.shields.io/packagist/dt/behat/behat.svg) |
| [blast-facades](https://github.com/phpthinktank/blast-facades): Minimize complexity and represent dependencies as facades. | ![](https://img.shields.io/packagist/dt/blast/facades.svg) |
| [interop.silex.di](https://github.com/thecodingmachine/interop.silex.di): an extension to [Silex](http://silex.sensiolabs.org/) that adds support for any *container-interop* compatible container | ![](https://img.shields.io/packagist/dt/mouf/interop.silex.di.svg) |
| [mindplay/walkway](https://github.com/mindplay-dk/walkway): a modular request router | ![](https://img.shields.io/packagist/dt/mindplay/walkway.svg) |
| [mindplay/middleman](https://github.com/mindplay-dk/middleman): minimalist PSR-7 middleware dispatcher | ![](https://img.shields.io/packagist/dt/mindplay/middleman.svg) |
| [PHP-DI/Invoker](https://github.com/PHP-DI/Invoker): extensible and configurable invoker/dispatcher | ![](https://img.shields.io/packagist/dt/php-di/invoker.svg) |
| [Prophiler](https://github.com/fabfuel/prophiler) | ![](https://img.shields.io/packagist/dt/fabfuel/prophiler.svg) |
| [Silly](https://github.com/mnapoli/silly): CLI micro-framework | ![](https://img.shields.io/packagist/dt/mnapoli/silly.svg) |
| [Slim v3](https://github.com/slimphp/Slim) | ![](https://img.shields.io/packagist/dt/slim/slim.svg) |
| [Splash](http://mouf-php.com/packages/mouf/mvc.splash-common/version/8.0-dev/README.md) | ![](https://img.shields.io/packagist/dt/mouf/mvc.splash-common.svg) |
| [Woohoo Labs. Harmony](https://github.com/woohoolabs/harmony): a flexible micro-framework | ![](https://img.shields.io/packagist/dt/woohoolabs/harmony.svg) |
| [zend-expressive](https://github.com/zendframework/zend-expressive) | ![](https://img.shields.io/packagist/dt/zendframework/zend-expressive.svg) |
## Workflow
Everyone is welcome to join and contribute.
The general workflow looks like this:
1. Someone opens a discussion (GitHub issue) to suggest an interface
1. Feedback is gathered
1. The interface is added to a development branch
1. We release alpha versions so that the interface can be experimented with
1. Discussions and edits ensue until the interface is deemed stable by a general consensus
1. A new minor version of the package is released
We try to not break BC by creating new interfaces instead of editing existing ones.
While we currently work on interfaces, we are open to anything that might help towards interoperability, may that
be code, best practices, etc.

View File

@ -0,0 +1,15 @@
{
"name": "container-interop/container-interop",
"type": "library",
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
"homepage": "https://github.com/container-interop/container-interop",
"license": "MIT",
"autoload": {
"psr-4": {
"Interop\\Container\\": "src/Interop/Container/"
}
},
"require": {
"psr/container": "^1.0"
}
}

View File

@ -0,0 +1,114 @@
# ContainerInterface Meta Document
## Introduction
This document describes the process and discussions that lead to the `ContainerInterface`.
Its goal is to explain the reasons behind each decision.
## Goal
The goal set by `ContainerInterface` is to standardize how frameworks and libraries make use of a
container to obtain objects and parameters.
By standardizing such a behavior, frameworks and libraries using the `ContainerInterface`
could work with any compatible container.
That would allow end users to choose their own container based on their own preferences.
It is important to distinguish the two usages of a container:
- configuring entries
- fetching entries
Most of the time, those two sides are not used by the same party.
While it is often end users who tend to configure entries, it is generally the framework that fetch
entries to build the application.
This is why this interface focuses only on how entries can be fetched from a container.
## Interface name
The interface name has been thoroughly discussed and was decided by a vote.
The list of options considered with their respective votes are:
- `ContainerInterface`: +8
- `ProviderInterface`: +2
- `LocatorInterface`: 0
- `ReadableContainerInterface`: -5
- `ServiceLocatorInterface`: -6
- `ObjectFactory`: -6
- `ObjectStore`: -8
- `ConsumerInterface`: -9
[Full results of the vote](https://github.com/container-interop/container-interop/wiki/%231-interface-name:-Vote)
The complete discussion can be read in [the issue #1](https://github.com/container-interop/container-interop/issues/1).
## Interface methods
The choice of which methods the interface would contain was made after a statistical analysis of existing containers.
The results of this analysis are available [in this document](https://gist.github.com/mnapoli/6159681).
The summary of the analysis showed that:
- all containers offer a method to get an entry by its id
- a large majority name such method `get()`
- for all containers, the `get()` method has 1 mandatory parameter of type string
- some containers have an optional additional argument for `get()`, but it doesn't have the same purpose between containers
- a large majority of the containers offer a method to test if it can return an entry by its id
- a majority name such method `has()`
- for all containers offering `has()`, the method has exactly 1 parameter of type string
- a large majority of the containers throw an exception rather than returning null when an entry is not found in `get()`
- a large majority of the containers don't implement `ArrayAccess`
The question of whether to include methods to define entries has been discussed in
[issue #1](https://github.com/container-interop/container-interop/issues/1).
It has been judged that such methods do not belong in the interface described here because it is out of its scope
(see the "Goal" section).
As a result, the `ContainerInterface` contains two methods:
- `get()`, returning anything, with one mandatory string parameter. Should throw an exception if the entry is not found.
- `has()`, returning a boolean, with one mandatory string parameter.
### Number of parameters in `get()` method
While `ContainerInterface` only defines one mandatory parameter in `get()`, it is not incompatible with
existing containers that have additional optional parameters. PHP allows an implementation to offer more parameters
as long as they are optional, because the implementation *does* satisfy the interface.
This issue has been discussed in [issue #6](https://github.com/container-interop/container-interop/issues/6).
### Type of the `$id` parameter
The type of the `$id` parameter in `get()` and `has()` has been discussed in
[issue #6](https://github.com/container-interop/container-interop/issues/6).
While `string` is used in all the containers that were analyzed, it was suggested that allowing
anything (such as objects) could allow containers to offer a more advanced query API.
An example given was to use the container as an object builder. The `$id` parameter would then be an
object that would describe how to create an instance.
The conclusion of the discussion was that this was beyond the scope of getting entries from a container without
knowing how the container provided them, and it was more fit for a factory.
## Contributors
Are listed here all people that contributed in the discussions or votes, by alphabetical order:
- [Amy Stephen](https://github.com/AmyStephen)
- [David Négrier](https://github.com/moufmouf)
- [Don Gilbert](https://github.com/dongilbert)
- [Jason Judge](https://github.com/judgej)
- [Jeremy Lindblom](https://github.com/jeremeamia)
- [Marco Pivetta](https://github.com/Ocramius)
- [Matthieu Napoli](https://github.com/mnapoli)
- [Paul M. Jones](https://github.com/pmjones)
- [Stephan Hochdörfer](https://github.com/shochdoerfer)
- [Taylor Otwell](https://github.com/taylorotwell)
## Relevant links
- [`ContainerInterface.php`](https://github.com/container-interop/container-interop/blob/master/src/Interop/Container/ContainerInterface.php)
- [List of all issues](https://github.com/container-interop/container-interop/issues?labels=ContainerInterface&milestone=&page=1&state=closed)
- [Vote for the interface name](https://github.com/container-interop/container-interop/wiki/%231-interface-name:-Vote)

View File

@ -0,0 +1,158 @@
Container interface
===================
This document describes a common interface for dependency injection containers.
The goal set by `ContainerInterface` is to standardize how frameworks and libraries make use of a
container to obtain objects and parameters (called *entries* in the rest of this document).
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
interpreted as described in [RFC 2119][].
The word `implementor` in this document is to be interpreted as someone
implementing the `ContainerInterface` in a dependency injection-related library or framework.
Users of dependency injections containers (DIC) are referred to as `user`.
[RFC 2119]: http://tools.ietf.org/html/rfc2119
1. Specification
-----------------
### 1.1 Basics
- The `Interop\Container\ContainerInterface` exposes two methods : `get` and `has`.
- `get` takes one mandatory parameter: an entry identifier. It MUST be a string.
A call to `get` can return anything (a *mixed* value), or throws an exception if the identifier
is not known to the container. Two successive calls to `get` with the same
identifier SHOULD return the same value. However, depending on the `implementor`
design and/or `user` configuration, different values might be returned, so
`user` SHOULD NOT rely on getting the same value on 2 successive calls.
While `ContainerInterface` only defines one mandatory parameter in `get()`, implementations
MAY accept additional optional parameters.
- `has` takes one unique parameter: an entry identifier. It MUST return `true`
if an entry identifier is known to the container and `false` if it is not.
`has($id)` returning true does not mean that `get($id)` will not throw an exception.
It does however mean that `get($id)` will not throw a `NotFoundException`.
### 1.2 Exceptions
Exceptions directly thrown by the container MUST implement the
[`Interop\Container\Exception\ContainerException`](../src/Interop/Container/Exception/ContainerException.php).
A call to the `get` method with a non-existing id SHOULD throw a
[`Interop\Container\Exception\NotFoundException`](../src/Interop/Container/Exception/NotFoundException.php).
### 1.3 Additional features
This section describes additional features that MAY be added to a container. Containers are not
required to implement these features to respect the ContainerInterface.
#### 1.3.1 Delegate lookup feature
The goal of the *delegate lookup* feature is to allow several containers to share entries.
Containers implementing this feature can perform dependency lookups in other containers.
Containers implementing this feature will offer a greater lever of interoperability
with other containers. Implementation of this feature is therefore RECOMMENDED.
A container implementing this feature:
- MUST implement the `ContainerInterface`
- MUST provide a way to register a delegate container (using a constructor parameter, or a setter,
or any possible way). The delegate container MUST implement the `ContainerInterface`.
When a container is configured to use a delegate container for dependencies:
- Calls to the `get` method should only return an entry if the entry is part of the container.
If the entry is not part of the container, an exception should be thrown
(as requested by the `ContainerInterface`).
- Calls to the `has` method should only return `true` if the entry is part of the container.
If the entry is not part of the container, `false` should be returned.
- If the fetched entry has dependencies, **instead** of performing
the dependency lookup in the container, the lookup is performed on the *delegate container*.
Important! By default, the lookup SHOULD be performed on the delegate container **only**, not on the container itself.
It is however allowed for containers to provide exception cases for special entries, and a way to lookup
into the same container (or another container) instead of the delegate container.
2. Package
----------
The interfaces and classes described as well as relevant exception are provided as part of the
[container-interop/container-interop](https://packagist.org/packages/container-interop/container-interop) package.
3. `Interop\Container\ContainerInterface`
-----------------------------------------
```php
<?php
namespace Interop\Container;
use Interop\Container\Exception\ContainerException;
use Interop\Container\Exception\NotFoundException;
/**
* Describes the interface of a container that exposes methods to read its entries.
*/
interface ContainerInterface
{
/**
* Finds an entry of the container by its identifier and returns it.
*
* @param string $id Identifier of the entry to look for.
*
* @throws NotFoundException No entry was found for this identifier.
* @throws ContainerException Error while retrieving the entry.
*
* @return mixed Entry.
*/
public function get($id);
/**
* Returns true if the container can return an entry for the given identifier.
* Returns false otherwise.
*
* `has($id)` returning true does not mean that `get($id)` will not throw an exception.
* It does however mean that `get($id)` will not throw a `NotFoundException`.
*
* @param string $id Identifier of the entry to look for.
*
* @return boolean
*/
public function has($id);
}
```
4. `Interop\Container\Exception\ContainerException`
---------------------------------------------------
```php
<?php
namespace Interop\Container\Exception;
/**
* Base interface representing a generic exception in a container.
*/
interface ContainerException
{
}
```
5. `Interop\Container\Exception\NotFoundException`
---------------------------------------------------
```php
<?php
namespace Interop\Container\Exception;
/**
* No entry was found in the container.
*/
interface NotFoundException extends ContainerException
{
}
```

View File

@ -0,0 +1,259 @@
Delegate lookup feature Meta Document
=====================================
1. Summary
----------
This document describes the *delegate lookup feature*.
Containers are not required to implement this feature to respect the `ContainerInterface`.
However, containers implementing this feature will offer a greater lever of interoperability
with other containers, allowing multiple containers to share entries in the same application.
Implementation of this feature is therefore recommanded.
2. Why Bother?
--------------
The [`ContainerInterface`](../src/Interop/Container/ContainerInterface.php) ([meta doc](ContainerInterface.md))
standardizes how frameworks and libraries make use of a container to obtain objects and parameters.
By standardizing such a behavior, frameworks and libraries relying on the `ContainerInterface`
could work with any compatible container.
That would allow end users to choose their own container based on their own preferences.
The `ContainerInterface` is also enough if we want to have several containers side-by-side in the same
application. For instance, this is what the [CompositeContainer](https://github.com/jeremeamia/acclimate-container/blob/master/src/CompositeContainer.php)
class of [Acclimate](https://github.com/jeremeamia/acclimate-container) is designed for:
![Side by side containers](images/side_by_side_containers.png)
However, an instance in container 1 cannot reference an instance in container 2.
It would be better if an instance of container 1 could reference an instance in container 2,
and the opposite should be true.
![Interoperating containers](images/interoperating_containers.png)
In the sample above, entry 1 in container 1 is referencing entry 3 in container 2.
3. Scope
--------
### 3.1 Goals
The goal of the *delegate lookup* feature is to allow several containers to share entries.
4. Approaches
-------------
### 4.1 Chosen Approach
Containers implementing this feature can perform dependency lookups in other containers.
A container implementing this feature:
- must implement the `ContainerInterface`
- must provide a way to register a *delegate container* (using a constructor parameter, or a setter, or any
possible way). The *delegate container* must implement the `ContainerInterface`.
When a *delegate container* is configured on a container:
- Calls to the `get` method should only return an entry if the entry is part of the container.
If the entry is not part of the container, an exception should be thrown (as required in the `ContainerInterface`).
- Calls to the `has` method should only return *true* if the entry is part of the container.
If the entry is not part of the container, *false* should be returned.
- Finally, the important part: if the entry we are fetching has dependencies,
**instead** of perfoming the dependency lookup in the container, the lookup is performed on the *delegate container*.
Important! By default, the lookup should be performed on the delegate container **only**, not on the container itself.
It is however allowed for containers to provide exception cases for special entries, and a way to lookup into
the same container (or another container) instead of the delegate container.
### 4.2 Typical usage
The *delegate container* will usually be a composite container. A composite container is a container that
contains several other containers. When performing a lookup on a composite container, the inner containers are
queried until one container returns an entry.
An inner container implementing the *delegate lookup feature* will return entries it contains, but if these
entries have dependencies, the dependencies lookup calls will be performed on the composite container, giving
a chance to all containers to answer.
Interestingly enough, the order in which containers are added in the composite container matters. Indeed,
the first containers to be added in the composite container can "override" the entries of containers with
lower priority.
![Containers priority](images/priority.png)
In the example above, "container 2" contains a controller "myController" and the controller is referencing an
"entityManager" entry. "Container 1" contains also an entry named "entityManager".
Without the *delegate lookup* feature, when requesting the "myController" instance to container 2, it would take
in charge the instanciation of both entries.
However, using the *delegate lookup* feature, here is what happens when we ask the composite container for the
"myController" instance:
- The composite container asks container 1 if if contains the "myController" instance. The answer is no.
- The composite container asks container 2 if if contains the "myController" instance. The answer is yes.
- The composite container performs a `get` call on container 2 for the "myController" instance.
- Container 2 sees that "myController" has a dependency on "entityManager".
- Container 2 delegates the lookup of "entityManager" to the composite container.
- The composite container asks container 1 if if contains the "entityManager" instance. The answer is yes.
- The composite container performs a `get` call on container 1 for the "entityManager" instance.
In the end, we get a controller instanciated by container 2 that references an entityManager instanciated
by container 1.
### 4.3 Alternative: the fallback strategy
The first proposed approach we tried was to perform all the lookups in the "local" container,
and if a lookup fails in the container, to use the delegate container. In this scenario, the
delegate container is used in "fallback" mode.
This strategy has been described in @moufmouf blog post: http://mouf-php.com/container-interop-whats-next (solution 1).
It was also discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-33570697) and
[here](https://github.com/container-interop/container-interop/pull/20#issuecomment-56599631).
Problems with this strategy:
- Heavy problem regarding infinite loops
- Unable to overload a container entry with the delegate container entry
### 4.4 Alternative: force implementing an interface
The first proposed approach was to develop a `ParentAwareContainerInterface` interface.
It was proposed here: https://github.com/container-interop/container-interop/pull/8
The interface would have had the behaviour of the delegate lookup feature but would have forced the addition of
a `setParentContainter` method:
```php
interface ParentAwareContainerInterface extends ReadableContainerInterface {
/**
* Sets the parent container associated to that container. This container will call
* the parent container to fetch dependencies.
*
* @param ContainerInterface $container
*/
public function setParentContainer(ContainerInterface $container);
}
```
The interface idea was first questioned by @Ocramius [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51721777).
@Ocramius expressed the idea that an interface should not contain setters, otherwise, it is forcing implementation
details on the class implementing the interface.
Then @mnapoli made a proposal for a "convention" [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51841079),
this idea was further discussed until all participants in the discussion agreed to remove the interface idea
and replace it with a "standard" feature.
**Pros:**
If we had had an interface, we could have delegated the registration of the delegate/composite container to the
the delegate/composite container itself.
For instance:
```php
$containerA = new ContainerA();
$containerB = new ContainerB();
$compositeContainer = new CompositeContainer([$containerA, $containerB]);
// The call to 'setParentContainer' is delegated to the CompositeContainer
// It is not the responsibility of the user anymore.
class CompositeContainer {
...
public function __construct($containers) {
foreach ($containers as $container) {
if ($container instanceof ParentAwareContainerInterface) {
$container->setParentContainer($this);
}
}
...
}
}
```
**Cons:**
Cons have been extensively discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51721777).
Basically, forcing a setter into an interface is a bad idea. Setters are similar to constructor arguments,
and it's a bad idea to standardize a constructor: how the delegate container is configured into a container is an implementation detail. This outweights the benefits of the interface.
### 4.4 Alternative: no exception case for delegate lookups
Originally, the proposed wording for delegate lookup calls was:
> Important! The lookup MUST be performed on the delegate container **only**, not on the container itself.
This was later replaced by:
> Important! By default, the lookup SHOULD be performed on the delegate container **only**, not on the container itself.
>
> It is however allowed for containers to provide exception cases for special entries, and a way to lookup
> into the same container (or another container) instead of the delegate container.
Exception cases have been allowed to avoid breaking dependencies with some services that must be provided
by the container (on @njasm proposal). This was proposed here: https://github.com/container-interop/container-interop/pull/20#issuecomment-56597235
### 4.5 Alternative: having one of the containers act as the composite container
In real-life scenarios, we usually have a big framework (Symfony 2, Zend Framework 2, etc...) and we want to
add another DI container to this container. Most of the time, the "big" framework will be responsible for
creating the controller's instances, using it's own DI container. Until *container-interop* is fully adopted,
the "big" framework will not be aware of the existence of a composite container that it should use instead
of its own container.
For this real-life use cases, @mnapoli and @moufmouf proposed to extend the "big" framework's DI container
to make it act as a composite container.
This has been discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-40367194)
and [here](http://mouf-php.com/container-interop-whats-next#solution4).
This was implemented in Symfony 2 using:
- [interop.symfony.di](https://github.com/thecodingmachine/interop.symfony.di/tree/v0.1.0)
- [framework interop](https://github.com/mnapoli/framework-interop/)
This was implemented in Silex using:
- [interop.silex.di](https://github.com/thecodingmachine/interop.silex.di)
Having a container act as the composite container is not part of the delegate lookup standard because it is
simply a temporary design pattern used to make existing frameworks that do not support yet ContainerInterop
play nice with other DI containers.
5. Implementations
------------------
The following projects already implement the delegate lookup feature:
- [Mouf](http://mouf-php.com), through the [`setDelegateLookupContainer` method](https://github.com/thecodingmachine/mouf/blob/2.0/src/Mouf/MoufManager.php#L2120)
- [PHP-DI](http://php-di.org/), through the [`$wrapperContainer` parameter of the constructor](https://github.com/mnapoli/PHP-DI/blob/master/src/DI/Container.php#L72)
- [pimple-interop](https://github.com/moufmouf/pimple-interop), through the [`$container` parameter of the constructor](https://github.com/moufmouf/pimple-interop/blob/master/src/Interop/Container/Pimple/PimpleInterop.php#L62)
6. People
---------
Are listed here all people that contributed in the discussions, by alphabetical order:
- [Alexandru Pătrănescu](https://github.com/drealecs)
- [Ben Peachey](https://github.com/potherca)
- [David Négrier](https://github.com/moufmouf)
- [Jeremy Lindblom](https://github.com/jeremeamia)
- [Marco Pivetta](https://github.com/Ocramius)
- [Matthieu Napoli](https://github.com/mnapoli)
- [Nelson J Morais](https://github.com/njasm)
- [Phil Sturgeon](https://github.com/philsturgeon)
- [Stephan Hochdörfer](https://github.com/shochdoerfer)
7. Relevant Links
-----------------
_**Note:** Order descending chronologically._
- [Pull request on the delegate lookup feature](https://github.com/container-interop/container-interop/pull/20)
- [Pull request on the interface idea](https://github.com/container-interop/container-interop/pull/8)
- [Original article exposing the delegate lookup idea along many others](http://mouf-php.com/container-interop-whats-next)

View File

@ -0,0 +1,60 @@
Delegate lookup feature
=======================
This document describes a standard for dependency injection containers.
The goal set by the *delegate lookup* feature is to allow several containers to share entries.
Containers implementing this feature can perform dependency lookups in other containers.
Containers implementing this feature will offer a greater lever of interoperability
with other containers. Implementation of this feature is therefore RECOMMENDED.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
interpreted as described in [RFC 2119][].
The word `implementor` in this document is to be interpreted as someone
implementing the delegate lookup feature in a dependency injection-related library or framework.
Users of dependency injections containers (DIC) are referred to as `user`.
[RFC 2119]: http://tools.ietf.org/html/rfc2119
1. Vocabulary
-------------
In a dependency injection container, the container is used to fetch entries.
Entries can have dependencies on other entries. Usually, these other entries are fetched by the container.
The *delegate lookup* feature is the ability for a container to fetch dependencies in
another container. In the rest of the document, the word "container" will reference the container
implemented by the implementor. The word "delegate container" will reference the container we are
fetching the dependencies from.
2. Specification
----------------
A container implementing the *delegate lookup* feature:
- MUST implement the [`ContainerInterface`](ContainerInterface.md)
- MUST provide a way to register a delegate container (using a constructor parameter, or a setter,
or any possible way). The delegate container MUST implement the [`ContainerInterface`](ContainerInterface.md).
When a container is configured to use a delegate container for dependencies:
- Calls to the `get` method should only return an entry if the entry is part of the container.
If the entry is not part of the container, an exception should be thrown
(as requested by the [`ContainerInterface`](ContainerInterface.md)).
- Calls to the `has` method should only return `true` if the entry is part of the container.
If the entry is not part of the container, `false` should be returned.
- If the fetched entry has dependencies, **instead** of performing
the dependency lookup in the container, the lookup is performed on the *delegate container*.
Important: By default, the dependency lookups SHOULD be performed on the delegate container **only**, not on the container itself.
It is however allowed for containers to provide exception cases for special entries, and a way to lookup
into the same container (or another container) instead of the delegate container.
3. Package / Interface
----------------------
This feature is not tied to any code, interface or package.

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,15 @@
<?php
/**
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace Interop\Container;
use Psr\Container\ContainerInterface as PsrContainerInterface;
/**
* Describes the interface of a container that exposes methods to read its entries.
*/
interface ContainerInterface extends PsrContainerInterface
{
}

View File

@ -0,0 +1,15 @@
<?php
/**
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace Interop\Container\Exception;
use Psr\Container\ContainerExceptionInterface as PsrContainerException;
/**
* Base interface representing a generic exception in a container.
*/
interface ContainerException extends PsrContainerException
{
}

View File

@ -0,0 +1,15 @@
<?php
/**
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace Interop\Container\Exception;
use Psr\Container\NotFoundExceptionInterface as PsrNotFoundException;
/**
* No entry was found in the container.
*/
interface NotFoundException extends ContainerException, PsrNotFoundException
{
}

130
vendor/doctrine/annotations/CHANGELOG.md vendored Normal file
View File

@ -0,0 +1,130 @@
## Changelog
### 1.5.0
This release increments the minimum supported PHP version to 7.1.0.
Also, HHVM official support has been dropped.
Some noticeable performance improvements to annotation autoloading
have been applied, making failed annotation autoloading less heavy
on the filesystem access.
- [133: Add @throws annotation in AnnotationReader#__construct()](https://github.com/doctrine/annotations/issues/133) thanks to @SenseException
- [134: Require PHP 7.1, drop HHVM support](https://github.com/doctrine/annotations/issues/134) thanks to @lcobucci
- [135: Prevent the same loader from being registered twice](https://github.com/doctrine/annotations/issues/135) thanks to @jrjohnson
- [137: #135 optimise multiple class load attempts in AnnotationRegistry](https://github.com/doctrine/annotations/issues/137) thanks to @Ocramius
### 1.4.0
This release fix an issue were some annotations could be not loaded if the namespace in the use statement started with a backslash.
It also update the tests and drop the support for php 5.X
- [115: Missing annotations with the latest composer version](https://github.com/doctrine/annotations/issues/115) thanks to @pascalporedda
- [120: Missing annotations with the latest composer version](https://github.com/doctrine/annotations/pull/120) thanks to @gnat42
- [121: Adding a more detailed explanation of the test](https://github.com/doctrine/annotations/pull/121) thanks to @mikeSimonson
- [101: Test annotation parameters containing space](https://github.com/doctrine/annotations/pull/101) thanks to @mikeSimonson
- [111: Cleanup: move to correct phpunit assertions](https://github.com/doctrine/annotations/pull/111) thanks to @Ocramius
- [112: Removes support for PHP 5.x](https://github.com/doctrine/annotations/pull/112) thanks to @railto
- [113: bumped phpunit version to 5.7](https://github.com/doctrine/annotations/pull/113) thanks to @gabbydgab
- [114: Enhancement: Use SVG Travis build badge](https://github.com/doctrine/annotations/pull/114) thanks to @localheinz
- [118: Integrating PHPStan](https://github.com/doctrine/annotations/pull/118) thanks to @ondrejmirtes
### 1.3.1 - 2016-12-30
This release fixes an issue with ignored annotations that were already
autoloaded, causing the `SimpleAnnotationReader` to pick them up
anyway. [#110](https://github.com/doctrine/annotations/pull/110)
Additionally, an issue was fixed in the `CachedReader`, which was
not correctly checking the freshness of cached annotations when
traits were defined on a class. [#105](https://github.com/doctrine/annotations/pull/105)
Total issues resolved: **2**
- [105: Return single max timestamp](https://github.com/doctrine/annotations/pull/105)
- [110: setIgnoreNotImportedAnnotations(true) didn&rsquo;t work for existing classes](https://github.com/doctrine/annotations/pull/110)
### 1.3.0
This release introduces a PHP version bump. `doctrine/annotations` now requires PHP
5.6 or later to be installed.
A series of additional improvements have been introduced:
* support for PHP 7 "grouped use statements"
* support for ignoring entire namespace names
via `Doctrine\Common\Annotations\AnnotationReader::addGlobalIgnoredNamespace()` and
`Doctrine\Common\Annotations\DocParser::setIgnoredAnnotationNamespaces()`. This will
allow you to ignore annotations from namespaces that you cannot autoload
* testing all parent classes and interfaces when checking if the annotation cache
in the `CachedReader` is fresh
* simplifying the cache keys used by the `CachedReader`: keys are no longer artificially
namespaced, since `Doctrine\Common\Cache` already supports that
* corrected parsing of multibyte strings when `mbstring.func_overload` is enabled
* corrected parsing of annotations when `"\t"` is put before the first annotation
in a docblock
* allow skipping non-imported annotations when a custom `DocParser` is passed to
the `AnnotationReader` constructor
Total issues resolved: **15**
- [45: DocParser can now ignore whole namespaces](https://github.com/doctrine/annotations/pull/45)
- [57: Switch to the docker-based infrastructure on Travis](https://github.com/doctrine/annotations/pull/57)
- [59: opcache.load&#95;comments has been removed from PHP 7](https://github.com/doctrine/annotations/pull/59)
- [62: &#91;CachedReader&#92; Test traits and parent class to see if cache is fresh](https://github.com/doctrine/annotations/pull/62)
- [65: Remove cache salt making key unnecessarily long](https://github.com/doctrine/annotations/pull/65)
- [66: Fix of incorrect parsing multibyte strings](https://github.com/doctrine/annotations/pull/66)
- [68: Annotations that are indented by tab are not processed.](https://github.com/doctrine/annotations/issues/68)
- [69: Support for Group Use Statements](https://github.com/doctrine/annotations/pull/69)
- [70: Allow tab character before first annotation in DocBlock](https://github.com/doctrine/annotations/pull/70)
- [74: Ignore not registered annotations fix](https://github.com/doctrine/annotations/pull/74)
- [92: Added tests for AnnotationRegistry class.](https://github.com/doctrine/annotations/pull/92)
- [96: Fix/#62 check trait and parent class ttl in annotations](https://github.com/doctrine/annotations/pull/96)
- [97: Feature - #45 - allow ignoring entire namespaces](https://github.com/doctrine/annotations/pull/97)
- [98: Enhancement/#65 remove cache salt from cached reader](https://github.com/doctrine/annotations/pull/98)
- [99: Fix - #70 - allow tab character before first annotation in docblock](https://github.com/doctrine/annotations/pull/99)
### 1.2.4
Total issues resolved: **1**
- [51: FileCacheReader::saveCacheFile::unlink fix](https://github.com/doctrine/annotations/pull/51)
### 1.2.3
Total issues resolved: [**2**](https://github.com/doctrine/annotations/milestones/v1.2.3)
- [49: #46 - applying correct `chmod()` to generated cache file](https://github.com/doctrine/annotations/pull/49)
- [50: Hotfix: match escaped quotes (revert #44)](https://github.com/doctrine/annotations/pull/50)
### 1.2.2
Total issues resolved: **4**
- [43: Exclude files from distribution with .gitattributes](https://github.com/doctrine/annotations/pull/43)
- [44: Update DocLexer.php](https://github.com/doctrine/annotations/pull/44)
- [46: A plain &quot;file&#95;put&#95;contents&quot; can cause havoc](https://github.com/doctrine/annotations/pull/46)
- [48: Deprecating the `FileCacheReader` in 1.2.2: will be removed in 2.0.0](https://github.com/doctrine/annotations/pull/48)
### 1.2.1
Total issues resolved: **4**
- [38: fixes doctrine/common#326](https://github.com/doctrine/annotations/pull/38)
- [39: Remove superfluous NS](https://github.com/doctrine/annotations/pull/39)
- [41: Warn if load_comments is not enabled.](https://github.com/doctrine/annotations/pull/41)
- [42: Clean up unused uses](https://github.com/doctrine/annotations/pull/42)
### 1.2.0
* HHVM support
* Allowing dangling comma in annotations
* Excluded annotations are no longer autoloaded
* Importing namespaces also in traits
* Added support for `::class` 5.5-style constant, works also in 5.3 and 5.4
### 1.1.0
* Add Exception when ZendOptimizer+ or Opcache is configured to drop comments

19
vendor/doctrine/annotations/LICENSE vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2006-2013 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

17
vendor/doctrine/annotations/README.md vendored Normal file
View File

@ -0,0 +1,17 @@
# Doctrine Annotations
[![Build Status](https://travis-ci.org/doctrine/annotations.svg?branch=master)](https://travis-ci.org/doctrine/annotations)
[![Dependency Status](https://www.versioneye.com/package/php--doctrine--annotations/badge.png)](https://www.versioneye.com/package/php--doctrine--annotations)
[![Reference Status](https://www.versioneye.com/php/doctrine:annotations/reference_badge.svg)](https://www.versioneye.com/php/doctrine:annotations/references)
[![Total Downloads](https://poser.pugx.org/doctrine/annotations/downloads.png)](https://packagist.org/packages/doctrine/annotations)
[![Latest Stable Version](https://poser.pugx.org/doctrine/annotations/v/stable.png)](https://packagist.org/packages/doctrine/annotations)
Docblock Annotations Parser library (extracted from [Doctrine Common](https://github.com/doctrine/common)).
## Documentation
See the [doctrine-project website](http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/annotations.html).
## Changelog
See [CHANGELOG.md](CHANGELOG.md).

View File

@ -0,0 +1,34 @@
{
"name": "doctrine/annotations",
"type": "library",
"description": "Docblock Annotations Parser",
"keywords": ["annotations", "docblock", "parser"],
"homepage": "http://www.doctrine-project.org",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
],
"require": {
"php": "^7.1",
"doctrine/lexer": "1.*"
},
"require-dev": {
"doctrine/cache": "1.*",
"phpunit/phpunit": "^6.4"
},
"autoload": {
"psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" }
},
"autoload-dev": {
"psr-4": { "Doctrine\\Tests\\Common\\Annotations\\": "tests/Doctrine/Tests/Common/Annotations" }
},
"extra": {
"branch-alias": {
"dev-master": "1.6.x-dev"
}
}
}

View File

@ -0,0 +1,79 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
/**
* Annotations class.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class Annotation
{
/**
* Value property. Common among all derived classes.
*
* @var string
*/
public $value;
/**
* Constructor.
*
* @param array $data Key-value for properties to be defined in this class.
*/
public final function __construct(array $data)
{
foreach ($data as $key => $value) {
$this->$key = $value;
}
}
/**
* Error handler for unknown property accessor in Annotation class.
*
* @param string $name Unknown property name.
*
* @throws \BadMethodCallException
*/
public function __get($name)
{
throw new \BadMethodCallException(
sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
);
}
/**
* Error handler for unknown property mutator in Annotation class.
*
* @param string $name Unknown property name.
* @param mixed $value Property value.
*
* @throws \BadMethodCallException
*/
public function __set($name, $value)
{
throw new \BadMethodCallException(
sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
);
}
}

View File

@ -0,0 +1,47 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser
* to check the attribute type during the parsing process.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*
* @Annotation
*/
final class Attribute
{
/**
* @var string
*/
public $name;
/**
* @var string
*/
public $type;
/**
* @var boolean
*/
public $required = false;
}

View File

@ -0,0 +1,37 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser
* to check the types of all declared attributes during the parsing process.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*
* @Annotation
*/
final class Attributes
{
/**
* @var array<Doctrine\Common\Annotations\Annotation\Attribute>
*/
public $value;
}

View File

@ -0,0 +1,84 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser
* to check the available values during the parsing process.
*
* @since 2.4
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*
* @Annotation
* @Attributes({
* @Attribute("value", required = true, type = "array"),
* @Attribute("literal", required = false, type = "array")
* })
*/
final class Enum
{
/**
* @var array
*/
public $value;
/**
* Literal target declaration.
*
* @var array
*/
public $literal;
/**
* Annotation constructor.
*
* @param array $values
*
* @throws \InvalidArgumentException
*/
public function __construct(array $values)
{
if ( ! isset($values['literal'])) {
$values['literal'] = array();
}
foreach ($values['value'] as $var) {
if( ! is_scalar($var)) {
throw new \InvalidArgumentException(sprintf(
'@Enum supports only scalar values "%s" given.',
is_object($var) ? get_class($var) : gettype($var)
));
}
}
foreach ($values['literal'] as $key => $var) {
if( ! in_array($key, $values['value'])) {
throw new \InvalidArgumentException(sprintf(
'Undefined enumerator value "%s" for literal "%s".',
$key , $var
));
}
}
$this->value = $values['value'];
$this->literal = $values['literal'];
}
}

View File

@ -0,0 +1,54 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser to ignore specific
* annotations during the parsing process.
*
* @Annotation
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
final class IgnoreAnnotation
{
/**
* @var array
*/
public $names;
/**
* Constructor.
*
* @param array $values
*
* @throws \RuntimeException
*/
public function __construct(array $values)
{
if (is_string($values['value'])) {
$values['value'] = array($values['value']);
}
if (!is_array($values['value'])) {
throw new \RuntimeException(sprintf('@IgnoreAnnotation expects either a string name, or an array of strings, but got %s.', json_encode($values['value'])));
}
$this->names = $values['value'];
}
}

View File

@ -0,0 +1,33 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser
* to check if that attribute is required during the parsing process.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*
* @Annotation
*/
final class Required
{
}

View File

@ -0,0 +1,107 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser
* to check the annotation target during the parsing process.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*
* @Annotation
*/
final class Target
{
const TARGET_CLASS = 1;
const TARGET_METHOD = 2;
const TARGET_PROPERTY = 4;
const TARGET_ANNOTATION = 8;
const TARGET_ALL = 15;
/**
* @var array
*/
private static $map = array(
'ALL' => self::TARGET_ALL,
'CLASS' => self::TARGET_CLASS,
'METHOD' => self::TARGET_METHOD,
'PROPERTY' => self::TARGET_PROPERTY,
'ANNOTATION' => self::TARGET_ANNOTATION,
);
/**
* @var array
*/
public $value;
/**
* Targets as bitmask.
*
* @var integer
*/
public $targets;
/**
* Literal target declaration.
*
* @var integer
*/
public $literal;
/**
* Annotation constructor.
*
* @param array $values
*
* @throws \InvalidArgumentException
*/
public function __construct(array $values)
{
if (!isset($values['value'])){
$values['value'] = null;
}
if (is_string($values['value'])){
$values['value'] = array($values['value']);
}
if (!is_array($values['value'])){
throw new \InvalidArgumentException(
sprintf('@Target expects either a string value, or an array of strings, "%s" given.',
is_object($values['value']) ? get_class($values['value']) : gettype($values['value'])
)
);
}
$bitmask = 0;
foreach ($values['value'] as $literal) {
if(!isset(self::$map[$literal])){
throw new \InvalidArgumentException(
sprintf('Invalid Target "%s". Available targets: [%s]',
$literal, implode(', ', array_keys(self::$map)))
);
}
$bitmask |= self::$map[$literal];
}
$this->targets = $bitmask;
$this->value = $values['value'];
$this->literal = implode(', ', $this->value);
}
}

View File

@ -0,0 +1,197 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
/**
* Description of AnnotationException
*
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class AnnotationException extends \Exception
{
/**
* Creates a new AnnotationException describing a Syntax error.
*
* @param string $message Exception message
*
* @return AnnotationException
*/
public static function syntaxError($message)
{
return new self('[Syntax Error] ' . $message);
}
/**
* Creates a new AnnotationException describing a Semantical error.
*
* @param string $message Exception message
*
* @return AnnotationException
*/
public static function semanticalError($message)
{
return new self('[Semantical Error] ' . $message);
}
/**
* Creates a new AnnotationException describing an error which occurred during
* the creation of the annotation.
*
* @since 2.2
*
* @param string $message
*
* @return AnnotationException
*/
public static function creationError($message)
{
return new self('[Creation Error] ' . $message);
}
/**
* Creates a new AnnotationException describing a type error.
*
* @since 1.1
*
* @param string $message
*
* @return AnnotationException
*/
public static function typeError($message)
{
return new self('[Type Error] ' . $message);
}
/**
* Creates a new AnnotationException describing a constant semantical error.
*
* @since 2.3
*
* @param string $identifier
* @param string $context
*
* @return AnnotationException
*/
public static function semanticalErrorConstants($identifier, $context = null)
{
return self::semanticalError(sprintf(
"Couldn't find constant %s%s.",
$identifier,
$context ? ', ' . $context : ''
));
}
/**
* Creates a new AnnotationException describing an type error of an attribute.
*
* @since 2.2
*
* @param string $attributeName
* @param string $annotationName
* @param string $context
* @param string $expected
* @param mixed $actual
*
* @return AnnotationException
*/
public static function attributeTypeError($attributeName, $annotationName, $context, $expected, $actual)
{
return self::typeError(sprintf(
'Attribute "%s" of @%s declared on %s expects %s, but got %s.',
$attributeName,
$annotationName,
$context,
$expected,
is_object($actual) ? 'an instance of ' . get_class($actual) : gettype($actual)
));
}
/**
* Creates a new AnnotationException describing an required error of an attribute.
*
* @since 2.2
*
* @param string $attributeName
* @param string $annotationName
* @param string $context
* @param string $expected
*
* @return AnnotationException
*/
public static function requiredError($attributeName, $annotationName, $context, $expected)
{
return self::typeError(sprintf(
'Attribute "%s" of @%s declared on %s expects %s. This value should not be null.',
$attributeName,
$annotationName,
$context,
$expected
));
}
/**
* Creates a new AnnotationException describing a invalid enummerator.
*
* @since 2.4
*
* @param string $attributeName
* @param string $annotationName
* @param string $context
* @param array $available
* @param mixed $given
*
* @return AnnotationException
*/
public static function enumeratorError($attributeName, $annotationName, $context, $available, $given)
{
return new self(sprintf(
'[Enum Error] Attribute "%s" of @%s declared on %s accept only [%s], but got %s.',
$attributeName,
$annotationName,
$context,
implode(', ', $available),
is_object($given) ? get_class($given) : $given
));
}
/**
* @return AnnotationException
*/
public static function optimizerPlusSaveComments()
{
return new self(
"You have to enable opcache.save_comments=1 or zend_optimizerplus.save_comments=1."
);
}
/**
* @return AnnotationException
*/
public static function optimizerPlusLoadComments()
{
return new self(
"You have to enable opcache.load_comments=1 or zend_optimizerplus.load_comments=1."
);
}
}

View File

@ -0,0 +1,425 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation;
use Doctrine\Common\Annotations\Annotation\Target;
use ReflectionClass;
use ReflectionMethod;
use ReflectionProperty;
/**
* A reader for docblock annotations.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class AnnotationReader implements Reader
{
/**
* Global map for imports.
*
* @var array
*/
private static $globalImports = array(
'ignoreannotation' => 'Doctrine\Common\Annotations\Annotation\IgnoreAnnotation',
);
/**
* A list with annotations that are not causing exceptions when not resolved to an annotation class.
*
* The names are case sensitive.
*
* @var array
*/
private static $globalIgnoredNames = array(
// Annotation tags
'Annotation' => true, 'Attribute' => true, 'Attributes' => true,
/* Can we enable this? 'Enum' => true, */
'Required' => true,
'Target' => true,
// Widely used tags (but not existent in phpdoc)
'fix' => true , 'fixme' => true,
'override' => true,
// PHPDocumentor 1 tags
'abstract'=> true, 'access'=> true,
'code' => true,
'deprec'=> true,
'endcode' => true, 'exception'=> true,
'final'=> true,
'ingroup' => true, 'inheritdoc'=> true, 'inheritDoc'=> true,
'magic' => true,
'name'=> true,
'toc' => true, 'tutorial'=> true,
'private' => true,
'static'=> true, 'staticvar'=> true, 'staticVar'=> true,
'throw' => true,
// PHPDocumentor 2 tags.
'api' => true, 'author'=> true,
'category'=> true, 'copyright'=> true,
'deprecated'=> true,
'example'=> true,
'filesource'=> true,
'global'=> true,
'ignore'=> true, /* Can we enable this? 'index' => true, */ 'internal'=> true,
'license'=> true, 'link'=> true,
'method' => true,
'package'=> true, 'param'=> true, 'property' => true, 'property-read' => true, 'property-write' => true,
'return'=> true,
'see'=> true, 'since'=> true, 'source' => true, 'subpackage'=> true,
'throws'=> true, 'todo'=> true, 'TODO'=> true,
'usedby'=> true, 'uses' => true,
'var'=> true, 'version'=> true,
// PHPUnit tags
'codeCoverageIgnore' => true, 'codeCoverageIgnoreStart' => true, 'codeCoverageIgnoreEnd' => true,
// PHPCheckStyle
'SuppressWarnings' => true,
// PHPStorm
'noinspection' => true,
// PEAR
'package_version' => true,
// PlantUML
'startuml' => true, 'enduml' => true,
// Symfony 3.3 Cache Adapter
'experimental' => true
);
/**
* A list with annotations that are not causing exceptions when not resolved to an annotation class.
*
* The names are case sensitive.
*
* @var array
*/
private static $globalIgnoredNamespaces = array();
/**
* Add a new annotation to the globally ignored annotation names with regard to exception handling.
*
* @param string $name
*/
static public function addGlobalIgnoredName($name)
{
self::$globalIgnoredNames[$name] = true;
}
/**
* Add a new annotation to the globally ignored annotation namespaces with regard to exception handling.
*
* @param string $namespace
*/
static public function addGlobalIgnoredNamespace($namespace)
{
self::$globalIgnoredNamespaces[$namespace] = true;
}
/**
* Annotations parser.
*
* @var \Doctrine\Common\Annotations\DocParser
*/
private $parser;
/**
* Annotations parser used to collect parsing metadata.
*
* @var \Doctrine\Common\Annotations\DocParser
*/
private $preParser;
/**
* PHP parser used to collect imports.
*
* @var \Doctrine\Common\Annotations\PhpParser
*/
private $phpParser;
/**
* In-memory cache mechanism to store imported annotations per class.
*
* @var array
*/
private $imports = array();
/**
* In-memory cache mechanism to store ignored annotations per class.
*
* @var array
*/
private $ignoredAnnotationNames = array();
/**
* Constructor.
*
* Initializes a new AnnotationReader.
*
* @param DocParser $parser
*
* @throws AnnotationException
*/
public function __construct(DocParser $parser = null)
{
if (extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.save_comments') === "0" || ini_get('opcache.save_comments') === "0")) {
throw AnnotationException::optimizerPlusSaveComments();
}
if (extension_loaded('Zend OPcache') && ini_get('opcache.save_comments') == 0) {
throw AnnotationException::optimizerPlusSaveComments();
}
if (PHP_VERSION_ID < 70000) {
if (extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.load_comments') === "0" || ini_get('opcache.load_comments') === "0")) {
throw AnnotationException::optimizerPlusLoadComments();
}
if (extension_loaded('Zend OPcache') && ini_get('opcache.load_comments') == 0) {
throw AnnotationException::optimizerPlusLoadComments();
}
}
AnnotationRegistry::registerFile(__DIR__ . '/Annotation/IgnoreAnnotation.php');
$this->parser = $parser ?: new DocParser();
$this->preParser = new DocParser;
$this->preParser->setImports(self::$globalImports);
$this->preParser->setIgnoreNotImportedAnnotations(true);
$this->phpParser = new PhpParser;
}
/**
* {@inheritDoc}
*/
public function getClassAnnotations(ReflectionClass $class)
{
$this->parser->setTarget(Target::TARGET_CLASS);
$this->parser->setImports($this->getClassImports($class));
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
$this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces);
return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName());
}
/**
* {@inheritDoc}
*/
public function getClassAnnotation(ReflectionClass $class, $annotationName)
{
$annotations = $this->getClassAnnotations($class);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public function getPropertyAnnotations(ReflectionProperty $property)
{
$class = $property->getDeclaringClass();
$context = 'property ' . $class->getName() . "::\$" . $property->getName();
$this->parser->setTarget(Target::TARGET_PROPERTY);
$this->parser->setImports($this->getPropertyImports($property));
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
$this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces);
return $this->parser->parse($property->getDocComment(), $context);
}
/**
* {@inheritDoc}
*/
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
{
$annotations = $this->getPropertyAnnotations($property);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public function getMethodAnnotations(ReflectionMethod $method)
{
$class = $method->getDeclaringClass();
$context = 'method ' . $class->getName() . '::' . $method->getName() . '()';
$this->parser->setTarget(Target::TARGET_METHOD);
$this->parser->setImports($this->getMethodImports($method));
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
$this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces);
return $this->parser->parse($method->getDocComment(), $context);
}
/**
* {@inheritDoc}
*/
public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
{
$annotations = $this->getMethodAnnotations($method);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* Returns the ignored annotations for the given class.
*
* @param \ReflectionClass $class
*
* @return array
*/
private function getIgnoredAnnotationNames(ReflectionClass $class)
{
$name = $class->getName();
if (isset($this->ignoredAnnotationNames[$name])) {
return $this->ignoredAnnotationNames[$name];
}
$this->collectParsingMetadata($class);
return $this->ignoredAnnotationNames[$name];
}
/**
* Retrieves imports.
*
* @param \ReflectionClass $class
*
* @return array
*/
private function getClassImports(ReflectionClass $class)
{
$name = $class->getName();
if (isset($this->imports[$name])) {
return $this->imports[$name];
}
$this->collectParsingMetadata($class);
return $this->imports[$name];
}
/**
* Retrieves imports for methods.
*
* @param \ReflectionMethod $method
*
* @return array
*/
private function getMethodImports(ReflectionMethod $method)
{
$class = $method->getDeclaringClass();
$classImports = $this->getClassImports($class);
if (!method_exists($class, 'getTraits')) {
return $classImports;
}
$traitImports = array();
foreach ($class->getTraits() as $trait) {
if ($trait->hasMethod($method->getName())
&& $trait->getFileName() === $method->getFileName()
) {
$traitImports = array_merge($traitImports, $this->phpParser->parseClass($trait));
}
}
return array_merge($classImports, $traitImports);
}
/**
* Retrieves imports for properties.
*
* @param \ReflectionProperty $property
*
* @return array
*/
private function getPropertyImports(ReflectionProperty $property)
{
$class = $property->getDeclaringClass();
$classImports = $this->getClassImports($class);
if (!method_exists($class, 'getTraits')) {
return $classImports;
}
$traitImports = array();
foreach ($class->getTraits() as $trait) {
if ($trait->hasProperty($property->getName())) {
$traitImports = array_merge($traitImports, $this->phpParser->parseClass($trait));
}
}
return array_merge($classImports, $traitImports);
}
/**
* Collects parsing metadata for a given class.
*
* @param \ReflectionClass $class
*/
private function collectParsingMetadata(ReflectionClass $class)
{
$ignoredAnnotationNames = self::$globalIgnoredNames;
$annotations = $this->preParser->parse($class->getDocComment(), 'class ' . $class->name);
foreach ($annotations as $annotation) {
if ($annotation instanceof IgnoreAnnotation) {
foreach ($annotation->names AS $annot) {
$ignoredAnnotationNames[$annot] = true;
}
}
}
$name = $class->getName();
$this->imports[$name] = array_merge(
self::$globalImports,
$this->phpParser->parseClass($class),
array('__NAMESPACE__' => $class->getNamespaceName())
);
$this->ignoredAnnotationNames[$name] = $ignoredAnnotationNames;
}
}

View File

@ -0,0 +1,174 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
final class AnnotationRegistry
{
/**
* A map of namespaces to use for autoloading purposes based on a PSR-0 convention.
*
* Contains the namespace as key and an array of directories as value. If the value is NULL
* the include path is used for checking for the corresponding file.
*
* This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own.
*
* @var string[][]|string[]|null[]
*/
static private $autoloadNamespaces = [];
/**
* A map of autoloader callables.
*
* @var callable[]
*/
static private $loaders = [];
/**
* An array of classes which cannot be found
*
* @var null[] indexed by class name
*/
static private $failedToAutoload = [];
public static function reset() : void
{
self::$autoloadNamespaces = [];
self::$loaders = [];
self::$failedToAutoload = [];
}
/**
* Registers file.
*
* @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
* autoloading should be deferred to the globally registered autoloader by then. For now,
* use @example AnnotationRegistry::registerLoader('class_exists')
*/
public static function registerFile(string $file) : void
{
require_once $file;
}
/**
* Adds a namespace with one or many directories to look for files or null for the include path.
*
* Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
*
* @param string $namespace
* @param string|array|null $dirs
*
* @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
* autoloading should be deferred to the globally registered autoloader by then. For now,
* use @example AnnotationRegistry::registerLoader('class_exists')
*/
public static function registerAutoloadNamespace(string $namespace, $dirs = null) : void
{
self::$autoloadNamespaces[$namespace] = $dirs;
}
/**
* Registers multiple namespaces.
*
* Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
*
* @param string[][]|string[]|null[] $namespaces indexed by namespace name
*
* @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
* autoloading should be deferred to the globally registered autoloader by then. For now,
* use @example AnnotationRegistry::registerLoader('class_exists')
*/
public static function registerAutoloadNamespaces(array $namespaces) : void
{
self::$autoloadNamespaces = \array_merge(self::$autoloadNamespaces, $namespaces);
}
/**
* Registers an autoloading callable for annotations, much like spl_autoload_register().
*
* NOTE: These class loaders HAVE to be silent when a class was not found!
* IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class.
*
* @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
* autoloading should be deferred to the globally registered autoloader by then. For now,
* use @example AnnotationRegistry::registerLoader('class_exists')
*/
public static function registerLoader(callable $callable) : void
{
// Reset our static cache now that we have a new loader to work with
self::$failedToAutoload = [];
self::$loaders[] = $callable;
}
/**
* Registers an autoloading callable for annotations, if it is not already registered
*
* @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
*/
public static function registerUniqueLoader(callable $callable) : void
{
if ( ! in_array($callable, self::$loaders, true) ) {
self::registerLoader($callable);
}
}
/**
* Autoloads an annotation class silently.
*/
public static function loadAnnotationClass(string $class) : bool
{
if (\class_exists($class, false)) {
return true;
}
if (\array_key_exists($class, self::$failedToAutoload)) {
return false;
}
foreach (self::$autoloadNamespaces AS $namespace => $dirs) {
if (\strpos($class, $namespace) === 0) {
$file = \str_replace('\\', \DIRECTORY_SEPARATOR, $class) . '.php';
if ($dirs === null) {
if ($path = stream_resolve_include_path($file)) {
require $path;
return true;
}
} else {
foreach((array) $dirs AS $dir) {
if (is_file($dir . \DIRECTORY_SEPARATOR . $file)) {
require $dir . \DIRECTORY_SEPARATOR . $file;
return true;
}
}
}
}
}
foreach (self::$loaders AS $loader) {
if ($loader($class) === true) {
return true;
}
}
self::$failedToAutoload[$class] = null;
return false;
}
}

View File

@ -0,0 +1,262 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
use Doctrine\Common\Cache\Cache;
use ReflectionClass;
/**
* A cache aware annotation reader.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
final class CachedReader implements Reader
{
/**
* @var Reader
*/
private $delegate;
/**
* @var Cache
*/
private $cache;
/**
* @var boolean
*/
private $debug;
/**
* @var array
*/
private $loadedAnnotations = array();
/**
* Constructor.
*
* @param Reader $reader
* @param Cache $cache
* @param bool $debug
*/
public function __construct(Reader $reader, Cache $cache, $debug = false)
{
$this->delegate = $reader;
$this->cache = $cache;
$this->debug = (boolean) $debug;
}
/**
* {@inheritDoc}
*/
public function getClassAnnotations(ReflectionClass $class)
{
$cacheKey = $class->getName();
if (isset($this->loadedAnnotations[$cacheKey])) {
return $this->loadedAnnotations[$cacheKey];
}
if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) {
$annots = $this->delegate->getClassAnnotations($class);
$this->saveToCache($cacheKey, $annots);
}
return $this->loadedAnnotations[$cacheKey] = $annots;
}
/**
* {@inheritDoc}
*/
public function getClassAnnotation(ReflectionClass $class, $annotationName)
{
foreach ($this->getClassAnnotations($class) as $annot) {
if ($annot instanceof $annotationName) {
return $annot;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public function getPropertyAnnotations(\ReflectionProperty $property)
{
$class = $property->getDeclaringClass();
$cacheKey = $class->getName().'$'.$property->getName();
if (isset($this->loadedAnnotations[$cacheKey])) {
return $this->loadedAnnotations[$cacheKey];
}
if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) {
$annots = $this->delegate->getPropertyAnnotations($property);
$this->saveToCache($cacheKey, $annots);
}
return $this->loadedAnnotations[$cacheKey] = $annots;
}
/**
* {@inheritDoc}
*/
public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
{
foreach ($this->getPropertyAnnotations($property) as $annot) {
if ($annot instanceof $annotationName) {
return $annot;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public function getMethodAnnotations(\ReflectionMethod $method)
{
$class = $method->getDeclaringClass();
$cacheKey = $class->getName().'#'.$method->getName();
if (isset($this->loadedAnnotations[$cacheKey])) {
return $this->loadedAnnotations[$cacheKey];
}
if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) {
$annots = $this->delegate->getMethodAnnotations($method);
$this->saveToCache($cacheKey, $annots);
}
return $this->loadedAnnotations[$cacheKey] = $annots;
}
/**
* {@inheritDoc}
*/
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
{
foreach ($this->getMethodAnnotations($method) as $annot) {
if ($annot instanceof $annotationName) {
return $annot;
}
}
return null;
}
/**
* Clears loaded annotations.
*
* @return void
*/
public function clearLoadedAnnotations()
{
$this->loadedAnnotations = array();
}
/**
* Fetches a value from the cache.
*
* @param string $cacheKey The cache key.
* @param ReflectionClass $class The related class.
*
* @return mixed The cached value or false when the value is not in cache.
*/
private function fetchFromCache($cacheKey, ReflectionClass $class)
{
if (($data = $this->cache->fetch($cacheKey)) !== false) {
if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
return $data;
}
}
return false;
}
/**
* Saves a value to the cache.
*
* @param string $cacheKey The cache key.
* @param mixed $value The value.
*
* @return void
*/
private function saveToCache($cacheKey, $value)
{
$this->cache->save($cacheKey, $value);
if ($this->debug) {
$this->cache->save('[C]'.$cacheKey, time());
}
}
/**
* Checks if the cache is fresh.
*
* @param string $cacheKey
* @param ReflectionClass $class
*
* @return boolean
*/
private function isCacheFresh($cacheKey, ReflectionClass $class)
{
if (null === $lastModification = $this->getLastModification($class)) {
return true;
}
return $this->cache->fetch('[C]'.$cacheKey) >= $lastModification;
}
/**
* Returns the time the class was last modified, testing traits and parents
*
* @param ReflectionClass $class
* @return int
*/
private function getLastModification(ReflectionClass $class)
{
$filename = $class->getFileName();
$parent = $class->getParentClass();
return max(array_merge(
[$filename ? filemtime($filename) : 0],
array_map([$this, 'getTraitLastModificationTime'], $class->getTraits()),
array_map([$this, 'getLastModification'], $class->getInterfaces()),
$parent ? [$this->getLastModification($parent)] : []
));
}
/**
* @param ReflectionClass $reflectionTrait
* @return int
*/
private function getTraitLastModificationTime(ReflectionClass $reflectionTrait)
{
$fileName = $reflectionTrait->getFileName();
return max(array_merge(
[$fileName ? filemtime($fileName) : 0],
array_map([$this, 'getTraitLastModificationTime'], $reflectionTrait->getTraits())
));
}
}

View File

@ -0,0 +1,134 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
use Doctrine\Common\Lexer\AbstractLexer;
/**
* Simple lexer for docblock annotations.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
final class DocLexer extends AbstractLexer
{
const T_NONE = 1;
const T_INTEGER = 2;
const T_STRING = 3;
const T_FLOAT = 4;
// All tokens that are also identifiers should be >= 100
const T_IDENTIFIER = 100;
const T_AT = 101;
const T_CLOSE_CURLY_BRACES = 102;
const T_CLOSE_PARENTHESIS = 103;
const T_COMMA = 104;
const T_EQUALS = 105;
const T_FALSE = 106;
const T_NAMESPACE_SEPARATOR = 107;
const T_OPEN_CURLY_BRACES = 108;
const T_OPEN_PARENTHESIS = 109;
const T_TRUE = 110;
const T_NULL = 111;
const T_COLON = 112;
/**
* @var array
*/
protected $noCase = array(
'@' => self::T_AT,
',' => self::T_COMMA,
'(' => self::T_OPEN_PARENTHESIS,
')' => self::T_CLOSE_PARENTHESIS,
'{' => self::T_OPEN_CURLY_BRACES,
'}' => self::T_CLOSE_CURLY_BRACES,
'=' => self::T_EQUALS,
':' => self::T_COLON,
'\\' => self::T_NAMESPACE_SEPARATOR
);
/**
* @var array
*/
protected $withCase = array(
'true' => self::T_TRUE,
'false' => self::T_FALSE,
'null' => self::T_NULL
);
/**
* {@inheritdoc}
*/
protected function getCatchablePatterns()
{
return array(
'[a-z_\\\][a-z0-9_\:\\\]*[a-z_][a-z0-9_]*',
'(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?',
'"(?:""|[^"])*+"',
);
}
/**
* {@inheritdoc}
*/
protected function getNonCatchablePatterns()
{
return array('\s+', '\*+', '(.)');
}
/**
* {@inheritdoc}
*/
protected function getType(&$value)
{
$type = self::T_NONE;
if ($value[0] === '"') {
$value = str_replace('""', '"', substr($value, 1, strlen($value) - 2));
return self::T_STRING;
}
if (isset($this->noCase[$value])) {
return $this->noCase[$value];
}
if ($value[0] === '_' || $value[0] === '\\' || ctype_alpha($value[0])) {
return self::T_IDENTIFIER;
}
$lowerValue = strtolower($value);
if (isset($this->withCase[$lowerValue])) {
return $this->withCase[$lowerValue];
}
// Checking numeric value
if (is_numeric($value)) {
return (strpos($value, '.') !== false || stripos($value, 'e') !== false)
? self::T_FLOAT : self::T_INTEGER;
}
return $type;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,290 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
/**
* File cache reader for annotations.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*
* @deprecated the FileCacheReader is deprecated and will be removed
* in version 2.0.0 of doctrine/annotations. Please use the
* {@see \Doctrine\Common\Annotations\CachedReader} instead.
*/
class FileCacheReader implements Reader
{
/**
* @var Reader
*/
private $reader;
/**
* @var string
*/
private $dir;
/**
* @var bool
*/
private $debug;
/**
* @var array
*/
private $loadedAnnotations = array();
/**
* @var array
*/
private $classNameHashes = array();
/**
* @var int
*/
private $umask;
/**
* Constructor.
*
* @param Reader $reader
* @param string $cacheDir
* @param boolean $debug
*
* @throws \InvalidArgumentException
*/
public function __construct(Reader $reader, $cacheDir, $debug = false, $umask = 0002)
{
if ( ! is_int($umask)) {
throw new \InvalidArgumentException(sprintf(
'The parameter umask must be an integer, was: %s',
gettype($umask)
));
}
$this->reader = $reader;
$this->umask = $umask;
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777 & (~$this->umask), true)) {
throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $cacheDir));
}
$this->dir = rtrim($cacheDir, '\\/');
$this->debug = $debug;
}
/**
* {@inheritDoc}
*/
public function getClassAnnotations(\ReflectionClass $class)
{
if ( ! isset($this->classNameHashes[$class->name])) {
$this->classNameHashes[$class->name] = sha1($class->name);
}
$key = $this->classNameHashes[$class->name];
if (isset($this->loadedAnnotations[$key])) {
return $this->loadedAnnotations[$key];
}
$path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
if (!is_file($path)) {
$annot = $this->reader->getClassAnnotations($class);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
if ($this->debug
&& (false !== $filename = $class->getFileName())
&& filemtime($path) < filemtime($filename)) {
@unlink($path);
$annot = $this->reader->getClassAnnotations($class);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
return $this->loadedAnnotations[$key] = include $path;
}
/**
* {@inheritDoc}
*/
public function getPropertyAnnotations(\ReflectionProperty $property)
{
$class = $property->getDeclaringClass();
if ( ! isset($this->classNameHashes[$class->name])) {
$this->classNameHashes[$class->name] = sha1($class->name);
}
$key = $this->classNameHashes[$class->name].'$'.$property->getName();
if (isset($this->loadedAnnotations[$key])) {
return $this->loadedAnnotations[$key];
}
$path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
if (!is_file($path)) {
$annot = $this->reader->getPropertyAnnotations($property);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
if ($this->debug
&& (false !== $filename = $class->getFilename())
&& filemtime($path) < filemtime($filename)) {
@unlink($path);
$annot = $this->reader->getPropertyAnnotations($property);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
return $this->loadedAnnotations[$key] = include $path;
}
/**
* {@inheritDoc}
*/
public function getMethodAnnotations(\ReflectionMethod $method)
{
$class = $method->getDeclaringClass();
if ( ! isset($this->classNameHashes[$class->name])) {
$this->classNameHashes[$class->name] = sha1($class->name);
}
$key = $this->classNameHashes[$class->name].'#'.$method->getName();
if (isset($this->loadedAnnotations[$key])) {
return $this->loadedAnnotations[$key];
}
$path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
if (!is_file($path)) {
$annot = $this->reader->getMethodAnnotations($method);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
if ($this->debug
&& (false !== $filename = $class->getFilename())
&& filemtime($path) < filemtime($filename)) {
@unlink($path);
$annot = $this->reader->getMethodAnnotations($method);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
return $this->loadedAnnotations[$key] = include $path;
}
/**
* Saves the cache file.
*
* @param string $path
* @param mixed $data
*
* @return void
*/
private function saveCacheFile($path, $data)
{
if (!is_writable($this->dir)) {
throw new \InvalidArgumentException(sprintf('The directory "%s" is not writable. Both, the webserver and the console user need access. You can manage access rights for multiple users with "chmod +a". If your system does not support this, check out the acl package.', $this->dir));
}
$tempfile = tempnam($this->dir, uniqid('', true));
if (false === $tempfile) {
throw new \RuntimeException(sprintf('Unable to create tempfile in directory: %s', $this->dir));
}
@chmod($tempfile, 0666 & (~$this->umask));
$written = file_put_contents($tempfile, '<?php return unserialize('.var_export(serialize($data), true).');');
if (false === $written) {
throw new \RuntimeException(sprintf('Unable to write cached file to: %s', $tempfile));
}
@chmod($tempfile, 0666 & (~$this->umask));
if (false === rename($tempfile, $path)) {
@unlink($tempfile);
throw new \RuntimeException(sprintf('Unable to rename %s to %s', $tempfile, $path));
}
}
/**
* {@inheritDoc}
*/
public function getClassAnnotation(\ReflectionClass $class, $annotationName)
{
$annotations = $this->getClassAnnotations($class);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
{
$annotations = $this->getMethodAnnotations($method);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
{
$annotations = $this->getPropertyAnnotations($property);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* Clears loaded annotations.
*
* @return void
*/
public function clearLoadedAnnotations()
{
$this->loadedAnnotations = array();
}
}

View File

@ -0,0 +1,119 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
/**
* Allows the reader to be used in-place of Doctrine's reader.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class IndexedReader implements Reader
{
/**
* @var Reader
*/
private $delegate;
/**
* Constructor.
*
* @param Reader $reader
*/
public function __construct(Reader $reader)
{
$this->delegate = $reader;
}
/**
* {@inheritDoc}
*/
public function getClassAnnotations(\ReflectionClass $class)
{
$annotations = array();
foreach ($this->delegate->getClassAnnotations($class) as $annot) {
$annotations[get_class($annot)] = $annot;
}
return $annotations;
}
/**
* {@inheritDoc}
*/
public function getClassAnnotation(\ReflectionClass $class, $annotation)
{
return $this->delegate->getClassAnnotation($class, $annotation);
}
/**
* {@inheritDoc}
*/
public function getMethodAnnotations(\ReflectionMethod $method)
{
$annotations = array();
foreach ($this->delegate->getMethodAnnotations($method) as $annot) {
$annotations[get_class($annot)] = $annot;
}
return $annotations;
}
/**
* {@inheritDoc}
*/
public function getMethodAnnotation(\ReflectionMethod $method, $annotation)
{
return $this->delegate->getMethodAnnotation($method, $annotation);
}
/**
* {@inheritDoc}
*/
public function getPropertyAnnotations(\ReflectionProperty $property)
{
$annotations = array();
foreach ($this->delegate->getPropertyAnnotations($property) as $annot) {
$annotations[get_class($annot)] = $annot;
}
return $annotations;
}
/**
* {@inheritDoc}
*/
public function getPropertyAnnotation(\ReflectionProperty $property, $annotation)
{
return $this->delegate->getPropertyAnnotation($property, $annotation);
}
/**
* Proxies all methods to the delegate.
*
* @param string $method
* @param array $args
*
* @return mixed
*/
public function __call($method, $args)
{
return call_user_func_array(array($this->delegate, $method), $args);
}
}

View File

@ -0,0 +1,91 @@
<?php
/*
* 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
* OWNER 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.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
use SplFileObject;
/**
* Parses a file for namespaces/use/class declarations.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Christian Kaps <christian.kaps@mohiva.com>
*/
final class PhpParser
{
/**
* Parses a class.
*
* @param \ReflectionClass $class A <code>ReflectionClass</code> object.
*
* @return array A list with use statements in the form (Alias => FQN).
*/
public function parseClass(\ReflectionClass $class)
{
if (method_exists($class, 'getUseStatements')) {
return $class->getUseStatements();
}
if (false === $filename = $class->getFileName()) {
return array();
}
$content = $this->getFileContent($filename, $class->getStartLine());
if (null === $content) {
return array();
}
$namespace = preg_quote($class->getNamespaceName());
$content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content);
$tokenizer = new TokenParser('<?php ' . $content);
$statements = $tokenizer->parseUseStatements($class->getNamespaceName());
return $statements;
}
/**
* Gets the content of the file right up to the given line number.
*
* @param string $filename The name of the file to load.
* @param integer $lineNumber The number of lines to read from file.
*
* @return string|null The content of the file or null if the file does not exist.
*/
private function getFileContent($filename, $lineNumber)
{
if ( ! is_file($filename)) {
return null;
}
$content = '';
$lineCnt = 0;
$file = new SplFileObject($filename);
while (!$file->eof()) {
if ($lineCnt++ == $lineNumber) {
break;
}
$content .= $file->fgets();
}
return $content;
}
}

Some files were not shown because too many files have changed in this diff Show More