N°1280 Upgrade Silex library to 2.2 (Which is possible as iTop 2.5 requirements are now PHP 5.6+!)

SVN:trunk[5305]
This commit is contained in:
Guillaume Lajarige
2018-01-31 13:37:51 +00:00
parent a7cfcefee2
commit 0254a75c95
1446 changed files with 100946 additions and 5486 deletions

View File

@@ -377,9 +377,9 @@ class ObjectFormManager extends FormManager
if ($this->aFormProperties['layout']['type'] === 'twig')
{
// Creating sandbox twig env. to load and test the custom form template
$oTwig = new \Twig_Environment(new \Twig_Loader_String());
$oTwig = new \Twig_Environment(new \Twig_Loader_Array( array($oForm->GetId() => $this->aFormProperties['layout']['content']) ));
ApplicationHelper::RegisterTwigExtensions($oTwig);
$sRendered = $oTwig->render($this->aFormProperties['layout']['content'], array('oRenderer' => $this->oRenderer, 'oObject' => $this->oObject));
$sRendered = $oTwig->render($oForm->GetId(), array('oRenderer' => $this->oRenderer, 'oObject' => $this->oObject));
}
else
{

View File

@@ -23,6 +23,8 @@ use Exception;
use Silex\Application;
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\ExceptionHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Twig_Environment;
use Twig_SimpleFilter;
use Dict;
@@ -277,16 +279,18 @@ class ApplicationHelper
// Intercepting manually aborted request
if (1 || !$oApp['debug'])
{
$oApp->error(function(Exception $e, $code) use ($oApp)
$oApp->error(function(Exception $oException, Request $oRequest) use ($oApp)
{
$iErrorCode = ($oException instanceof HttpException) ? $oException->getStatusCode() : 500;
$aData = array(
'exception' => $e,
'code' => $code,
'exception' => $oException,
'code' => $iErrorCode,
'error_title' => '',
'error_message' => $e->getMessage()
'error_message' => $oException->getMessage()
);
switch ($code)
switch ($iErrorCode)
{
case 404:
$aData['error_title'] = Dict::S('Error:HTTP:404');
@@ -298,15 +302,15 @@ class ApplicationHelper
IssueLog::Error($aData['error_title'] . ' : ' . $aData['error_message']);
if ($oApp['request']->isXmlHttpRequest())
if ($oApp['request_stack']->getCurrentRequest()->isXmlHttpRequest())
{
$oResponse = $oApp->json($aData, $code);
$oResponse = $oApp->json($aData, $iErrorCode);
}
else
{
// Preparing debug trace
$aSteps = array();
foreach($e->getTrace() as $aStep)
foreach($oException->getTrace() as $aStep)
{
// - Default file name
if(!isset($aStep['file']))

View File

@@ -19,8 +19,8 @@
namespace Combodo\iTop\Portal\Provider;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Combodo\iTop\Portal\Helper\ContextManipulatorHelper;
/**
@@ -31,9 +31,9 @@ use Combodo\iTop\Portal\Helper\ContextManipulatorHelper;
class ContextManipulatorServiceProvider implements ServiceProviderInterface
{
public function register(Application $oApp)
public function register(Container $oApp)
{
$oApp['context_manipulator'] = $oApp->share(function ($oApp)
$oApp['context_manipulator'] = function ($oApp)
{
$oApp->flush();
@@ -41,10 +41,10 @@ class ContextManipulatorServiceProvider implements ServiceProviderInterface
$oContextManipulatorHelper->SetApp($oApp);
return $oContextManipulatorHelper;
});
};
}
public function boot(Application $oApp)
public function boot(Container $oApp)
{
}

View File

@@ -19,8 +19,8 @@
namespace Combodo\iTop\Portal\Provider;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Combodo\iTop\Portal\Helper\LifecycleValidatorHelper;
/**
@@ -31,9 +31,9 @@ use Combodo\iTop\Portal\Helper\LifecycleValidatorHelper;
class LifecycleValidatorServiceProvider implements ServiceProviderInterface
{
public function register(Application $oApp)
public function register(Container $oApp)
{
$oApp['lifecycle_validator'] = $oApp->share(function ($oApp)
$oApp['lifecycle_validator'] = function ($oApp)
{
$oApp->flush();
@@ -44,10 +44,10 @@ class LifecycleValidatorServiceProvider implements ServiceProviderInterface
}
return $oLifecycleValidatorHelper;
});
};
}
public function boot(Application $oApp)
public function boot(Container $oApp)
{
}

View File

@@ -19,8 +19,8 @@
namespace Combodo\iTop\Portal\Provider;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Combodo\iTop\Portal\Helper\ScopeValidatorHelper;
/**
@@ -31,9 +31,9 @@ use Combodo\iTop\Portal\Helper\ScopeValidatorHelper;
class ScopeValidatorServiceProvider implements ServiceProviderInterface
{
public function register(Application $oApp)
public function register(Container $oApp)
{
$oApp['scope_validator'] = $oApp->share(function ($oApp)
$oApp['scope_validator'] = function ($oApp)
{
$oApp->flush();
@@ -44,10 +44,10 @@ class ScopeValidatorServiceProvider implements ServiceProviderInterface
}
return $oScopeValidatorHelper;
});
};
}
public function boot(Application $oApp)
public function boot(Container $oApp)
{
}

View File

@@ -19,8 +19,8 @@
namespace Combodo\iTop\Portal\Provider;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Combodo\iTop\Portal\Helper\UrlGenerator;
/**
@@ -31,17 +31,17 @@ use Combodo\iTop\Portal\Helper\UrlGenerator;
class UrlGeneratorServiceProvider implements ServiceProviderInterface
{
public function register(Application $oApp)
public function register(Container $oApp)
{
$oApp['url_generator'] = $oApp->share(function ($oApp)
$oApp['url_generator'] = function ($oApp)
{
$oApp->flush();
return new UrlGenerator($oApp['routes'], $oApp['request_context']);
});
};
}
public function boot(Application $oApp)
public function boot(Container $oApp)
{
}

View File

@@ -1,6 +1,6 @@
{
"require": {
"silex/silex": "~1.1",
"twig/twig": "1.21.*"
"silex/silex": "~2.0",
"twig/twig": "1.35"
}
}

578
lib/silex/composer.lock generated
View File

@@ -4,35 +4,86 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "0cef8e455a5b99f76246934c54fb0b18",
"content-hash": "bcccad4b8962ec6793031384b3b2fc97",
"content-hash": "d3dddb99878fdc490eef79fde08c0b81",
"packages": [
{
"name": "pimple/pimple",
"version": "v1.1.1",
"name": "paragonie/random_compat",
"version": "v2.0.11",
"source": {
"type": "git",
"url": "https://github.com/silexphp/Pimple.git",
"reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d"
"url": "https://github.com/paragonie/random_compat.git",
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d",
"reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8",
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
],
"time": "2017-09-27T21:40:39+00:00"
},
{
"name": "pimple/pimple",
"version": "v3.2.3",
"source": {
"type": "git",
"url": "https://github.com/silexphp/Pimple.git",
"reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32",
"reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/container": "^1.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^3.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
"dev-master": "3.2.x-dev"
}
},
"autoload": {
"psr-0": {
"Pimple": "lib/"
"Pimple": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -45,32 +96,89 @@
"email": "fabien@symfony.com"
}
],
"description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
"description": "Pimple, a simple Dependency Injection Container",
"homepage": "http://pimple.sensiolabs.org",
"keywords": [
"container",
"dependency injection"
],
"time": "2013-11-22 08:30:29"
"time": "2018-01-21T07:42:36+00:00"
},
{
"name": "psr/log",
"name": "psr/container",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
"url": "https://github.com/php-fig/container.git",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Psr\\Log\\": ""
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"time": "2017-02-14T16:28:37+00:00"
},
{
"name": "psr/log",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -84,72 +192,80 @@
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"time": "2012-12-21 11:40:51"
"time": "2016-10-10T12:19:37+00:00"
},
{
"name": "silex/silex",
"version": "v1.2.5",
"version": "v2.2.2",
"source": {
"type": "git",
"url": "https://github.com/silexphp/Silex.git",
"reference": "ce75b98d82d4c509802e63005c618392db17afef"
"reference": "3fe50331f194c83ded2f824c47c1c24c20877a8c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/silexphp/Silex/zipball/ce75b98d82d4c509802e63005c618392db17afef",
"reference": "ce75b98d82d4c509802e63005c618392db17afef",
"url": "https://api.github.com/repos/silexphp/Silex/zipball/3fe50331f194c83ded2f824c47c1c24c20877a8c",
"reference": "3fe50331f194c83ded2f824c47c1c24c20877a8c",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"pimple/pimple": "~1.0",
"symfony/event-dispatcher": "~2.3,<2.7",
"symfony/http-foundation": "~2.3,<2.7",
"symfony/http-kernel": "~2.3,<2.7",
"symfony/routing": "~2.3,<2.7"
"php": ">=5.5.9",
"pimple/pimple": "~3.0",
"symfony/event-dispatcher": "~2.8|^3.0",
"symfony/http-foundation": "~2.8|^3.0",
"symfony/http-kernel": "~2.8|^3.0",
"symfony/routing": "~2.8|^3.0"
},
"conflict": {
"phpunit/phpunit": "<4.8.35 || >= 5.0, <5.4.3"
},
"replace": {
"silex/api": "self.version",
"silex/providers": "self.version"
},
"require-dev": {
"doctrine/dbal": "~2.2",
"monolog/monolog": "~1.4,>=1.4.1",
"swiftmailer/swiftmailer": "5.*",
"symfony/browser-kit": "~2.3,<2.7",
"symfony/config": "~2.3,<2.7",
"symfony/css-selector": "~2.3,<2.7",
"symfony/debug": "~2.3,<2.7",
"symfony/dom-crawler": "~2.3,<2.7",
"symfony/finder": "~2.3,<2.7",
"symfony/form": "~2.3,<2.7",
"symfony/locale": "~2.3,<2.7",
"symfony/monolog-bridge": "~2.3,<2.7",
"symfony/options-resolver": "~2.3,<2.7",
"symfony/process": "~2.3,<2.7",
"symfony/security": "~2.3,<2.7",
"symfony/serializer": "~2.3,<2.7",
"symfony/translation": "~2.3,<2.7",
"symfony/twig-bridge": "~2.3,<2.7",
"symfony/validator": "~2.3,<2.7",
"twig/twig": ">=1.8.0,<2.0-dev"
},
"suggest": {
"symfony/browser-kit": "~2.3",
"symfony/css-selector": "~2.3",
"symfony/dom-crawler": "~2.3",
"symfony/form": "~2.3"
"monolog/monolog": "^1.4.1",
"swiftmailer/swiftmailer": "~5",
"symfony/asset": "~2.8|^3.0",
"symfony/browser-kit": "~2.8|^3.0",
"symfony/config": "~2.8|^3.0",
"symfony/css-selector": "~2.8|^3.0",
"symfony/debug": "~2.8|^3.0",
"symfony/doctrine-bridge": "~2.8|^3.0",
"symfony/dom-crawler": "~2.8|^3.0",
"symfony/expression-language": "~2.8|^3.0",
"symfony/finder": "~2.8|^3.0",
"symfony/form": "~2.8|^3.0",
"symfony/intl": "~2.8|^3.0",
"symfony/monolog-bridge": "~2.8|^3.0",
"symfony/options-resolver": "~2.8|^3.0",
"symfony/phpunit-bridge": "^3.2",
"symfony/process": "~2.8|^3.0",
"symfony/security": "~2.8|^3.0",
"symfony/serializer": "~2.8|^3.0",
"symfony/translation": "~2.8|^3.0",
"symfony/twig-bridge": "~2.8|^3.0",
"symfony/validator": "~2.8|^3.0",
"symfony/var-dumper": "~2.8|^3.0",
"symfony/web-link": "^3.3",
"twig/twig": "~1.28|~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
"dev-master": "2.2.x-dev"
}
},
"autoload": {
"psr-0": {
"Silex": "src/"
"psr-4": {
"Silex\\": "src/Silex"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -166,55 +282,50 @@
"email": "igor@wiedler.ch"
}
],
"description": "The PHP micro-framework based on the Symfony2 Components",
"description": "The PHP micro-framework based on the Symfony Components",
"homepage": "http://silex.sensiolabs.org",
"keywords": [
"microframework"
],
"time": "2015-06-04 21:24:58"
"time": "2018-01-12T07:16:03+00:00"
},
{
"name": "symfony/debug",
"version": "v2.6.12",
"target-dir": "Symfony/Component/Debug",
"version": "v3.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941"
"reference": "53f6af2805daf52a43b393b93d2f24925d35c937"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/fca5696e0c9787722baa8f2ad6940dfd7a6a6941",
"reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941",
"url": "https://api.github.com/repos/symfony/debug/zipball/53f6af2805daf52a43b393b93d2f24925d35c937",
"reference": "53f6af2805daf52a43b393b93d2f24925d35c937",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"php": "^5.5.9|>=7.0.8",
"psr/log": "~1.0"
},
"conflict": {
"symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
},
"require-dev": {
"symfony/class-loader": "~2.2",
"symfony/http-foundation": "~2.1",
"symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2",
"symfony/phpunit-bridge": "~2.7"
},
"suggest": {
"symfony/http-foundation": "",
"symfony/http-kernel": ""
"symfony/http-kernel": "~2.8|~3.0|~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.6-dev"
"dev-master": "3.4-dev"
}
},
"autoload": {
"psr-0": {
"psr-4": {
"Symfony\\Component\\Debug\\": ""
}
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -232,33 +343,34 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2015-07-08 05:59:48"
"time": "2018-01-18T22:16:57+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v2.6.12",
"target-dir": "Symfony/Component/EventDispatcher",
"version": "v3.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02"
"reference": "26b87b6bca8f8f797331a30b76fdae5342dc26ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02",
"reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/26b87b6bca8f8f797331a30b76fdae5342dc26ca",
"reference": "26b87b6bca8f8f797331a30b76fdae5342dc26ca",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
"php": "^5.5.9|>=7.0.8"
},
"conflict": {
"symfony/dependency-injection": "<3.3"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~2.0,>=2.0.5",
"symfony/dependency-injection": "~2.6",
"symfony/expression-language": "~2.6",
"symfony/phpunit-bridge": "~2.7",
"symfony/stopwatch": "~2.3"
"symfony/config": "~2.8|~3.0|~4.0",
"symfony/dependency-injection": "~3.3|~4.0",
"symfony/expression-language": "~2.8|~3.0|~4.0",
"symfony/stopwatch": "~2.8|~3.0|~4.0"
},
"suggest": {
"symfony/dependency-injection": "",
@@ -267,13 +379,16 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.6-dev"
"dev-master": "3.4-dev"
}
},
"autoload": {
"psr-0": {
"psr-4": {
"Symfony\\Component\\EventDispatcher\\": ""
}
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -291,42 +406,42 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2015-05-02 15:18:45"
"time": "2018-01-03T07:37:34+00:00"
},
{
"name": "symfony/http-foundation",
"version": "v2.6.12",
"target-dir": "Symfony/Component/HttpFoundation",
"version": "v3.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c"
"reference": "8c39071ac9cc7e6d8dab1d556c990dc0d2cc3d30"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
"reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/8c39071ac9cc7e6d8dab1d556c990dc0d2cc3d30",
"reference": "8c39071ac9cc7e6d8dab1d556c990dc0d2cc3d30",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
"php": "^5.5.9|>=7.0.8",
"symfony/polyfill-mbstring": "~1.1",
"symfony/polyfill-php70": "~1.6"
},
"require-dev": {
"symfony/expression-language": "~2.4",
"symfony/phpunit-bridge": "~2.7"
"symfony/expression-language": "~2.8|~3.0|~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.6-dev"
"dev-master": "3.4-dev"
}
},
"autoload": {
"psr-0": {
"psr-4": {
"Symfony\\Component\\HttpFoundation\\": ""
},
"classmap": [
"Symfony/Component/HttpFoundation/Resources/stubs"
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -345,51 +460,58 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"time": "2015-07-22 10:08:40"
"time": "2018-01-29T09:03:43+00:00"
},
{
"name": "symfony/http-kernel",
"version": "v2.6.12",
"target-dir": "Symfony/Component/HttpKernel",
"version": "v3.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6"
"reference": "911d2e5dd4beb63caad9a72e43857de984301907"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6",
"reference": "498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/911d2e5dd4beb63caad9a72e43857de984301907",
"reference": "911d2e5dd4beb63caad9a72e43857de984301907",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"php": "^5.5.9|>=7.0.8",
"psr/log": "~1.0",
"symfony/debug": "~2.6,>=2.6.2",
"symfony/event-dispatcher": "~2.6,>=2.6.7",
"symfony/http-foundation": "~2.5,>=2.5.4"
"symfony/debug": "~2.8|~3.0|~4.0",
"symfony/event-dispatcher": "~2.8|~3.0|~4.0",
"symfony/http-foundation": "^3.4.4|^4.0.4"
},
"conflict": {
"symfony/config": "<2.8",
"symfony/dependency-injection": "<3.4",
"symfony/var-dumper": "<3.3",
"twig/twig": "<1.34|<2.4,>=2"
},
"provide": {
"psr/log-implementation": "1.0"
},
"require-dev": {
"symfony/browser-kit": "~2.3",
"symfony/class-loader": "~2.1",
"symfony/config": "~2.0,>=2.0.5",
"symfony/console": "~2.3",
"symfony/css-selector": "~2.0,>=2.0.5",
"symfony/dependency-injection": "~2.2",
"symfony/dom-crawler": "~2.0,>=2.0.5",
"symfony/expression-language": "~2.4",
"symfony/finder": "~2.0,>=2.0.5",
"symfony/phpunit-bridge": "~2.7",
"symfony/process": "~2.0,>=2.0.5",
"symfony/routing": "~2.2",
"symfony/stopwatch": "~2.3",
"symfony/templating": "~2.2",
"symfony/translation": "~2.0,>=2.0.5",
"symfony/var-dumper": "~2.6"
"psr/cache": "~1.0",
"symfony/browser-kit": "~2.8|~3.0|~4.0",
"symfony/class-loader": "~2.8|~3.0",
"symfony/config": "~2.8|~3.0|~4.0",
"symfony/console": "~2.8|~3.0|~4.0",
"symfony/css-selector": "~2.8|~3.0|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/dom-crawler": "~2.8|~3.0|~4.0",
"symfony/expression-language": "~2.8|~3.0|~4.0",
"symfony/finder": "~2.8|~3.0|~4.0",
"symfony/process": "~2.8|~3.0|~4.0",
"symfony/routing": "~3.4|~4.0",
"symfony/stopwatch": "~2.8|~3.0|~4.0",
"symfony/templating": "~2.8|~3.0|~4.0",
"symfony/translation": "~2.8|~3.0|~4.0",
"symfony/var-dumper": "~3.3|~4.0"
},
"suggest": {
"symfony/browser-kit": "",
"symfony/class-loader": "",
"symfony/config": "",
"symfony/console": "",
"symfony/dependency-injection": "",
@@ -399,13 +521,16 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.6-dev"
"dev-master": "3.4-dev"
}
},
"autoload": {
"psr-0": {
"psr-4": {
"Symfony\\Component\\HttpKernel\\": ""
}
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -423,52 +548,179 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
"time": "2015-11-23 11:37:53"
"time": "2018-01-29T12:29:46+00:00"
},
{
"name": "symfony/routing",
"version": "v2.6.12",
"target-dir": "Symfony/Component/Routing",
"name": "symfony/polyfill-mbstring",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
"reference": "0a1764d41bbb54f3864808c50569ac382b44d128"
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/0a1764d41bbb54f3864808c50569ac382b44d128",
"reference": "0a1764d41bbb54f3864808c50569ac382b44d128",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296",
"reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"time": "2017-10-11T12:05:26+00:00"
},
{
"name": "symfony/polyfill-php70",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php70.git",
"reference": "0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff",
"reference": "0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff",
"shasum": ""
},
"require": {
"paragonie/random_compat": "~1.0|~2.0",
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php70\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2017-10-11T12:05:26+00:00"
},
{
"name": "symfony/routing",
"version": "v3.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
"reference": "235d01730d553a97732990588407eaf6779bb4b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/235d01730d553a97732990588407eaf6779bb4b2",
"reference": "235d01730d553a97732990588407eaf6779bb4b2",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
},
"conflict": {
"symfony/config": "<2.8",
"symfony/dependency-injection": "<3.3",
"symfony/yaml": "<3.4"
},
"require-dev": {
"doctrine/annotations": "~1.0",
"doctrine/common": "~2.2",
"psr/log": "~1.0",
"symfony/config": "~2.2",
"symfony/expression-language": "~2.4",
"symfony/http-foundation": "~2.3",
"symfony/phpunit-bridge": "~2.7",
"symfony/yaml": "~2.0,>=2.0.5"
"symfony/config": "~2.8|~3.0|~4.0",
"symfony/dependency-injection": "~3.3|~4.0",
"symfony/expression-language": "~2.8|~3.0|~4.0",
"symfony/http-foundation": "~2.8|~3.0|~4.0",
"symfony/yaml": "~3.4|~4.0"
},
"suggest": {
"doctrine/annotations": "For using the annotation loader",
"symfony/config": "For using the all-in-one router or any loader",
"symfony/dependency-injection": "For loading routes from a service",
"symfony/expression-language": "For using expression matching",
"symfony/http-foundation": "For using a Symfony Request object",
"symfony/yaml": "For using the YAML loader"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.6-dev"
"dev-master": "3.4-dev"
}
},
"autoload": {
"psr-0": {
"psr-4": {
"Symfony\\Component\\Routing\\": ""
}
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -492,38 +744,42 @@
"uri",
"url"
],
"time": "2015-07-09 16:02:48"
"time": "2018-01-16T18:03:57+00:00"
},
{
"name": "twig/twig",
"version": "v1.21.2",
"version": "v1.35.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "ddce1136beb8db29b9cd7dffa8ab518b978c9db3"
"reference": "daa657073e55b0a78cce8fdd22682fddecc6385f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/ddce1136beb8db29b9cd7dffa8ab518b978c9db3",
"reference": "ddce1136beb8db29b9cd7dffa8ab518b978c9db3",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/daa657073e55b0a78cce8fdd22682fddecc6385f",
"reference": "daa657073e55b0a78cce8fdd22682fddecc6385f",
"shasum": ""
},
"require": {
"php": ">=5.2.7"
"php": ">=5.3.3"
},
"require-dev": {
"psr/container": "^1.0",
"symfony/debug": "~2.7",
"symfony/phpunit-bridge": "~2.7"
"symfony/phpunit-bridge": "~3.3@dev"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.21-dev"
"dev-master": "1.35-dev"
}
},
"autoload": {
"psr-0": {
"Twig_": "lib/"
},
"psr-4": {
"Twig\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -553,7 +809,7 @@
"keywords": [
"templating"
],
"time": "2015-09-09 05:28:51"
"time": "2017-09-27T18:06:46+00:00"
}
],
"packages-dev": [],

View File

@@ -2,6 +2,6 @@
// autoload.php @generated by Composer
require_once __DIR__ . '/composer' . '/autoload_real.php';
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInite16e7860e9352d90241324e1bba430e8::getLoader();
return ComposerAutoloaderInitc52ed037323c1472e1ed6497110f13b1::getLoader();

View File

@@ -13,9 +13,7 @@
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0 class loader
*
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
@@ -39,6 +37,8 @@ namespace Composer\Autoload;
*
* @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
{
@@ -53,8 +53,9 @@ class ClassLoader
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
@@ -147,7 +148,7 @@ class ClassLoader
* 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-0 base directories
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
@@ -271,6 +272,26 @@ class ClassLoader
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.
*
@@ -313,29 +334,34 @@ class ClassLoader
*/
public function findFile($class)
{
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
if ('\\' == $class[0]) {
$class = substr($class, 1);
}
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative) {
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 ($file === null && defined('HHVM_VERSION')) {
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if ($file === null) {
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
return $this->classMap[$class] = false;
$this->missingClasses[$class] = true;
}
return $file;
@@ -348,10 +374,14 @@ class ClassLoader
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
if (0 === strpos($class, $prefix)) {
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
@@ -399,6 +429,8 @@ class ClassLoader
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}

View File

@@ -1,5 +1,5 @@
Copyright (c) 2015 Nils Adermann, Jordi Boggiano
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -6,5 +6,11 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php',
'ArithmeticError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php',
'AssertionError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',
'DivisionByZeroError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php',
'Error' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/Error.php',
'ParseError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',
'SessionUpdateTimestampHandlerInterface' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php',
'TypeError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/TypeError.php',
);

View File

@@ -0,0 +1,12 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php',
);

View File

@@ -7,12 +7,5 @@ $baseDir = dirname($vendorDir);
return array(
'Twig_' => array($vendorDir . '/twig/twig/lib'),
'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'),
'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
'Silex' => array($vendorDir . '/silex/silex/src'),
'Psr\\Log\\' => array($vendorDir . '/psr/log'),
'Pimple' => array($vendorDir . '/pimple/pimple/lib'),
'Pimple' => array($vendorDir . '/pimple/pimple/src'),
);

View File

@@ -6,4 +6,15 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Twig\\' => array($vendorDir . '/twig/twig/src'),
'Symfony\\Polyfill\\Php70\\' => array($vendorDir . '/symfony/polyfill-php70'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'),
'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
'Silex\\' => array($vendorDir . '/silex/silex/src/Silex'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
);

View File

@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInite16e7860e9352d90241324e1bba430e8
class ComposerAutoloaderInitc52ed037323c1472e1ed6497110f13b1
{
private static $loader;
@@ -19,32 +19,52 @@ class ComposerAutoloaderInite16e7860e9352d90241324e1bba430e8
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInite16e7860e9352d90241324e1bba430e8', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitc52ed037323c1472e1ed6497110f13b1', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInite16e7860e9352d90241324e1bba430e8', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitc52ed037323c1472e1ed6497110f13b1', 'loadClassLoader'));
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$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';
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
call_user_func(\Composer\Autoload\ComposerStaticInitc52ed037323c1472e1ed6497110f13b1::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
$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\ComposerStaticInitc52ed037323c1472e1ed6497110f13b1::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequirec52ed037323c1472e1ed6497110f13b1($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequiree16e7860e9352d90241324e1bba430e8($file)
function composerRequirec52ed037323c1472e1ed6497110f13b1($fileIdentifier, $file)
{
require $file;
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

View File

@@ -0,0 +1,122 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInitc52ed037323c1472e1ed6497110f13b1
{
public static $files = array (
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php',
);
public static $prefixLengthsPsr4 = array (
'T' =>
array (
'Twig\\' => 5,
),
'S' =>
array (
'Symfony\\Polyfill\\Php70\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Component\\Routing\\' => 26,
'Symfony\\Component\\HttpKernel\\' => 29,
'Symfony\\Component\\HttpFoundation\\' => 33,
'Symfony\\Component\\EventDispatcher\\' => 34,
'Symfony\\Component\\Debug\\' => 24,
'Silex\\' => 6,
),
'P' =>
array (
'Psr\\Log\\' => 8,
'Psr\\Container\\' => 14,
),
);
public static $prefixDirsPsr4 = array (
'Twig\\' =>
array (
0 => __DIR__ . '/..' . '/twig/twig/src',
),
'Symfony\\Polyfill\\Php70\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php70',
),
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Component\\Routing\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/routing',
),
'Symfony\\Component\\HttpKernel\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/http-kernel',
),
'Symfony\\Component\\HttpFoundation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/http-foundation',
),
'Symfony\\Component\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
),
'Symfony\\Component\\Debug\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/debug',
),
'Silex\\' =>
array (
0 => __DIR__ . '/..' . '/silex/silex/src/Silex',
),
'Psr\\Log\\' =>
array (
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
),
'Psr\\Container\\' =>
array (
0 => __DIR__ . '/..' . '/psr/container/src',
),
);
public static $prefixesPsr0 = array (
'T' =>
array (
'Twig_' =>
array (
0 => __DIR__ . '/..' . '/twig/twig/lib',
),
),
'P' =>
array (
'Pimple' =>
array (
0 => __DIR__ . '/..' . '/pimple/pimple/src',
),
),
);
public static $classMap = array (
'ArithmeticError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php',
'AssertionError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',
'DivisionByZeroError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php',
'Error' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/Error.php',
'ParseError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',
'SessionUpdateTimestampHandlerInterface' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php',
'TypeError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/TypeError.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitc52ed037323c1472e1ed6497110f13b1::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitc52ed037323c1472e1ed6497110f13b1::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInitc52ed037323c1472e1ed6497110f13b1::$prefixesPsr0;
$loader->classMap = ComposerStaticInitc52ed037323c1472e1ed6497110f13b1::$classMap;
}, null, ClassLoader::class);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Paragon Initiative Enterprises
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,5 @@
#!/usr/bin/env bash
basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) )
php -dphar.readonly=0 "$basedir/other/build_phar.php" $*

View File

@@ -0,0 +1,37 @@
{
"name": "paragonie/random_compat",
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"random",
"pseudorandom"
],
"license": "MIT",
"type": "library",
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"support": {
"issues": "https://github.com/paragonie/random_compat/issues",
"email": "info@paragonie.com",
"source": "https://github.com/paragonie/random_compat"
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"autoload": {
"files": [
"lib/random.php"
]
}
}

View File

@@ -0,0 +1,5 @@
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm
pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p
+h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc
-----END PUBLIC KEY-----

View File

@@ -0,0 +1,11 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (MingW32)
iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip
QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg
1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW
NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA
NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV
JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74=
=B6+8
-----END PGP SIGNATURE-----

View File

@@ -0,0 +1,181 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
*
* 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.
*/
if (!is_callable('RandomCompat_strlen')) {
if (
defined('MB_OVERLOAD_STRING') &&
ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING
) {
/**
* strlen() implementation that isn't brittle to mbstring.func_overload
*
* This version uses mb_strlen() in '8bit' mode to treat strings as raw
* binary rather than UTF-8, ISO-8859-1, etc
*
* @param string $binary_string
*
* @throws TypeError
*
* @return int
*/
function RandomCompat_strlen($binary_string)
{
if (!is_string($binary_string)) {
throw new TypeError(
'RandomCompat_strlen() expects a string'
);
}
return (int) mb_strlen($binary_string, '8bit');
}
} else {
/**
* strlen() implementation that isn't brittle to mbstring.func_overload
*
* This version just used the default strlen()
*
* @param string $binary_string
*
* @throws TypeError
*
* @return int
*/
function RandomCompat_strlen($binary_string)
{
if (!is_string($binary_string)) {
throw new TypeError(
'RandomCompat_strlen() expects a string'
);
}
return (int) strlen($binary_string);
}
}
}
if (!is_callable('RandomCompat_substr')) {
if (
defined('MB_OVERLOAD_STRING')
&&
ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING
) {
/**
* substr() implementation that isn't brittle to mbstring.func_overload
*
* This version uses mb_substr() in '8bit' mode to treat strings as raw
* binary rather than UTF-8, ISO-8859-1, etc
*
* @param string $binary_string
* @param int $start
* @param int $length (optional)
*
* @throws TypeError
*
* @return string
*/
function RandomCompat_substr($binary_string, $start, $length = null)
{
if (!is_string($binary_string)) {
throw new TypeError(
'RandomCompat_substr(): First argument should be a string'
);
}
if (!is_int($start)) {
throw new TypeError(
'RandomCompat_substr(): Second argument should be an integer'
);
}
if ($length === null) {
/**
* mb_substr($str, 0, NULL, '8bit') returns an empty string on
* PHP 5.3, so we have to find the length ourselves.
*/
$length = RandomCompat_strlen($binary_string) - $start;
} elseif (!is_int($length)) {
throw new TypeError(
'RandomCompat_substr(): Third argument should be an integer, or omitted'
);
}
// Consistency with PHP's behavior
if ($start === RandomCompat_strlen($binary_string) && $length === 0) {
return '';
}
if ($start > RandomCompat_strlen($binary_string)) {
return '';
}
return (string) mb_substr($binary_string, $start, $length, '8bit');
}
} else {
/**
* substr() implementation that isn't brittle to mbstring.func_overload
*
* This version just uses the default substr()
*
* @param string $binary_string
* @param int $start
* @param int $length (optional)
*
* @throws TypeError
*
* @return string
*/
function RandomCompat_substr($binary_string, $start, $length = null)
{
if (!is_string($binary_string)) {
throw new TypeError(
'RandomCompat_substr(): First argument should be a string'
);
}
if (!is_int($start)) {
throw new TypeError(
'RandomCompat_substr(): Second argument should be an integer'
);
}
if ($length !== null) {
if (!is_int($length)) {
throw new TypeError(
'RandomCompat_substr(): Third argument should be an integer, or omitted'
);
}
return (string) substr($binary_string, $start, $length);
}
return (string) substr($binary_string, $start);
}
}
}

View File

@@ -0,0 +1,75 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
*
* 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.
*/
if (!is_callable('RandomCompat_intval')) {
/**
* Cast to an integer if we can, safely.
*
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
* lose precision, so the <= and => operators might accidentally let a float
* through.
*
* @param int|float $number The number we want to convert to an int
* @param bool $fail_open Set to true to not throw an exception
*
* @return float|int
* @psalm-suppress InvalidReturnType
*
* @throws TypeError
*/
function RandomCompat_intval($number, $fail_open = false)
{
if (is_int($number) || is_float($number)) {
$number += 0;
} elseif (is_numeric($number)) {
$number += 0;
}
if (
is_float($number)
&&
$number > ~PHP_INT_MAX
&&
$number < PHP_INT_MAX
) {
$number = (int) $number;
}
if (is_int($number)) {
return (int) $number;
} elseif (!$fail_open) {
throw new TypeError(
'Expected an integer.'
);
}
return $number;
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
*
* 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.
*/
if (!class_exists('Error', false)) {
// We can't really avoid making this extend Exception in PHP 5.
class Error extends Exception
{
}
}
if (!class_exists('TypeError', false)) {
if (is_subclass_of('Error', 'Exception')) {
class TypeError extends Error
{
}
} else {
class TypeError extends Exception
{
}
}
}

View File

@@ -0,0 +1,223 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* @version 2.0.10
* @released 2017-03-13
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
*
* 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.
*/
if (!defined('PHP_VERSION_ID')) {
// This constant was introduced in PHP 5.2.7
$RandomCompatversion = array_map('intval', explode('.', PHP_VERSION));
define(
'PHP_VERSION_ID',
$RandomCompatversion[0] * 10000
+ $RandomCompatversion[1] * 100
+ $RandomCompatversion[2]
);
$RandomCompatversion = null;
}
/**
* PHP 7.0.0 and newer have these functions natively.
*/
if (PHP_VERSION_ID >= 70000) {
return;
}
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
define('RANDOM_COMPAT_READ_BUFFER', 8);
}
$RandomCompatDIR = dirname(__FILE__);
require_once $RandomCompatDIR . '/byte_safe_strings.php';
require_once $RandomCompatDIR . '/cast_to_int.php';
require_once $RandomCompatDIR . '/error_polyfill.php';
if (!is_callable('random_bytes')) {
/**
* PHP 5.2.0 - 5.6.x way to implement random_bytes()
*
* We use conditional statements here to define the function in accordance
* to the operating environment. It's a micro-optimization.
*
* In order of preference:
* 1. Use libsodium if available.
* 2. fread() /dev/urandom if available (never on Windows)
* 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
* 4. COM('CAPICOM.Utilities.1')->GetRandom()
*
* See RATIONALE.md for our reasoning behind this particular order
*/
if (extension_loaded('libsodium')) {
// See random_bytes_libsodium.php
if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
require_once $RandomCompatDIR . '/random_bytes_libsodium.php';
} elseif (method_exists('Sodium', 'randombytes_buf')) {
require_once $RandomCompatDIR . '/random_bytes_libsodium_legacy.php';
}
}
/**
* Reading directly from /dev/urandom:
*/
if (DIRECTORY_SEPARATOR === '/') {
// DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
// way to exclude Windows.
$RandomCompatUrandom = true;
$RandomCompat_basedir = ini_get('open_basedir');
if (!empty($RandomCompat_basedir)) {
$RandomCompat_open_basedir = explode(
PATH_SEPARATOR,
strtolower($RandomCompat_basedir)
);
$RandomCompatUrandom = (array() !== array_intersect(
array('/dev', '/dev/', '/dev/urandom'),
$RandomCompat_open_basedir
));
$RandomCompat_open_basedir = null;
}
if (
!is_callable('random_bytes')
&&
$RandomCompatUrandom
&&
@is_readable('/dev/urandom')
) {
// Error suppression on is_readable() in case of an open_basedir
// or safe_mode failure. All we care about is whether or not we
// can read it at this point. If the PHP environment is going to
// panic over trying to see if the file can be read in the first
// place, that is not helpful to us here.
// See random_bytes_dev_urandom.php
require_once $RandomCompatDIR . '/random_bytes_dev_urandom.php';
}
// Unset variables after use
$RandomCompat_basedir = null;
} else {
$RandomCompatUrandom = false;
}
/**
* mcrypt_create_iv()
*
* We only want to use mcypt_create_iv() if:
*
* - random_bytes() hasn't already been defined
* - the mcrypt extensions is loaded
* - One of these two conditions is true:
* - We're on Windows (DIRECTORY_SEPARATOR !== '/')
* - We're not on Windows and /dev/urandom is readabale
* (i.e. we're not in a chroot jail)
* - Special case:
* - If we're not on Windows, but the PHP version is between
* 5.6.10 and 5.6.12, we don't want to use mcrypt. It will
* hang indefinitely. This is bad.
* - If we're on Windows, we want to use PHP >= 5.3.7 or else
* we get insufficient entropy errors.
*/
if (
!is_callable('random_bytes')
&&
// Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be.
(DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307)
&&
// Prevent this code from hanging indefinitely on non-Windows;
// see https://bugs.php.net/bug.php?id=69833
(
DIRECTORY_SEPARATOR !== '/' ||
(PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
)
&&
extension_loaded('mcrypt')
) {
// See random_bytes_mcrypt.php
require_once $RandomCompatDIR . '/random_bytes_mcrypt.php';
}
$RandomCompatUrandom = null;
/**
* This is a Windows-specific fallback, for when the mcrypt extension
* isn't loaded.
*/
if (
!is_callable('random_bytes')
&&
extension_loaded('com_dotnet')
&&
class_exists('COM')
) {
$RandomCompat_disabled_classes = preg_split(
'#\s*,\s*#',
strtolower(ini_get('disable_classes'))
);
if (!in_array('com', $RandomCompat_disabled_classes)) {
try {
$RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
// See random_bytes_com_dotnet.php
require_once $RandomCompatDIR . '/random_bytes_com_dotnet.php';
}
} catch (com_exception $e) {
// Don't try to use it.
}
}
$RandomCompat_disabled_classes = null;
$RandomCompatCOMtest = null;
}
/**
* throw new Exception
*/
if (!is_callable('random_bytes')) {
/**
* We don't have any more options, so let's throw an exception right now
* and hope the developer won't let it fail silently.
*
* @param mixed $length
* @return void
* @throws Exception
*/
function random_bytes($length)
{
unset($length); // Suppress "variable not used" warnings.
throw new Exception(
'There is no suitable CSPRNG installed on your system'
);
}
}
}
if (!is_callable('random_int')) {
require_once $RandomCompatDIR . '/random_int.php';
}
$RandomCompatDIR = null;

View File

@@ -0,0 +1,88 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
*
* 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.
*/
if (!is_callable('random_bytes')) {
/**
* Windows with PHP < 5.3.0 will not have the function
* openssl_random_pseudo_bytes() available, so let's use
* CAPICOM to work around this deficiency.
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
try {
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
$buf = '';
if (!class_exists('COM')) {
throw new Error(
'COM does not exist'
);
}
$util = new COM('CAPICOM.Utilities.1');
$execCount = 0;
/**
* Let's not let it loop forever. If we run N times and fail to
* get N bytes of random data, then CAPICOM has failed us.
*/
do {
$buf .= base64_decode($util->GetRandom($bytes, 0));
if (RandomCompat_strlen($buf) >= $bytes) {
/**
* Return our random entropy buffer here:
*/
return RandomCompat_substr($buf, 0, $bytes);
}
++$execCount;
} while ($execCount < $bytes);
/**
* If we reach here, PHP has failed us.
*/
throw new Exception(
'Could not gather sufficient random data'
);
}
}

View File

@@ -0,0 +1,167 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
*
* 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.
*/
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
define('RANDOM_COMPAT_READ_BUFFER', 8);
}
if (!is_callable('random_bytes')) {
/**
* Unless open_basedir is enabled, use /dev/urandom for
* random numbers in accordance with best practices
*
* Why we use /dev/urandom and not /dev/random
* @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
static $fp = null;
/**
* This block should only be run once
*/
if (empty($fp)) {
/**
* We use /dev/urandom if it is a char device.
* We never fall back to /dev/random
*/
$fp = fopen('/dev/urandom', 'rb');
if (!empty($fp)) {
$st = fstat($fp);
if (($st['mode'] & 0170000) !== 020000) {
fclose($fp);
$fp = false;
}
}
if (!empty($fp)) {
/**
* stream_set_read_buffer() does not exist in HHVM
*
* If we don't set the stream's read buffer to 0, PHP will
* internally buffer 8192 bytes, which can waste entropy
*
* stream_set_read_buffer returns 0 on success
*/
if (is_callable('stream_set_read_buffer')) {
stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
}
if (is_callable('stream_set_chunk_size')) {
stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
}
}
}
try {
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
/**
* This if() block only runs if we managed to open a file handle
*
* It does not belong in an else {} block, because the above
* if (empty($fp)) line is logic that should only be run once per
* page load.
*/
if (!empty($fp)) {
/**
* @var int
*/
$remaining = $bytes;
/**
* @var string|bool
*/
$buf = '';
/**
* We use fread() in a loop to protect against partial reads
*/
do {
/**
* @var string|bool
*/
$read = fread($fp, $remaining);
if (!is_string($read)) {
if ($read === false) {
/**
* We cannot safely read from the file. Exit the
* do-while loop and trigger the exception condition
*
* @var string|bool
*/
$buf = false;
break;
}
}
/**
* Decrease the number of bytes returned from remaining
*/
$remaining -= RandomCompat_strlen($read);
/**
* @var string|bool
*/
$buf = $buf . $read;
} while ($remaining > 0);
/**
* Is our result valid?
*/
if (is_string($buf)) {
if (RandomCompat_strlen($buf) === $bytes) {
/**
* Return our random entropy buffer here:
*/
return $buf;
}
}
}
/**
* If we reach here, PHP has failed us.
*/
throw new Exception(
'Error reading from source device'
);
}
}

View File

@@ -0,0 +1,88 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
*
* 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.
*/
if (!is_callable('random_bytes')) {
/**
* If the libsodium PHP extension is loaded, we'll use it above any other
* solution.
*
* libsodium-php project:
* @ref https://github.com/jedisct1/libsodium-php
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
try {
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
/**
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
* generated in one invocation.
*/
if ($bytes > 2147483647) {
$buf = '';
for ($i = 0; $i < $bytes; $i += 1073741824) {
$n = ($bytes - $i) > 1073741824
? 1073741824
: $bytes - $i;
$buf .= \Sodium\randombytes_buf($n);
}
} else {
$buf = \Sodium\randombytes_buf($bytes);
}
if ($buf !== false) {
if (RandomCompat_strlen($buf) === $bytes) {
return $buf;
}
}
/**
* If we reach here, PHP has failed us.
*/
throw new Exception(
'Could not gather sufficient random data'
);
}
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
*
* 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.
*/
if (!is_callable('random_bytes')) {
/**
* If the libsodium PHP extension is loaded, we'll use it above any other
* solution.
*
* libsodium-php project:
* @ref https://github.com/jedisct1/libsodium-php
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
try {
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
/**
* @var string
*/
$buf = '';
/**
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
* generated in one invocation.
*/
if ($bytes > 2147483647) {
for ($i = 0; $i < $bytes; $i += 1073741824) {
$n = ($bytes - $i) > 1073741824
? 1073741824
: $bytes - $i;
$buf .= Sodium::randombytes_buf((int) $n);
}
} else {
$buf .= Sodium::randombytes_buf((int) $bytes);
}
if (is_string($buf)) {
if (RandomCompat_strlen($buf) === $bytes) {
return $buf;
}
}
/**
* If we reach here, PHP has failed us.
*/
throw new Exception(
'Could not gather sufficient random data'
);
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
*
* 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.
*/
if (!is_callable('random_bytes')) {
/**
* Powered by ext/mcrypt (and thankfully NOT libmcrypt)
*
* @ref https://bugs.php.net/bug.php?id=55169
* @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
try {
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
$buf = @mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM);
if (
$buf !== false
&&
RandomCompat_strlen($buf) === $bytes
) {
/**
* Return our random entropy buffer here:
*/
return $buf;
}
/**
* If we reach here, PHP has failed us.
*/
throw new Exception(
'Could not gather sufficient random data'
);
}
}

View File

@@ -0,0 +1,190 @@
<?php
if (!is_callable('random_int')) {
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
*
* 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.
*/
/**
* Fetch a random integer between $min and $max inclusive
*
* @param int $min
* @param int $max
*
* @throws Exception
*
* @return int
*/
function random_int($min, $max)
{
/**
* Type and input logic checks
*
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
* lose precision, so the <= and => operators might accidentally let a float
* through.
*/
try {
$min = RandomCompat_intval($min);
} catch (TypeError $ex) {
throw new TypeError(
'random_int(): $min must be an integer'
);
}
try {
$max = RandomCompat_intval($max);
} catch (TypeError $ex) {
throw new TypeError(
'random_int(): $max must be an integer'
);
}
/**
* Now that we've verified our weak typing system has given us an integer,
* let's validate the logic then we can move forward with generating random
* integers along a given range.
*/
if ($min > $max) {
throw new Error(
'Minimum value must be less than or equal to the maximum value'
);
}
if ($max === $min) {
return (int) $min;
}
/**
* Initialize variables to 0
*
* We want to store:
* $bytes => the number of random bytes we need
* $mask => an integer bitmask (for use with the &) operator
* so we can minimize the number of discards
*/
$attempts = $bits = $bytes = $mask = $valueShift = 0;
/**
* At this point, $range is a positive number greater than 0. It might
* overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to
* a float and we will lose some precision.
*/
$range = $max - $min;
/**
* Test for integer overflow:
*/
if (!is_int($range)) {
/**
* Still safely calculate wider ranges.
* Provided by @CodesInChaos, @oittaa
*
* @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435
*
* We use ~0 as a mask in this case because it generates all 1s
*
* @ref https://eval.in/400356 (32-bit)
* @ref http://3v4l.org/XX9r5 (64-bit)
*/
$bytes = PHP_INT_SIZE;
$mask = ~0;
} else {
/**
* $bits is effectively ceil(log($range, 2)) without dealing with
* type juggling
*/
while ($range > 0) {
if ($bits % 8 === 0) {
++$bytes;
}
++$bits;
$range >>= 1;
$mask = $mask << 1 | 1;
}
$valueShift = $min;
}
$val = 0;
/**
* Now that we have our parameters set up, let's begin generating
* random integers until one falls between $min and $max
*/
do {
/**
* The rejection probability is at most 0.5, so this corresponds
* to a failure probability of 2^-128 for a working RNG
*/
if ($attempts > 128) {
throw new Exception(
'random_int: RNG is broken - too many rejections'
);
}
/**
* Let's grab the necessary number of random bytes
*/
$randomByteString = random_bytes($bytes);
/**
* Let's turn $randomByteString into an integer
*
* This uses bitwise operators (<< and |) to build an integer
* out of the values extracted from ord()
*
* Example: [9F] | [6D] | [32] | [0C] =>
* 159 + 27904 + 3276800 + 201326592 =>
* 204631455
*/
$val &= 0;
for ($i = 0; $i < $bytes; ++$i) {
$val |= ord($randomByteString[$i]) << ($i * 8);
}
/**
* Apply mask
*/
$val &= $mask;
$val += $valueShift;
++$attempts;
/**
* If $val overflows to a floating point number,
* ... or is larger than $max,
* ... or smaller than $min,
* then try again.
*/
} while (!is_int($val) || $val > $max || $val < $min);
return (int) $val;
}
}

View File

@@ -0,0 +1,57 @@
<?php
$dist = dirname(__DIR__).'/dist';
if (!is_dir($dist)) {
mkdir($dist, 0755);
}
if (file_exists($dist.'/random_compat.phar')) {
unlink($dist.'/random_compat.phar');
}
$phar = new Phar(
$dist.'/random_compat.phar',
FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME,
'random_compat.phar'
);
rename(
dirname(__DIR__).'/lib/random.php',
dirname(__DIR__).'/lib/index.php'
);
$phar->buildFromDirectory(dirname(__DIR__).'/lib');
rename(
dirname(__DIR__).'/lib/index.php',
dirname(__DIR__).'/lib/random.php'
);
/**
* If we pass an (optional) path to a private key as a second argument, we will
* sign the Phar with OpenSSL.
*
* If you leave this out, it will produce an unsigned .phar!
*/
if ($argc > 1) {
if (!@is_readable($argv[1])) {
echo 'Could not read the private key file:', $argv[1], "\n";
exit(255);
}
$pkeyFile = file_get_contents($argv[1]);
$private = openssl_get_privatekey($pkeyFile);
if ($private !== false) {
$pkey = '';
openssl_pkey_export($private, $pkey);
$phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey);
/**
* Save the corresponding public key to the file
*/
if (!@is_readable($dist.'/random_compat.phar.pubkey')) {
$details = openssl_pkey_get_details($private);
file_put_contents(
$dist.'/random_compat.phar.pubkey',
$details['key']
);
}
} else {
echo 'An error occurred reading the private key from OpenSSL.', "\n";
exit(255);
}
}

View File

@@ -0,0 +1,9 @@
<?php
require_once 'lib/byte_safe_strings.php';
require_once 'lib/cast_to_int.php';
require_once 'lib/error_polyfill.php';
require_once 'other/ide_stubs/libsodium.php';
require_once 'lib/random.php';
$int = random_int(0, 65536);

View File

@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<psalm
autoloader="psalm-autoload.php"
stopOnFirstError="false"
useDocblockTypes="true"
>
<projectFiles>
<directory name="lib" />
</projectFiles>
<issueHandlers>
<DuplicateClass errorLevel="info" />
<InvalidOperand errorLevel="info" />
<UndefinedConstant errorLevel="info" />
<MissingReturnType errorLevel="info" />
</issueHandlers>
</psalm>

View File

@@ -1 +1,3 @@
phpunit.xml
composer.lock
/vendor/

View File

@@ -0,0 +1,40 @@
language: php
env:
matrix:
- PIMPLE_EXT=no
- PIMPLE_EXT=yes
global:
- REPORT_EXIT_STATUS=1
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- 7.1
before_script:
- composer self-update
- COMPOSER_ROOT_VERSION=dev-master composer install
- if [ "$PIMPLE_EXT" == "yes" ]; then sh -c "cd ext/pimple && phpize && ./configure && make && sudo make install"; fi
- if [ "$PIMPLE_EXT" == "yes" ]; then echo "extension=pimple.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi
script:
- cd ext/pimple
- if [ "$PIMPLE_EXT" == "yes" ]; then yes n | make test | tee output ; grep -E 'Tests failed +. +0' output; fi
- if [ "$PIMPLE_EXT" == "yes" ]; then export SYMFONY_DEPRECATIONS_HELPER=weak; fi
- cd ../..
- ./vendor/bin/simple-phpunit
matrix:
include:
- php: hhvm
dist: trusty
env: PIMPLE_EXT=no
exclude:
- php: 7.0
env: PIMPLE_EXT=yes
- php: 7.1
env: PIMPLE_EXT=yes

View File

@@ -0,0 +1,59 @@
* 3.2.3 (2017-XX-XX)
* n/a
* 3.2.2 (2017-07-23)
* reverted extending a protected closure throws an exception (deprecated it instead)
* 3.2.1 (2017-07-17)
* fixed PHP error
* 3.2.0 (2017-07-17)
* added a PSR-11 service locator
* added a PSR-11 wrapper
* added ServiceIterator
* fixed extending a protected closure (now throws InvalidServiceIdentifierException)
* 3.1.0 (2017-07-03)
* deprecated the C extension
* added support for PSR-11 exceptions
* 3.0.2 (2015-09-11)
* refactored the C extension
* minor non-significant changes
* 3.0.1 (2015-07-30)
* simplified some code
* fixed a segfault in the C extension
* 3.0.0 (2014-07-24)
* removed the Pimple class alias (use Pimple\Container instead)
* 2.1.1 (2014-07-24)
* fixed compiler warnings for the C extension
* fixed code when dealing with circular references
* 2.1.0 (2014-06-24)
* moved the Pimple to Pimple\Container (with a BC layer -- Pimple is now a
deprecated alias which will be removed in Pimple 3.0)
* added Pimple\ServiceProviderInterface (and Pimple::register())
* 2.0.0 (2014-02-10)
* changed extend to automatically re-assign the extended service and keep it as shared or factory
(to keep BC, extend still returns the extended service)
* changed services to be shared by default (use factory() for factory
services)
* 1.0.0
* initial version

View File

@@ -1,4 +1,4 @@
Copyright (c) 2009-2013 Fabien Potencier
Copyright (c) 2009-2017 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,42 +1,53 @@
Pimple
======
Pimple is a small Dependency Injection Container for PHP 5.3 that consists
of just one file and one class (about 80 lines of code).
.. caution::
`Download it`_, require it in your code, and you're good to go::
This is the documentation for Pimple 3.x. If you are using Pimple 1.x, read
the `Pimple 1.x documentation`_. Reading the Pimple 1.x code is also a good
way to learn more about how to create a simple Dependency Injection
Container (recent versions of Pimple are more focused on performance).
require_once '/path/to/Pimple.php';
Pimple is a small Dependency Injection Container for PHP.
Creating a container is a matter of instating the ``Pimple`` class::
Installation
------------
$container = new Pimple();
Before using Pimple in your project, add it to your ``composer.json`` file:
As many other dependency injection containers, Pimple is able to manage two
different kind of data: *services* and *parameters*.
.. code-block:: bash
Defining Parameters
-------------------
$ ./composer.phar require pimple/pimple "^3.0"
Defining a parameter is as simple as using the Pimple instance as an array::
Usage
-----
// define some parameters
$container['cookie_name'] = 'SESSION_ID';
$container['session_storage_class'] = 'SessionStorage';
Creating a container is a matter of creating a ``Container`` instance:
.. code-block:: php
use Pimple\Container;
$container = new Container();
As many other dependency injection containers, Pimple manages two different
kind of data: **services** and **parameters**.
Defining Services
-----------------
~~~~~~~~~~~~~~~~~
A service is an object that does something as part of a larger system.
Examples of services: Database connection, templating engine, mailer. Almost
any object could be a service.
A service is an object that does something as part of a larger system. Examples
of services: a database connection, a templating engine, or a mailer. Almost
any **global** object can be a service.
Services are defined by anonymous functions that return an instance of an
object::
Services are defined by **anonymous functions** that return an instance of an
object:
.. code-block:: php
// define some services
$container['session_storage'] = function ($c) {
return new $c['session_storage_class']($c['cookie_name']);
return new SessionStorage('SESSION_ID');
};
$container['session'] = function ($c) {
@@ -47,9 +58,11 @@ Notice that the anonymous function has access to the current container
instance, allowing references to other services or parameters.
As objects are only created when you get them, the order of the definitions
does not matter, and there is no performance penalty.
does not matter.
Using the defined services is also very easy::
Using the defined services is also very easy:
.. code-block:: php
// get the session object
$session = $container['session'];
@@ -58,102 +71,256 @@ Using the defined services is also very easy::
// $storage = new SessionStorage('SESSION_ID');
// $session = new Session($storage);
Defining Shared Services
------------------------
Defining Factory Services
~~~~~~~~~~~~~~~~~~~~~~~~~
By default, each time you get a service, Pimple returns a new instance of it.
If you want the same instance to be returned for all calls, wrap your
anonymous function with the ``share()`` method::
By default, each time you get a service, Pimple returns the **same instance**
of it. If you want a different instance to be returned for all calls, wrap your
anonymous function with the ``factory()`` method
$container['session'] = $container->share(function ($c) {
.. code-block:: php
$container['session'] = $container->factory(function ($c) {
return new Session($c['session_storage']);
});
Now, each call to ``$container['session']`` returns a new instance of the
session.
Defining Parameters
~~~~~~~~~~~~~~~~~~~
Defining a parameter allows to ease the configuration of your container from
the outside and to store global values:
.. code-block:: php
// define some parameters
$container['cookie_name'] = 'SESSION_ID';
$container['session_storage_class'] = 'SessionStorage';
If you change the ``session_storage`` service definition like below:
.. code-block:: php
$container['session_storage'] = function ($c) {
return new $c['session_storage_class']($c['cookie_name']);
};
You can now easily change the cookie name by overriding the
``cookie_name`` parameter instead of redefining the service
definition.
Protecting Parameters
---------------------
~~~~~~~~~~~~~~~~~~~~~
Because Pimple sees anonymous functions as service definitions, you need to
wrap anonymous functions with the ``protect()`` method to store them as
parameter::
parameters:
$container['random'] = $container->protect(function () { return rand(); });
.. code-block:: php
Modifying services after creation
---------------------------------
$container['random_func'] = $container->protect(function () {
return rand();
});
Modifying Services after Definition
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In some cases you may want to modify a service definition after it has been
defined. You can use the ``extend()`` method to define additional code to
be run on your service just after it is created::
defined. You can use the ``extend()`` method to define additional code to be
run on your service just after it is created:
$container['mail'] = function ($c) {
return new \Zend_Mail();
.. code-block:: php
$container['session_storage'] = function ($c) {
return new $c['session_storage_class']($c['cookie_name']);
};
$container['mail'] = $container->extend('mail', function($mail, $c) {
$mail->setFrom($c['mail.default_from']);
return $mail;
$container->extend('session_storage', function ($storage, $c) {
$storage->...();
return $storage;
});
The first argument is the name of the object, the second is a function that
gets access to the object instance and the container. The return value is
a service definition, so you need to re-assign it on the container.
The first argument is the name of the service to extend, the second a function
that gets access to the object instance and the container.
If the service you plan to extend is already shared, it's recommended that you
re-wrap your extended service with the ``shared`` method, otherwise your extension
code will be called every time you access the service::
Extending a Container
~~~~~~~~~~~~~~~~~~~~~
$container['twig'] = $container->share(function ($c) {
return new Twig_Environment($c['twig.loader'], $c['twig.options']);
});
If you use the same libraries over and over, you might want to reuse some
services from one project to the next one; package your services into a
**provider** by implementing ``Pimple\ServiceProviderInterface``:
$container['twig'] = $container->share($container->extend('twig', function ($twig, $c) {
$twig->addExtension(new MyTwigExtension());
return $twig;
}));
.. code-block:: php
Fetching the service creation function
--------------------------------------
use Pimple\Container;
When you access an object, Pimple automatically calls the anonymous function
that you defined, which creates the service object for you. If you want to get
raw access to this function, you can use the ``raw()`` method::
$container['session'] = $container->share(function ($c) {
return new Session($c['session_storage']);
});
$sessionFunction = $container->raw('session');
Packaging a Container for reusability
-------------------------------------
If you use the same libraries over and over, you might want to create reusable
containers. Creating a reusable container is as simple as creating a class
that extends ``Pimple``, and configuring it in the constructor::
class SomeContainer extends Pimple
class FooProvider implements Pimple\ServiceProviderInterface
{
public function __construct()
public function register(Container $pimple)
{
$this['parameter'] = 'foo';
$this['object'] = function () { return stdClass(); };
// register some services and parameters
// on $pimple
}
}
Using this container from your own is as easy as it can get::
Then, register the provider on a Container:
$container = new Pimple();
.. code-block:: php
// define your project parameters and services
// ...
$pimple->register(new FooProvider());
// embed the SomeContainer container
$container['embedded'] = $container->share(function () { return new SomeContainer(); });
Fetching the Service Creation Function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// configure it
$container['embedded']['parameter'] = 'bar';
When you access an object, Pimple automatically calls the anonymous function
that you defined, which creates the service object for you. If you want to get
raw access to this function, you can use the ``raw()`` method:
// use it
$container['embedded']['object']->...;
.. code-block:: php
.. _Download it: https://github.com/fabpot/Pimple
$container['session'] = function ($c) {
return new Session($c['session_storage']);
};
$sessionFunction = $container->raw('session');
PSR-11 compatibility
--------------------
For historical reasons, the ``Container`` class does not implement the PSR-11
``ContainerInterface``. However, Pimple provides a helper class that will let
you decouple your code from the Pimple container class.
The PSR-11 container class
~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``Pimple\Psr11\Container`` class lets you access the content of an
underlying Pimple container using ``Psr\Container\ContainerInterface``
methods:
.. code-block:: php
use Pimple\Container;
use Pimple\Psr11\Container as PsrContainer;
$container = new Container();
$container['service'] = function ($c) {
return new Service();
};
$psr11 = new PsrContainer($container);
$controller = function (PsrContainer $container) {
$service = $container->get('service');
};
$controller($psr11);
Using the PSR-11 ServiceLocator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sometimes, a service needs access to several other services without being sure
that all of them will actually be used. In those cases, you may want the
instantiation of the services to be lazy.
The traditional solution is to inject the entire service container to get only
the services really needed. However, this is not recommended because it gives
services a too broad access to the rest of the application and it hides their
actual dependencies.
The ``ServiceLocator`` is intended to solve this problem by giving access to a
set of predefined services while instantiating them only when actually needed.
It also allows you to make your services available under a different name than
the one used to register them. For instance, you may want to use an object
that expects an instance of ``EventDispatcherInterface`` to be available under
the name ``event_dispatcher`` while your event dispatcher has been
registered under the name ``dispatcher``:
.. code-block:: php
use Monolog\Logger;
use Pimple\Psr11\ServiceLocator;
use Psr\Container\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
class MyService
{
/**
* "logger" must be an instance of Psr\Log\LoggerInterface
* "event_dispatcher" must be an instance of Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
private $services;
public function __construct(ContainerInterface $services)
{
$this->services = $services;
}
}
$container['logger'] = function ($c) {
return new Monolog\Logger();
};
$container['dispatcher'] = function () {
return new EventDispatcher();
};
$container['service'] = function ($c) {
$locator = new ServiceLocator($c, array('logger', 'event_dispatcher' => 'dispatcher'));
return new MyService($locator);
};
Referencing a Collection of Services Lazily
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passing a collection of services instances in an array may prove inefficient
if the class that consumes the collection only needs to iterate over it at a
later stage, when one of its method is called. It can also lead to problems
if there is a circular dependency between one of the services stored in the
collection and the class that consumes it.
The ``ServiceIterator`` class helps you solve these issues. It receives a
list of service names during instantiation and will retrieve the services
when iterated over:
.. code-block:: php
use Pimple\Container;
use Pimple\ServiceIterator;
class AuthorizationService
{
private $voters;
public function __construct($voters)
{
$this->voters = $voters;
}
public function canAccess($resource)
{
foreach ($this->voters as $voter) {
if (true === $voter->canAccess($resource) {
return true;
}
}
return false;
}
}
$container = new Container();
$container['voter1'] = function ($c) {
return new SomeVoter();
}
$container['voter2'] = function ($c) {
return new SomeOtherVoter($c['auth']);
}
$container['auth'] = function ($c) {
return new AuthorizationService(new ServiceIterator($c, array('voter1', 'voter2'));
}
.. _Pimple 1.x documentation: https://github.com/silexphp/Pimple/tree/1.1

View File

@@ -1,7 +1,7 @@
{
"name": "pimple/pimple",
"type": "library",
"description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
"description": "Pimple, a simple Dependency Injection Container",
"keywords": ["dependency injection", "container"],
"homepage": "http://pimple.sensiolabs.org",
"license": "MIT",
@@ -12,14 +12,18 @@
}
],
"require": {
"php": ">=5.3.0"
"php": ">=5.3.0",
"psr/container": "^1.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^3.2"
},
"autoload": {
"psr-0": { "Pimple": "lib/" }
"psr-0": { "Pimple": "src/" }
},
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
"dev-master": "3.2.x-dev"
}
}
}
}

View File

@@ -0,0 +1,30 @@
*.sw*
.deps
Makefile
Makefile.fragments
Makefile.global
Makefile.objects
acinclude.m4
aclocal.m4
build/
config.cache
config.guess
config.h
config.h.in
config.log
config.nice
config.status
config.sub
configure
configure.in
install-sh
libtool
ltmain.sh
missing
mkinstalldirs
run-tests.php
*.loT
.libs/
modules/
*.la
*.lo

View File

@@ -0,0 +1,12 @@
This is Pimple 2 implemented in C
* PHP >= 5.3
* Not tested under Windows, might work
Install
=======
> phpize
> ./configure
> make
> make install

View File

@@ -0,0 +1,63 @@
dnl $Id$
dnl config.m4 for extension pimple
dnl Comments in this file start with the string 'dnl'.
dnl Remove where necessary. This file will not work
dnl without editing.
dnl If your extension references something external, use with:
dnl PHP_ARG_WITH(pimple, for pimple support,
dnl Make sure that the comment is aligned:
dnl [ --with-pimple Include pimple support])
dnl Otherwise use enable:
PHP_ARG_ENABLE(pimple, whether to enable pimple support,
dnl Make sure that the comment is aligned:
[ --enable-pimple Enable pimple support])
if test "$PHP_PIMPLE" != "no"; then
dnl Write more examples of tests here...
dnl # --with-pimple -> check with-path
dnl SEARCH_PATH="/usr/local /usr" # you might want to change this
dnl SEARCH_FOR="/include/pimple.h" # you most likely want to change this
dnl if test -r $PHP_PIMPLE/$SEARCH_FOR; then # path given as parameter
dnl PIMPLE_DIR=$PHP_PIMPLE
dnl else # search default path list
dnl AC_MSG_CHECKING([for pimple files in default path])
dnl for i in $SEARCH_PATH ; do
dnl if test -r $i/$SEARCH_FOR; then
dnl PIMPLE_DIR=$i
dnl AC_MSG_RESULT(found in $i)
dnl fi
dnl done
dnl fi
dnl
dnl if test -z "$PIMPLE_DIR"; then
dnl AC_MSG_RESULT([not found])
dnl AC_MSG_ERROR([Please reinstall the pimple distribution])
dnl fi
dnl # --with-pimple -> add include path
dnl PHP_ADD_INCLUDE($PIMPLE_DIR/include)
dnl # --with-pimple -> check for lib and symbol presence
dnl LIBNAME=pimple # you may want to change this
dnl LIBSYMBOL=pimple # you most likely want to change this
dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
dnl [
dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $PIMPLE_DIR/lib, PIMPLE_SHARED_LIBADD)
dnl AC_DEFINE(HAVE_PIMPLELIB,1,[ ])
dnl ],[
dnl AC_MSG_ERROR([wrong pimple lib version or lib not found])
dnl ],[
dnl -L$PIMPLE_DIR/lib -lm
dnl ])
dnl
dnl PHP_SUBST(PIMPLE_SHARED_LIBADD)
PHP_NEW_EXTENSION(pimple, pimple.c, $ext_shared)
fi

View File

@@ -0,0 +1,13 @@
// $Id$
// vim:ft=javascript
// If your extension references something external, use ARG_WITH
// ARG_WITH("pimple", "for pimple support", "no");
// Otherwise, use ARG_ENABLE
// ARG_ENABLE("pimple", "enable pimple support", "no");
if (PHP_PIMPLE != "no") {
EXTENSION("pimple", "pimple.c");
}

View File

@@ -0,0 +1,137 @@
/*
* This file is part of Pimple.
*
* Copyright (c) 2014 Fabien Potencier
*
* 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.
*/
#ifndef PHP_PIMPLE_H
#define PHP_PIMPLE_H
extern zend_module_entry pimple_module_entry;
#define phpext_pimple_ptr &pimple_module_entry
#ifdef PHP_WIN32
# define PHP_PIMPLE_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
# define PHP_PIMPLE_API __attribute__ ((visibility("default")))
#else
# define PHP_PIMPLE_API
#endif
#ifdef ZTS
#include "TSRM.h"
#endif
#define PIMPLE_VERSION "3.2.3-DEV"
#define PIMPLE_NS "Pimple"
#define PSR_CONTAINER_NS "Psr\\Container"
#define PIMPLE_EXCEPTION_NS "Pimple\\Exception"
#define PIMPLE_DEFAULT_ZVAL_CACHE_NUM 5
#define PIMPLE_DEFAULT_ZVAL_VALUES_NUM 10
#define PIMPLE_DEPRECATE do { \
int er = EG(error_reporting); \
EG(error_reporting) = 0;\
php_error(E_DEPRECATED, "The Pimple C extension is deprecated since version 3.1 and will be removed in 4.0."); \
EG(error_reporting) = er; \
} while (0);
zend_module_entry *get_module(void);
PHP_MINIT_FUNCTION(pimple);
PHP_MINFO_FUNCTION(pimple);
PHP_METHOD(FrozenServiceException, __construct);
PHP_METHOD(InvalidServiceIdentifierException, __construct);
PHP_METHOD(UnknownIdentifierException, __construct);
PHP_METHOD(Pimple, __construct);
PHP_METHOD(Pimple, factory);
PHP_METHOD(Pimple, protect);
PHP_METHOD(Pimple, raw);
PHP_METHOD(Pimple, extend);
PHP_METHOD(Pimple, keys);
PHP_METHOD(Pimple, register);
PHP_METHOD(Pimple, offsetSet);
PHP_METHOD(Pimple, offsetUnset);
PHP_METHOD(Pimple, offsetGet);
PHP_METHOD(Pimple, offsetExists);
PHP_METHOD(PimpleClosure, invoker);
typedef struct _pimple_bucket_value {
zval *value; /* Must be the first element */
zval *raw;
zend_object_handle handle_num;
enum {
PIMPLE_IS_PARAM = 0,
PIMPLE_IS_SERVICE = 2
} type;
zend_bool initialized;
zend_fcall_info_cache fcc;
} pimple_bucket_value;
typedef struct _pimple_object {
zend_object zobj;
HashTable values;
HashTable factories;
HashTable protected;
} pimple_object;
typedef struct _pimple_closure_object {
zend_object zobj;
zval *callable;
zval *factory;
} pimple_closure_object;
static const char sensiolabs_logo[] = "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHYAAAAUCAMAAABvRTlyAAAAz1BMVEUAAAAAAAAAAAAsThWB5j4AAACD6T8AAACC6D+C6D6C6D+C6D4AAAAAAACC6D4AAAAAAACC6D8AAAAAAAAAAAAAAAAAAAAAAACC6D4AAAAAAAAAAACC6D4AAAAAAAAAAAAAAAAAAAAAAACC6D8AAACC6D4AAAAAAAAAAAAAAAAAAACC6D8AAACC6D6C6D+B6D+C6D+C6D+C6D8AAACC6D6C6D4AAACC6D/K/2KC6D+B6D6C6D6C6D+C6D8sTxUyWRhEeiEAAACC6D+C5z6B6D7drnEVAAAAQXRSTlMAE3oCNSUuDHFHzxaF9UFsu+irX+zlKzYimaJXktyOSFD6BolxqT7QGMMdarMIpuO28r9EolXKgR16OphfXYd4V14GtB4AAAMpSURBVEjHvVSJctowEF1jjME2RziMwUCoMfd9heZqG4n//6buLpJjkmYm03byZmxJa2nf6u2uQcG2bfhqRN4LoTKBzyGDm68M7mAwcOEdjo4zhA/Rf9Go/CVtTgiRhXfIC3EDH8F/eUX1/9KexRo+QgOdtHDsEe/sM7QT32/+K61Z1LFXcXJxN4pTbu1aTQUzuy2PIA0rDo0/0Aa5XFaJvKaVTrubywXvaa1Wq4Vu/Snr3Y7Aojh4VccwykW2N2oQ8wmjyut6+Q1t5ywIG5Npj1sh5E0B7YOzFDjfuRfaOh3O+MbbVNfTWS9COZk3Obd2su5d0a6IU9KLREbw8gEehWSr1r2sPWciXLG38r5NdW0xu9eioU87omjC9yNaMi5GNf6WppVSOqXCFkmCvMB3p9SROLoYQn5pDgQOujA1xjYvqH+plUdkwnmII8VxR/PKYkrfLLomhVlE3b/LhNbNr7hp0H2JaOc4v8dFB58HSsFTSafaqtY1sT3GO8wsy5rhokYPlRJdjPMajyYqTt1EHF/2uqSWQWmAjCUSmQ1MS3g8Btf1XOsy7YIC0CB1b5Xw1Vhba0zbxiCAQLH9TNPmHJXQUtJAN0KcDsoqLxsNvJrJExa7mKIdp2lRE2WexiS4pqWk/0jROlw6K6bV9YOBDGAuqMJ0bnuUKGB0L27bxgRhGEbzihbhxxXaQC88Vkwq8ldCi86RApWUb0Q+4VDosBCc+1s81lUdnBavH4Zp2mm3O44USwOfvSo9oBiwpFg71lMS1VKJLKljS3j9p+fOTvXXlsSNuEv6YPaZda9uRope0VJfKdo7fPiYfSmvFjXQbkhY0d9hCbBWIktRgEDieDhf1N3wbbkmNNgRy8hyl620yGQat/grV3HMpc2HDKTVmOPFz6ylPCKt/nXcAyV260jaAowwIW0YuBzrOgb/KrddZS9OmJaLgpWK4JX2DDuklcLZSDGcn8Vmx9YDNvT6UsjyBApRyFQVX7Vxm9TGxE16nmfRd8/zQoDmggQOTRh5Hv8pMt9Q/L2JmSwkMCE7dA4BuDjHJwfu0Om4QAhOjrN5XkIatglfiN/bUPdCQFjTYgAAAABJRU5ErkJggg==\">";
static void pimple_exception_call_parent_constructor(zval *this_ptr, const char *format, const char *arg1 TSRMLS_DC);
static int pimple_zval_to_pimpleval(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC);
static int pimple_zval_is_valid_callback(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC);
static void pimple_bucket_dtor(pimple_bucket_value *bucket);
static void pimple_free_bucket(pimple_bucket_value *bucket);
static zval *pimple_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC);
static void pimple_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC);
static int pimple_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC);
static void pimple_object_unset_dimension(zval *object, zval *offset TSRMLS_DC);
static zend_object_value pimple_object_create(zend_class_entry *ce TSRMLS_DC);
static void pimple_free_object_storage(pimple_object *obj TSRMLS_DC);
static void pimple_closure_free_object_storage(pimple_closure_object *obj TSRMLS_DC);
static zend_object_value pimple_closure_object_create(zend_class_entry *ce TSRMLS_DC);
static zend_function *pimple_closure_get_constructor(zval * TSRMLS_DC);
static int pimple_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC);
#ifdef ZTS
#define PIMPLE_G(v) TSRMG(pimple_globals_id, zend_pimple_globals *, v)
#else
#define PIMPLE_G(v) (pimple_globals.v)
#endif
#endif /* PHP_PIMPLE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,81 @@
/*
* This file is part of Pimple.
*
* Copyright (c) 2014 Fabien Potencier
*
* 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.
*/
#ifndef PIMPLE_COMPAT_H_
#define PIMPLE_COMPAT_H_
#include "Zend/zend_extensions.h" /* for ZEND_EXTENSION_API_NO */
#define PHP_5_0_X_API_NO 220040412
#define PHP_5_1_X_API_NO 220051025
#define PHP_5_2_X_API_NO 220060519
#define PHP_5_3_X_API_NO 220090626
#define PHP_5_4_X_API_NO 220100525
#define PHP_5_5_X_API_NO 220121212
#define PHP_5_6_X_API_NO 220131226
#define IS_PHP_56 ZEND_EXTENSION_API_NO == PHP_5_6_X_API_NO
#define IS_AT_LEAST_PHP_56 ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO
#define IS_PHP_55 ZEND_EXTENSION_API_NO == PHP_5_5_X_API_NO
#define IS_AT_LEAST_PHP_55 ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
#define IS_PHP_54 ZEND_EXTENSION_API_NO == PHP_5_4_X_API_NO
#define IS_AT_LEAST_PHP_54 ZEND_EXTENSION_API_NO >= PHP_5_4_X_API_NO
#define IS_PHP_53 ZEND_EXTENSION_API_NO == PHP_5_3_X_API_NO
#define IS_AT_LEAST_PHP_53 ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
#if IS_PHP_53
#define object_properties_init(obj, ce) do { \
zend_hash_copy(obj->properties, &ce->default_properties, zval_copy_property_ctor(ce), NULL, sizeof(zval *)); \
} while (0);
#endif
#define ZEND_OBJ_INIT(obj, ce) do { \
zend_object_std_init(obj, ce TSRMLS_CC); \
object_properties_init((obj), (ce)); \
} while(0);
#if IS_PHP_53 || IS_PHP_54
static void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos) {
Bucket *p;
p = pos ? (*pos) : ht->pInternalPointer;
if (!p) {
Z_TYPE_P(key) = IS_NULL;
} else if (p->nKeyLength) {
Z_TYPE_P(key) = IS_STRING;
Z_STRVAL_P(key) = estrndup(p->arKey, p->nKeyLength - 1);
Z_STRLEN_P(key) = p->nKeyLength - 1;
} else {
Z_TYPE_P(key) = IS_LONG;
Z_LVAL_P(key) = p->h;
}
}
#endif
#endif /* PIMPLE_COMPAT_H_ */

View File

@@ -0,0 +1,45 @@
--TEST--
Test for read_dim/write_dim handlers
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$p[42] = 'foo';
$p['foo'] = 42;
echo $p[42];
echo "\n";
echo $p['foo'];
echo "\n";
try {
var_dump($p['nonexistant']);
echo "Exception excpected";
} catch (InvalidArgumentException $e) { }
$p[54.2] = 'foo2';
echo $p[54];
echo "\n";
$p[242.99] = 'foo99';
echo $p[242];
echo "\n";
$p[5] = 'bar';
$p[5] = 'baz';
echo $p[5];
echo "\n";
$p['str'] = 'str';
$p['str'] = 'strstr';
echo $p['str'];
?>
--EXPECTF--
foo
42
foo2
foo99
baz
strstr

View File

@@ -0,0 +1,15 @@
--TEST--
Test for constructor
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
var_dump($p[42]);
$p = new Pimple\Container(array(42=>'foo'));
var_dump($p[42]);
?>
--EXPECT--
NULL
string(3) "foo"

View File

@@ -0,0 +1,16 @@
--TEST--
Test empty dimensions
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$p[] = 42;
var_dump($p[0]);
$p[41] = 'foo';
$p[] = 'bar';
var_dump($p[42]);
?>
--EXPECT--
int(42)
string(3) "bar"

View File

@@ -0,0 +1,30 @@
--TEST--
Test has/unset dim handlers
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$p[] = 42;
var_dump($p[0]);
unset($p[0]);
var_dump($p[0]);
$p['foo'] = 'bar';
var_dump(isset($p['foo']));
unset($p['foo']);
try {
var_dump($p['foo']);
echo "Excpected exception";
} catch (InvalidArgumentException $e) { }
var_dump(isset($p['bar']));
$p['bar'] = NULL;
var_dump(isset($p['bar']));
var_dump(empty($p['bar']));
?>
--EXPECT--
int(42)
NULL
bool(true)
bool(false)
bool(true)
bool(true)

View File

@@ -0,0 +1,27 @@
--TEST--
Test simple class inheritance
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
class MyPimple extends Pimple\Container
{
public $someAttr = 'fooAttr';
public function offsetget($o)
{
var_dump("hit");
return parent::offsetget($o);
}
}
$p = new MyPimple;
$p[42] = 'foo';
echo $p[42];
echo "\n";
echo $p->someAttr;
?>
--EXPECT--
string(3) "hit"
foo
fooAttr

View File

@@ -0,0 +1,51 @@
--TEST--
Test complex class inheritance
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
class MyPimple extends Pimple\Container
{
public function offsetget($o)
{
var_dump("hit offsetget in " . __CLASS__);
return parent::offsetget($o);
}
}
class TestPimple extends MyPimple
{
public function __construct($values)
{
array_shift($values);
parent::__construct($values);
}
public function offsetget($o)
{
var_dump('hit offsetget in ' . __CLASS__);
return parent::offsetget($o);
}
public function offsetset($o, $v)
{
var_dump('hit offsetset');
return parent::offsetset($o, $v);
}
}
$defaultValues = array('foo' => 'bar', 88 => 'baz');
$p = new TestPimple($defaultValues);
$p[42] = 'foo';
var_dump($p[42]);
var_dump($p[0]);
?>
--EXPECT--
string(13) "hit offsetset"
string(27) "hit offsetget in TestPimple"
string(25) "hit offsetget in MyPimple"
string(3) "foo"
string(27) "hit offsetget in TestPimple"
string(25) "hit offsetget in MyPimple"
string(3) "baz"

View File

@@ -0,0 +1,22 @@
--TEST--
Test for read_dim/write_dim handlers
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$p[42] = 'foo';
$p['foo'] = 42;
echo $p[42];
echo "\n";
echo $p['foo'];
echo "\n";
try {
var_dump($p['nonexistant']);
echo "Exception excpected";
} catch (InvalidArgumentException $e) { }
?>
--EXPECTF--
foo
42

View File

@@ -0,0 +1,29 @@
--TEST--
Test frozen services
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$p[42] = 'foo';
$p[42] = 'bar';
$p['foo'] = function () { };
$p['foo'] = function () { };
$a = $p['foo'];
try {
$p['foo'] = function () { };
echo "Exception excpected";
} catch (RuntimeException $e) { }
$p[42] = function() { };
$a = $p[42];
try {
$p[42] = function () { };
echo "Exception excpected";
} catch (RuntimeException $e) { }
?>
--EXPECTF--

View File

@@ -0,0 +1,13 @@
--TEST--
Test service is called as callback, and only once
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$p['foo'] = function($arg) use ($p) { var_dump($p === $arg); };
$a = $p['foo'];
$b = $p['foo']; /* should return not calling the callback */
?>
--EXPECTF--
bool(true)

View File

@@ -0,0 +1,45 @@
--TEST--
Test service is called as callback for every callback type
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
function callme()
{
return 'called';
}
$a = function() { return 'called'; };
class Foo
{
public static function bar()
{
return 'called';
}
}
$p = new Pimple\Container();
$p['foo'] = 'callme';
echo $p['foo'] . "\n";
$p['bar'] = $a;
echo $p['bar'] . "\n";
$p['baz'] = "Foo::bar";
echo $p['baz'] . "\n";
$p['foobar'] = array('Foo', 'bar');
var_dump($p['foobar']);
?>
--EXPECTF--
callme
called
Foo::bar
array(2) {
[0]=>
string(3) "Foo"
[1]=>
string(3) "bar"
}

View File

@@ -0,0 +1,19 @@
--TEST--
Test service callback throwing an exception
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
class CallBackException extends RuntimeException { }
$p = new Pimple\Container();
$p['foo'] = function () { throw new CallBackException; };
try {
echo $p['foo'] . "\n";
echo "should not come here";
} catch (CallBackException $e) {
echo "all right!";
}
?>
--EXPECTF--
all right!

View File

@@ -0,0 +1,28 @@
--TEST--
Test service factory
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$p->factory($f = function() { var_dump('called-1'); return 'ret-1';});
$p[] = $f;
$p[] = function () { var_dump('called-2'); return 'ret-2'; };
var_dump($p[0]);
var_dump($p[0]);
var_dump($p[1]);
var_dump($p[1]);
?>
--EXPECTF--
string(8) "called-1"
string(5) "ret-1"
string(8) "called-1"
string(5) "ret-1"
string(8) "called-2"
string(5) "ret-2"
string(5) "ret-2"

View File

@@ -0,0 +1,33 @@
--TEST--
Test keys()
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
var_dump($p->keys());
$p['foo'] = 'bar';
$p[] = 'foo';
var_dump($p->keys());
unset($p['foo']);
var_dump($p->keys());
?>
--EXPECTF--
array(0) {
}
array(2) {
[0]=>
string(3) "foo"
[1]=>
int(0)
}
array(1) {
[0]=>
int(0)
}

View File

@@ -0,0 +1,30 @@
--TEST--
Test raw()
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$f = function () { var_dump('called-2'); return 'ret-2'; };
$p['foo'] = $f;
$p[42] = $f;
var_dump($p['foo']);
var_dump($p->raw('foo'));
var_dump($p[42]);
unset($p['foo']);
try {
$p->raw('foo');
echo "expected exception";
} catch (InvalidArgumentException $e) { }
--EXPECTF--
string(8) "called-2"
string(5) "ret-2"
object(Closure)#%i (0) {
}
string(8) "called-2"
string(5) "ret-2"

View File

@@ -0,0 +1,17 @@
--TEST--
Test protect()
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$f = function () { return 'foo'; };
$p['foo'] = $f;
$p->protect($f);
var_dump($p['foo']);
--EXPECTF--
object(Closure)#%i (0) {
}

View File

@@ -0,0 +1,24 @@
--TEST--
Test extend()
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
/*
This is part of Pimple::extend() code :
$extended = function ($c) use ($callable, $factory) {
return $callable($factory($c), $c);
};
*/
$p = new Pimple\Container();
$p[12] = function ($v) { var_dump($v); return 'foo';}; /* $factory in code above */
$c = $p->extend(12, function ($w) { var_dump($w); return 'bar'; }); /* $callable in code above */
var_dump($c('param'));
--EXPECTF--
string(5) "param"
string(3) "foo"
string(3) "bar"

View File

@@ -0,0 +1,17 @@
--TEST--
Test extend() with exception in service extension
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$p[12] = function ($v) { return 'foo';};
$c = $p->extend(12, function ($w) { throw new BadMethodCallException; });
try {
$p[12];
echo "Exception expected";
} catch (BadMethodCallException $e) { }
--EXPECTF--

View File

@@ -0,0 +1,17 @@
--TEST--
Test extend() with exception in service factory
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
$p = new Pimple\Container();
$p[12] = function ($v) { throw new BadMethodCallException; };
$c = $p->extend(12, function ($w) { return 'foobar'; });
try {
$p[12];
echo "Exception expected";
} catch (BadMethodCallException $e) { }
--EXPECTF--

View File

@@ -0,0 +1,23 @@
--TEST--
Test register()
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
class Foo implements Pimple\ServiceProviderInterface
{
public function register(Pimple\Container $p)
{
var_dump($p);
}
}
$p = new Pimple\Container();
$p->register(new Foo, array(42 => 'bar'));
var_dump($p[42]);
--EXPECTF--
object(Pimple\Container)#1 (0) {
}
string(3) "bar"

View File

@@ -0,0 +1,18 @@
--TEST--
Test register() returns static and is a fluent interface
--SKIPIF--
<?php if (!extension_loaded("pimple")) print "skip"; ?>
--FILE--
<?php
class Foo implements Pimple\ServiceProviderInterface
{
public function register(Pimple\Container $p)
{
}
}
$p = new Pimple\Container();
var_dump($p === $p->register(new Foo));
--EXPECTF--
bool(true)

View File

@@ -0,0 +1,51 @@
<?php
if (!class_exists('Pimple\Container')) {
require_once __DIR__ . '/../../../src/Pimple/Container.php';
} else {
echo "pimple-c extension detected, using...\n\n";
}
$time = microtime(true);
function foo() { }
$factory = function () { };
for ($i=0; $i<10000; $i++) {
$p = new Pimple\Container;
$p['foo'] = 'bar';
if (!isset($p[3])) {
$p[3] = $p['foo'];
$p[] = 'bar';
}
$p[2] = 42;
if (isset($p[2])) {
unset($p[2]);
}
$p[42] = $p['foo'];
$p['cb'] = function($arg) { };
$p[] = $p['cb'];
echo $p['cb'];
echo $p['cb'];
echo $p['cb'];
//$p->factory($factory);
$p['factory'] = $factory;
echo $p['factory'];
echo $p['factory'];
echo $p['factory'];
}
echo microtime(true) - $time;

View File

@@ -0,0 +1,25 @@
<?php
if (!class_exists('Pimple\Container')) {
require_once __DIR__ . '/../../../src/Pimple/Container.php';
} else {
echo "pimple-c extension detected, using...\n\n";
}
$time = microtime(true);
$service = function ($arg) { return "I'm a service"; };
for ($i=0; $i<10000; $i++) {
$p = new Pimple\Container;
$p['my_service'] = $service;
$a = $p['my_service'];
$b = $p['my_service'];
}
echo microtime(true) - $time;
?>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="Pimple Test Suite">
<directory>./src/Pimple/Tests</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@@ -0,0 +1,298 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple;
use Pimple\Exception\ExpectedInvokableException;
use Pimple\Exception\FrozenServiceException;
use Pimple\Exception\InvalidServiceIdentifierException;
use Pimple\Exception\UnknownIdentifierException;
/**
* Container main class.
*
* @author Fabien Potencier
*/
class Container implements \ArrayAccess
{
private $values = array();
private $factories;
private $protected;
private $frozen = array();
private $raw = array();
private $keys = array();
/**
* Instantiates the container.
*
* Objects and parameters can be passed as argument to the constructor.
*
* @param array $values The parameters or objects
*/
public function __construct(array $values = array())
{
$this->factories = new \SplObjectStorage();
$this->protected = new \SplObjectStorage();
foreach ($values as $key => $value) {
$this->offsetSet($key, $value);
}
}
/**
* Sets a parameter or an object.
*
* Objects must be defined as Closures.
*
* Allowing any PHP callable leads to difficult to debug problems
* as function names (strings) are callable (creating a function with
* the same name as an existing parameter would break your container).
*
* @param string $id The unique identifier for the parameter or object
* @param mixed $value The value of the parameter or a closure to define an object
*
* @throws FrozenServiceException Prevent override of a frozen service
*/
public function offsetSet($id, $value)
{
if (isset($this->frozen[$id])) {
throw new FrozenServiceException($id);
}
$this->values[$id] = $value;
$this->keys[$id] = true;
}
/**
* Gets a parameter or an object.
*
* @param string $id The unique identifier for the parameter or object
*
* @return mixed The value of the parameter or an object
*
* @throws UnknownIdentifierException If the identifier is not defined
*/
public function offsetGet($id)
{
if (!isset($this->keys[$id])) {
throw new UnknownIdentifierException($id);
}
if (
isset($this->raw[$id])
|| !\is_object($this->values[$id])
|| isset($this->protected[$this->values[$id]])
|| !\method_exists($this->values[$id], '__invoke')
) {
return $this->values[$id];
}
if (isset($this->factories[$this->values[$id]])) {
return $this->values[$id]($this);
}
$raw = $this->values[$id];
$val = $this->values[$id] = $raw($this);
$this->raw[$id] = $raw;
$this->frozen[$id] = true;
return $val;
}
/**
* Checks if a parameter or an object is set.
*
* @param string $id The unique identifier for the parameter or object
*
* @return bool
*/
public function offsetExists($id)
{
return isset($this->keys[$id]);
}
/**
* Unsets a parameter or an object.
*
* @param string $id The unique identifier for the parameter or object
*/
public function offsetUnset($id)
{
if (isset($this->keys[$id])) {
if (\is_object($this->values[$id])) {
unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]);
}
unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]);
}
}
/**
* Marks a callable as being a factory service.
*
* @param callable $callable A service definition to be used as a factory
*
* @return callable The passed callable
*
* @throws ExpectedInvokableException Service definition has to be a closure or an invokable object
*/
public function factory($callable)
{
if (!\method_exists($callable, '__invoke')) {
throw new ExpectedInvokableException('Service definition is not a Closure or invokable object.');
}
$this->factories->attach($callable);
return $callable;
}
/**
* Protects a callable from being interpreted as a service.
*
* This is useful when you want to store a callable as a parameter.
*
* @param callable $callable A callable to protect from being evaluated
*
* @return callable The passed callable
*
* @throws ExpectedInvokableException Service definition has to be a closure or an invokable object
*/
public function protect($callable)
{
if (!\method_exists($callable, '__invoke')) {
throw new ExpectedInvokableException('Callable is not a Closure or invokable object.');
}
$this->protected->attach($callable);
return $callable;
}
/**
* Gets a parameter or the closure defining an object.
*
* @param string $id The unique identifier for the parameter or object
*
* @return mixed The value of the parameter or the closure defining an object
*
* @throws UnknownIdentifierException If the identifier is not defined
*/
public function raw($id)
{
if (!isset($this->keys[$id])) {
throw new UnknownIdentifierException($id);
}
if (isset($this->raw[$id])) {
return $this->raw[$id];
}
return $this->values[$id];
}
/**
* Extends an object definition.
*
* Useful when you want to extend an existing object definition,
* without necessarily loading that object.
*
* @param string $id The unique identifier for the object
* @param callable $callable A service definition to extend the original
*
* @return callable The wrapped callable
*
* @throws UnknownIdentifierException If the identifier is not defined
* @throws FrozenServiceException If the service is frozen
* @throws InvalidServiceIdentifierException If the identifier belongs to a parameter
* @throws ExpectedInvokableException If the extension callable is not a closure or an invokable object
*/
public function extend($id, $callable)
{
if (!isset($this->keys[$id])) {
throw new UnknownIdentifierException($id);
}
if (isset($this->frozen[$id])) {
throw new FrozenServiceException($id);
}
if (!\is_object($this->values[$id]) || !\method_exists($this->values[$id], '__invoke')) {
throw new InvalidServiceIdentifierException($id);
}
if (isset($this->protected[$this->values[$id]])) {
@\trigger_error(\sprintf('How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "%s" should be protected?', $id), \E_USER_DEPRECATED);
}
if (!\is_object($callable) || !\method_exists($callable, '__invoke')) {
throw new ExpectedInvokableException('Extension service definition is not a Closure or invokable object.');
}
$factory = $this->values[$id];
$extended = function ($c) use ($callable, $factory) {
return $callable($factory($c), $c);
};
if (isset($this->factories[$factory])) {
$this->factories->detach($factory);
$this->factories->attach($extended);
}
return $this[$id] = $extended;
}
/**
* Returns all defined value names.
*
* @return array An array of value names
*/
public function keys()
{
return \array_keys($this->values);
}
/**
* Registers a service provider.
*
* @param ServiceProviderInterface $provider A ServiceProviderInterface instance
* @param array $values An array of values that customizes the provider
*
* @return static
*/
public function register(ServiceProviderInterface $provider, array $values = array())
{
$provider->register($this);
foreach ($values as $key => $value) {
$this[$key] = $value;
}
return $this;
}
}

View File

@@ -0,0 +1,38 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Exception;
use Psr\Container\ContainerExceptionInterface;
/**
* A closure or invokable object was expected.
*
* @author Pascal Luna <skalpa@zetareticuli.org>
*/
class ExpectedInvokableException extends \InvalidArgumentException implements ContainerExceptionInterface
{
}

View File

@@ -0,0 +1,45 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Exception;
use Psr\Container\ContainerExceptionInterface;
/**
* An attempt to modify a frozen service was made.
*
* @author Pascal Luna <skalpa@zetareticuli.org>
*/
class FrozenServiceException extends \RuntimeException implements ContainerExceptionInterface
{
/**
* @param string $id Identifier of the frozen service
*/
public function __construct($id)
{
parent::__construct(\sprintf('Cannot override frozen service "%s".', $id));
}
}

View File

@@ -0,0 +1,45 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Exception;
use Psr\Container\NotFoundExceptionInterface;
/**
* An attempt to perform an operation that requires a service identifier was made.
*
* @author Pascal Luna <skalpa@zetareticuli.org>
*/
class InvalidServiceIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface
{
/**
* @param string $id The invalid identifier
*/
public function __construct($id)
{
parent::__construct(\sprintf('Identifier "%s" does not contain an object definition.', $id));
}
}

View File

@@ -0,0 +1,45 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Exception;
use Psr\Container\NotFoundExceptionInterface;
/**
* The identifier of a valid service or parameter was expected.
*
* @author Pascal Luna <skalpa@zetareticuli.org>
*/
class UnknownIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface
{
/**
* @param string $id The unknown identifier
*/
public function __construct($id)
{
parent::__construct(\sprintf('Identifier "%s" is not defined.', $id));
}
}

View File

@@ -0,0 +1,55 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009-2017 Fabien Potencier
*
* 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.
*/
namespace Pimple\Psr11;
use Pimple\Container as PimpleContainer;
use Psr\Container\ContainerInterface;
/**
* PSR-11 compliant wrapper.
*
* @author Pascal Luna <skalpa@zetareticuli.org>
*/
final class Container implements ContainerInterface
{
private $pimple;
public function __construct(PimpleContainer $pimple)
{
$this->pimple = $pimple;
}
public function get($id)
{
return $this->pimple[$id];
}
public function has($id)
{
return isset($this->pimple[$id]);
}
}

View File

@@ -0,0 +1,75 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Psr11;
use Pimple\Container as PimpleContainer;
use Pimple\Exception\UnknownIdentifierException;
use Psr\Container\ContainerInterface;
/**
* Pimple PSR-11 service locator.
*
* @author Pascal Luna <skalpa@zetareticuli.org>
*/
class ServiceLocator implements ContainerInterface
{
private $container;
private $aliases = array();
/**
* @param PimpleContainer $container The Container instance used to locate services
* @param array $ids Array of service ids that can be located. String keys can be used to define aliases
*/
public function __construct(PimpleContainer $container, array $ids)
{
$this->container = $container;
foreach ($ids as $key => $id) {
$this->aliases[\is_int($key) ? $id : $key] = $id;
}
}
/**
* {@inheritdoc}
*/
public function get($id)
{
if (!isset($this->aliases[$id])) {
throw new UnknownIdentifierException($id);
}
return $this->container[$this->aliases[$id]];
}
/**
* {@inheritdoc}
*/
public function has($id)
{
return isset($this->aliases[$id]) && isset($this->container[$this->aliases[$id]]);
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple;
/**
* Lazy service iterator.
*
* @author Pascal Luna <skalpa@zetareticuli.org>
*/
final class ServiceIterator implements \Iterator
{
private $container;
private $ids;
public function __construct(Container $container, array $ids)
{
$this->container = $container;
$this->ids = $ids;
}
public function rewind()
{
\reset($this->ids);
}
public function current()
{
return $this->container[\current($this->ids)];
}
public function key()
{
return \current($this->ids);
}
public function next()
{
\next($this->ids);
}
public function valid()
{
return null !== \key($this->ids);
}
}

View File

@@ -0,0 +1,46 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple;
/**
* Pimple service provider interface.
*
* @author Fabien Potencier
* @author Dominik Zogg
*/
interface ServiceProviderInterface
{
/**
* Registers services on the given container.
*
* This method should only be used to configure services and parameters.
* It should not get services.
*
* @param Container $pimple A container instance
*/
public function register(Container $pimple);
}

View File

@@ -0,0 +1,38 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Tests\Fixtures;
class Invokable
{
public function __invoke($value = null)
{
$service = new Service();
$service->value = $value;
return $service;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Tests\Fixtures;
class NonInvokable
{
public function __call($a, $b)
{
}
}

View File

@@ -0,0 +1,54 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Tests\Fixtures;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class PimpleServiceProvider implements ServiceProviderInterface
{
/**
* Registers services on the given container.
*
* This method should only be used to configure services and parameters.
* It should not get services.
*
* @param Container $pimple An Container instance
*/
public function register(Container $pimple)
{
$pimple['param'] = 'value';
$pimple['service'] = function () {
return new Service();
};
$pimple['factory'] = $pimple->factory(function () {
return new Service();
});
}
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Tests\Fixtures;
/**
* @author Igor Wiedler <igor@wiedler.ch>
*/
class Service
{
public $value;
}

View File

@@ -0,0 +1,76 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Tests;
use Pimple\Container;
/**
* @author Dominik Zogg <dominik.zogg@gmail.com>
*/
class PimpleServiceProviderInterfaceTest extends \PHPUnit_Framework_TestCase
{
public function testProvider()
{
$pimple = new Container();
$pimpleServiceProvider = new Fixtures\PimpleServiceProvider();
$pimpleServiceProvider->register($pimple);
$this->assertEquals('value', $pimple['param']);
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
$serviceOne = $pimple['factory'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
$serviceTwo = $pimple['factory'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
$this->assertNotSame($serviceOne, $serviceTwo);
}
public function testProviderWithRegisterMethod()
{
$pimple = new Container();
$pimple->register(new Fixtures\PimpleServiceProvider(), array(
'anotherParameter' => 'anotherValue',
));
$this->assertEquals('value', $pimple['param']);
$this->assertEquals('anotherValue', $pimple['anotherParameter']);
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
$serviceOne = $pimple['factory'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
$serviceTwo = $pimple['factory'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
$this->assertNotSame($serviceOne, $serviceTwo);
}
}

View File

@@ -0,0 +1,589 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Tests;
use Pimple\Container;
/**
* @author Igor Wiedler <igor@wiedler.ch>
*/
class PimpleTest extends \PHPUnit_Framework_TestCase
{
public function testWithString()
{
$pimple = new Container();
$pimple['param'] = 'value';
$this->assertEquals('value', $pimple['param']);
}
public function testWithClosure()
{
$pimple = new Container();
$pimple['service'] = function () {
return new Fixtures\Service();
};
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
}
public function testServicesShouldBeDifferent()
{
$pimple = new Container();
$pimple['service'] = $pimple->factory(function () {
return new Fixtures\Service();
});
$serviceOne = $pimple['service'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
$serviceTwo = $pimple['service'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
$this->assertNotSame($serviceOne, $serviceTwo);
}
public function testShouldPassContainerAsParameter()
{
$pimple = new Container();
$pimple['service'] = function () {
return new Fixtures\Service();
};
$pimple['container'] = function ($container) {
return $container;
};
$this->assertNotSame($pimple, $pimple['service']);
$this->assertSame($pimple, $pimple['container']);
}
public function testIsset()
{
$pimple = new Container();
$pimple['param'] = 'value';
$pimple['service'] = function () {
return new Fixtures\Service();
};
$pimple['null'] = null;
$this->assertTrue(isset($pimple['param']));
$this->assertTrue(isset($pimple['service']));
$this->assertTrue(isset($pimple['null']));
$this->assertFalse(isset($pimple['non_existent']));
}
public function testConstructorInjection()
{
$params = array('param' => 'value');
$pimple = new Container($params);
$this->assertSame($params['param'], $pimple['param']);
}
/**
* @expectedException \Pimple\Exception\UnknownIdentifierException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testOffsetGetValidatesKeyIsPresent()
{
$pimple = new Container();
echo $pimple['foo'];
}
/**
* @group legacy
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testLegacyOffsetGetValidatesKeyIsPresent()
{
$pimple = new Container();
echo $pimple['foo'];
}
public function testOffsetGetHonorsNullValues()
{
$pimple = new Container();
$pimple['foo'] = null;
$this->assertNull($pimple['foo']);
}
public function testUnset()
{
$pimple = new Container();
$pimple['param'] = 'value';
$pimple['service'] = function () {
return new Fixtures\Service();
};
unset($pimple['param'], $pimple['service']);
$this->assertFalse(isset($pimple['param']));
$this->assertFalse(isset($pimple['service']));
}
/**
* @dataProvider serviceDefinitionProvider
*/
public function testShare($service)
{
$pimple = new Container();
$pimple['shared_service'] = $service;
$serviceOne = $pimple['shared_service'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
$serviceTwo = $pimple['shared_service'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
$this->assertSame($serviceOne, $serviceTwo);
}
/**
* @dataProvider serviceDefinitionProvider
*/
public function testProtect($service)
{
$pimple = new Container();
$pimple['protected'] = $pimple->protect($service);
$this->assertSame($service, $pimple['protected']);
}
public function testGlobalFunctionNameAsParameterValue()
{
$pimple = new Container();
$pimple['global_function'] = 'strlen';
$this->assertSame('strlen', $pimple['global_function']);
}
public function testRaw()
{
$pimple = new Container();
$pimple['service'] = $definition = $pimple->factory(function () { return 'foo'; });
$this->assertSame($definition, $pimple->raw('service'));
}
public function testRawHonorsNullValues()
{
$pimple = new Container();
$pimple['foo'] = null;
$this->assertNull($pimple->raw('foo'));
}
public function testFluentRegister()
{
$pimple = new Container();
$this->assertSame($pimple, $pimple->register($this->getMockBuilder('Pimple\ServiceProviderInterface')->getMock()));
}
/**
* @expectedException \Pimple\Exception\UnknownIdentifierException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testRawValidatesKeyIsPresent()
{
$pimple = new Container();
$pimple->raw('foo');
}
/**
* @group legacy
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testLegacyRawValidatesKeyIsPresent()
{
$pimple = new Container();
$pimple->raw('foo');
}
/**
* @dataProvider serviceDefinitionProvider
*/
public function testExtend($service)
{
$pimple = new Container();
$pimple['shared_service'] = function () {
return new Fixtures\Service();
};
$pimple['factory_service'] = $pimple->factory(function () {
return new Fixtures\Service();
});
$pimple->extend('shared_service', $service);
$serviceOne = $pimple['shared_service'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
$serviceTwo = $pimple['shared_service'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
$this->assertSame($serviceOne, $serviceTwo);
$this->assertSame($serviceOne->value, $serviceTwo->value);
$pimple->extend('factory_service', $service);
$serviceOne = $pimple['factory_service'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
$serviceTwo = $pimple['factory_service'];
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
$this->assertNotSame($serviceOne, $serviceTwo);
$this->assertNotSame($serviceOne->value, $serviceTwo->value);
}
public function testExtendDoesNotLeakWithFactories()
{
if (extension_loaded('pimple')) {
$this->markTestSkipped('Pimple extension does not support this test');
}
$pimple = new Container();
$pimple['foo'] = $pimple->factory(function () { return; });
$pimple['foo'] = $pimple->extend('foo', function ($foo, $pimple) { return; });
unset($pimple['foo']);
$p = new \ReflectionProperty($pimple, 'values');
$p->setAccessible(true);
$this->assertEmpty($p->getValue($pimple));
$p = new \ReflectionProperty($pimple, 'factories');
$p->setAccessible(true);
$this->assertCount(0, $p->getValue($pimple));
}
/**
* @expectedException \Pimple\Exception\UnknownIdentifierException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testExtendValidatesKeyIsPresent()
{
$pimple = new Container();
$pimple->extend('foo', function () {});
}
/**
* @group legacy
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testLegacyExtendValidatesKeyIsPresent()
{
$pimple = new Container();
$pimple->extend('foo', function () {});
}
public function testKeys()
{
$pimple = new Container();
$pimple['foo'] = 123;
$pimple['bar'] = 123;
$this->assertEquals(array('foo', 'bar'), $pimple->keys());
}
/** @test */
public function settingAnInvokableObjectShouldTreatItAsFactory()
{
$pimple = new Container();
$pimple['invokable'] = new Fixtures\Invokable();
$this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['invokable']);
}
/** @test */
public function settingNonInvokableObjectShouldTreatItAsParameter()
{
$pimple = new Container();
$pimple['non_invokable'] = new Fixtures\NonInvokable();
$this->assertInstanceOf('Pimple\Tests\Fixtures\NonInvokable', $pimple['non_invokable']);
}
/**
* @dataProvider badServiceDefinitionProvider
* @expectedException \Pimple\Exception\ExpectedInvokableException
* @expectedExceptionMessage Service definition is not a Closure or invokable object.
*/
public function testFactoryFailsForInvalidServiceDefinitions($service)
{
$pimple = new Container();
$pimple->factory($service);
}
/**
* @group legacy
* @dataProvider badServiceDefinitionProvider
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Service definition is not a Closure or invokable object.
*/
public function testLegacyFactoryFailsForInvalidServiceDefinitions($service)
{
$pimple = new Container();
$pimple->factory($service);
}
/**
* @dataProvider badServiceDefinitionProvider
* @expectedException \Pimple\Exception\ExpectedInvokableException
* @expectedExceptionMessage Callable is not a Closure or invokable object.
*/
public function testProtectFailsForInvalidServiceDefinitions($service)
{
$pimple = new Container();
$pimple->protect($service);
}
/**
* @group legacy
* @dataProvider badServiceDefinitionProvider
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Callable is not a Closure or invokable object.
*/
public function testLegacyProtectFailsForInvalidServiceDefinitions($service)
{
$pimple = new Container();
$pimple->protect($service);
}
/**
* @dataProvider badServiceDefinitionProvider
* @expectedException \Pimple\Exception\InvalidServiceIdentifierException
* @expectedExceptionMessage Identifier "foo" does not contain an object definition.
*/
public function testExtendFailsForKeysNotContainingServiceDefinitions($service)
{
$pimple = new Container();
$pimple['foo'] = $service;
$pimple->extend('foo', function () {});
}
/**
* @group legacy
* @dataProvider badServiceDefinitionProvider
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Identifier "foo" does not contain an object definition.
*/
public function testLegacyExtendFailsForKeysNotContainingServiceDefinitions($service)
{
$pimple = new Container();
$pimple['foo'] = $service;
$pimple->extend('foo', function () {});
}
/**
* @group legacy
* @expectedDeprecation How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "foo" should be protected?
*/
public function testExtendingProtectedClosureDeprecation()
{
$pimple = new Container();
$pimple['foo'] = $pimple->protect(function () {
return 'bar';
});
$pimple->extend('foo', function ($value) {
return $value.'-baz';
});
$this->assertSame('bar-baz', $pimple['foo']);
}
/**
* @dataProvider badServiceDefinitionProvider
* @expectedException \Pimple\Exception\ExpectedInvokableException
* @expectedExceptionMessage Extension service definition is not a Closure or invokable object.
*/
public function testExtendFailsForInvalidServiceDefinitions($service)
{
$pimple = new Container();
$pimple['foo'] = function () {};
$pimple->extend('foo', $service);
}
/**
* @group legacy
* @dataProvider badServiceDefinitionProvider
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Extension service definition is not a Closure or invokable object.
*/
public function testLegacyExtendFailsForInvalidServiceDefinitions($service)
{
$pimple = new Container();
$pimple['foo'] = function () {};
$pimple->extend('foo', $service);
}
/**
* @expectedException \Pimple\Exception\FrozenServiceException
* @expectedExceptionMessage Cannot override frozen service "foo".
*/
public function testExtendFailsIfFrozenServiceIsNonInvokable()
{
$pimple = new Container();
$pimple['foo'] = function () {
return new Fixtures\NonInvokable();
};
$foo = $pimple['foo'];
$pimple->extend('foo', function () {});
}
/**
* @expectedException \Pimple\Exception\FrozenServiceException
* @expectedExceptionMessage Cannot override frozen service "foo".
*/
public function testExtendFailsIfFrozenServiceIsInvokable()
{
$pimple = new Container();
$pimple['foo'] = function () {
return new Fixtures\Invokable();
};
$foo = $pimple['foo'];
$pimple->extend('foo', function () {});
}
/**
* Provider for invalid service definitions.
*/
public function badServiceDefinitionProvider()
{
return array(
array(123),
array(new Fixtures\NonInvokable()),
);
}
/**
* Provider for service definitions.
*/
public function serviceDefinitionProvider()
{
return array(
array(function ($value) {
$service = new Fixtures\Service();
$service->value = $value;
return $service;
}),
array(new Fixtures\Invokable()),
);
}
public function testDefiningNewServiceAfterFreeze()
{
$pimple = new Container();
$pimple['foo'] = function () {
return 'foo';
};
$foo = $pimple['foo'];
$pimple['bar'] = function () {
return 'bar';
};
$this->assertSame('bar', $pimple['bar']);
}
/**
* @expectedException \Pimple\Exception\FrozenServiceException
* @expectedExceptionMessage Cannot override frozen service "foo".
*/
public function testOverridingServiceAfterFreeze()
{
$pimple = new Container();
$pimple['foo'] = function () {
return 'foo';
};
$foo = $pimple['foo'];
$pimple['foo'] = function () {
return 'bar';
};
}
/**
* @group legacy
* @expectedException \RuntimeException
* @expectedExceptionMessage Cannot override frozen service "foo".
*/
public function testLegacyOverridingServiceAfterFreeze()
{
$pimple = new Container();
$pimple['foo'] = function () {
return 'foo';
};
$foo = $pimple['foo'];
$pimple['foo'] = function () {
return 'bar';
};
}
public function testRemovingServiceAfterFreeze()
{
$pimple = new Container();
$pimple['foo'] = function () {
return 'foo';
};
$foo = $pimple['foo'];
unset($pimple['foo']);
$pimple['foo'] = function () {
return 'bar';
};
$this->assertSame('bar', $pimple['foo']);
}
public function testExtendingService()
{
$pimple = new Container();
$pimple['foo'] = function () {
return 'foo';
};
$pimple['foo'] = $pimple->extend('foo', function ($foo, $app) {
return "$foo.bar";
});
$pimple['foo'] = $pimple->extend('foo', function ($foo, $app) {
return "$foo.baz";
});
$this->assertSame('foo.bar.baz', $pimple['foo']);
}
public function testExtendingServiceAfterOtherServiceFreeze()
{
$pimple = new Container();
$pimple['foo'] = function () {
return 'foo';
};
$pimple['bar'] = function () {
return 'bar';
};
$foo = $pimple['foo'];
$pimple['bar'] = $pimple->extend('bar', function ($bar, $app) {
return "$bar.baz";
});
$this->assertSame('bar.baz', $pimple['bar']);
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009-2017 Fabien Potencier
*
* 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.
*/
namespace Pimple\Tests\Psr11;
use PHPUnit\Framework\TestCase;
use Pimple\Container;
use Pimple\Psr11\Container as PsrContainer;
use Pimple\Tests\Fixtures\Service;
class ContainerTest extends TestCase
{
public function testGetReturnsExistingService()
{
$pimple = new Container();
$pimple['service'] = function () {
return new Service();
};
$psr = new PsrContainer($pimple);
$this->assertSame($pimple['service'], $psr->get('service'));
}
/**
* @expectedException \Psr\Container\NotFoundExceptionInterface
* @expectedExceptionMessage Identifier "service" is not defined.
*/
public function testGetThrowsExceptionIfServiceIsNotFound()
{
$pimple = new Container();
$psr = new PsrContainer($pimple);
$psr->get('service');
}
public function testHasReturnsTrueIfServiceExists()
{
$pimple = new Container();
$pimple['service'] = function () {
return new Service();
};
$psr = new PsrContainer($pimple);
$this->assertTrue($psr->has('service'));
}
public function testHasReturnsFalseIfServiceDoesNotExist()
{
$pimple = new Container();
$psr = new PsrContainer($pimple);
$this->assertFalse($psr->has('service'));
}
}

View File

@@ -0,0 +1,134 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Tests\Psr11;
use PHPUnit\Framework\TestCase;
use Pimple\Container;
use Pimple\Psr11\ServiceLocator;
use Pimple\Tests\Fixtures;
/**
* ServiceLocator test case.
*
* @author Pascal Luna <skalpa@zetareticuli.org>
*/
class ServiceLocatorTest extends TestCase
{
public function testCanAccessServices()
{
$pimple = new Container();
$pimple['service'] = function () {
return new Fixtures\Service();
};
$locator = new ServiceLocator($pimple, array('service'));
$this->assertSame($pimple['service'], $locator->get('service'));
}
public function testCanAccessAliasedServices()
{
$pimple = new Container();
$pimple['service'] = function () {
return new Fixtures\Service();
};
$locator = new ServiceLocator($pimple, array('alias' => 'service'));
$this->assertSame($pimple['service'], $locator->get('alias'));
}
/**
* @expectedException \Pimple\Exception\UnknownIdentifierException
* @expectedExceptionMessage Identifier "service" is not defined.
*/
public function testCannotAccessAliasedServiceUsingRealIdentifier()
{
$pimple = new Container();
$pimple['service'] = function () {
return new Fixtures\Service();
};
$locator = new ServiceLocator($pimple, array('alias' => 'service'));
$service = $locator->get('service');
}
/**
* @expectedException \Pimple\Exception\UnknownIdentifierException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testGetValidatesServiceCanBeLocated()
{
$pimple = new Container();
$pimple['service'] = function () {
return new Fixtures\Service();
};
$locator = new ServiceLocator($pimple, array('alias' => 'service'));
$service = $locator->get('foo');
}
/**
* @expectedException \Pimple\Exception\UnknownIdentifierException
* @expectedExceptionMessage Identifier "invalid" is not defined.
*/
public function testGetValidatesTargetServiceExists()
{
$pimple = new Container();
$pimple['service'] = function () {
return new Fixtures\Service();
};
$locator = new ServiceLocator($pimple, array('alias' => 'invalid'));
$service = $locator->get('alias');
}
public function testHasValidatesServiceCanBeLocated()
{
$pimple = new Container();
$pimple['service1'] = function () {
return new Fixtures\Service();
};
$pimple['service2'] = function () {
return new Fixtures\Service();
};
$locator = new ServiceLocator($pimple, array('service1'));
$this->assertTrue($locator->has('service1'));
$this->assertFalse($locator->has('service2'));
}
public function testHasChecksIfTargetServiceExists()
{
$pimple = new Container();
$pimple['service'] = function () {
return new Fixtures\Service();
};
$locator = new ServiceLocator($pimple, array('foo' => 'service', 'bar' => 'invalid'));
$this->assertTrue($locator->has('foo'));
$this->assertFalse($locator->has('bar'));
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* 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.
*/
namespace Pimple\Tests;
use PHPUnit\Framework\TestCase;
use Pimple\Container;
use Pimple\ServiceIterator;
use Pimple\Tests\Fixtures\Service;
class ServiceIteratorTest extends TestCase
{
public function testIsIterable()
{
$pimple = new Container();
$pimple['service1'] = function () {
return new Service();
};
$pimple['service2'] = function () {
return new Service();
};
$pimple['service3'] = function () {
return new Service();
};
$iterator = new ServiceIterator($pimple, array('service1', 'service2'));
$this->assertSame(array('service1' => $pimple['service1'], 'service2' => $pimple['service2']), iterator_to_array($iterator));
}
}

View File

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

21
lib/silex/vendor/psr/container/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2013-2016 container-interop
Copyright (c) 2016 PHP Framework Interoperability Group
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,5 @@
# PSR Container
This repository holds all interfaces/classes/traits related to [PSR-11](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md).
Note that this is not a container implementation of its own. See the specification for more details.

View File

@@ -0,0 +1,27 @@
{
"name": "psr/container",
"type": "library",
"description": "Common Container Interface (PHP FIG PSR-11)",
"keywords": ["psr", "psr-11", "container", "container-interop", "container-interface"],
"homepage": "https://github.com/php-fig/container",
"license": "MIT",
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"require": {
"php": ">=5.3.0"
},
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
}
}

View File

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

View File

@@ -0,0 +1,37 @@
<?php
/**
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace Psr\Container;
/**
* 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 NotFoundExceptionInterface No entry was found for **this** identifier.
* @throws ContainerExceptionInterface 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 `NotFoundExceptionInterface`.
*
* @param string $id Identifier of the entry to look for.
*
* @return bool
*/
public function has($id);
}

View File

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

View File

@@ -15,8 +15,9 @@ abstract class AbstractLogger implements LoggerInterface
* System is unusable.
*
* @param string $message
* @param array $context
* @return null
* @param array $context
*
* @return void
*/
public function emergency($message, array $context = array())
{
@@ -30,8 +31,9 @@ abstract class AbstractLogger implements LoggerInterface
* trigger the SMS alerts and wake you up.
*
* @param string $message
* @param array $context
* @return null
* @param array $context
*
* @return void
*/
public function alert($message, array $context = array())
{
@@ -44,8 +46,9 @@ abstract class AbstractLogger implements LoggerInterface
* Example: Application component unavailable, unexpected exception.
*
* @param string $message
* @param array $context
* @return null
* @param array $context
*
* @return void
*/
public function critical($message, array $context = array())
{
@@ -57,8 +60,9 @@ abstract class AbstractLogger implements LoggerInterface
* be logged and monitored.
*
* @param string $message
* @param array $context
* @return null
* @param array $context
*
* @return void
*/
public function error($message, array $context = array())
{
@@ -72,8 +76,9 @@ abstract class AbstractLogger implements LoggerInterface
* that are not necessarily wrong.
*
* @param string $message
* @param array $context
* @return null
* @param array $context
*
* @return void
*/
public function warning($message, array $context = array())
{
@@ -84,8 +89,9 @@ abstract class AbstractLogger implements LoggerInterface
* Normal but significant events.
*
* @param string $message
* @param array $context
* @return null
* @param array $context
*
* @return void
*/
public function notice($message, array $context = array())
{
@@ -98,8 +104,9 @@ abstract class AbstractLogger implements LoggerInterface
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
* @return null
* @param array $context
*
* @return void
*/
public function info($message, array $context = array())
{
@@ -110,8 +117,9 @@ abstract class AbstractLogger implements LoggerInterface
* Detailed debug information.
*
* @param string $message
* @param array $context
* @return null
* @param array $context
*
* @return void
*/
public function debug($message, array $context = array())
{

View File

@@ -3,16 +3,16 @@
namespace Psr\Log;
/**
* Describes log levels
* Describes log levels.
*/
class LogLevel
{
const EMERGENCY = 'emergency';
const ALERT = 'alert';
const CRITICAL = 'critical';
const ERROR = 'error';
const WARNING = 'warning';
const NOTICE = 'notice';
const INFO = 'info';
const DEBUG = 'debug';
const ALERT = 'alert';
const CRITICAL = 'critical';
const ERROR = 'error';
const WARNING = 'warning';
const NOTICE = 'notice';
const INFO = 'info';
const DEBUG = 'debug';
}

View File

@@ -3,15 +3,16 @@
namespace Psr\Log;
/**
* Describes a logger-aware instance
* Describes a logger-aware instance.
*/
interface LoggerAwareInterface
{
/**
* Sets a logger instance on the object
* Sets a logger instance on the object.
*
* @param LoggerInterface $logger
* @return null
*
* @return void
*/
public function setLogger(LoggerInterface $logger);
}

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