1
0
mirror of https://github.com/typemill/typemill.git synced 2025-08-03 12:47:34 +02:00

update dependencies

This commit is contained in:
Sebastian
2017-11-14 21:15:14 +01:00
parent 4fe7244734
commit 67d2a487de
99 changed files with 2136 additions and 700 deletions

4
.gitignore vendored
View File

@@ -4,4 +4,6 @@ cache/lastSitemap.txt
cache/lastCache.txt
settings/settings.yaml
typemill.zip
typemill-1.0.1.zip
typemill-1.0.1.zip
typemill-1.0.2.zip
zip.php

View File

@@ -9,14 +9,14 @@
"vendor-dir": "system/vendor"
},
"require": {
"slim/slim": "^3.7",
"twig/twig": "^1.18",
"slim/twig-view": "dev-master",
"slim/flash": "dev-master",
"slim/slim": "~3.7",
"twig/twig": "~1.18",
"slim/twig-view": "~2.3",
"slim/flash": "~0.4",
"symfony/yaml": "~2.8",
"erusev/parsedown": "~1.4",
"erusev/parsedown-extra": "dev-master",
"jbroadway/urlify": "dev-master"
"jbroadway/urlify": "~1.1"
},
"autoload": {
"psr-4": {

93
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "d87e8a91b5cd2804da3d65681e9d5945",
"content-hash": "d5756d6121a1cf74d8c17d9ba55ae0d5",
"packages": [
{
"name": "container-interop/container-interop",
@@ -39,16 +39,16 @@
},
{
"name": "erusev/parsedown",
"version": "1.6.2",
"version": "1.6.3",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "1bf24f7334fe16c88bf9d467863309ceaf285b01"
"reference": "728952b90a333b5c6f77f06ea9422b94b585878d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/1bf24f7334fe16c88bf9d467863309ceaf285b01",
"reference": "1bf24f7334fe16c88bf9d467863309ceaf285b01",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/728952b90a333b5c6f77f06ea9422b94b585878d",
"reference": "728952b90a333b5c6f77f06ea9422b94b585878d",
"shasum": ""
},
"require": {
@@ -77,7 +77,7 @@
"markdown",
"parser"
],
"time": "2017-03-29T16:04:15+00:00"
"time": "2017-05-14T14:47:48+00:00"
},
{
"name": "erusev/parsedown-extra",
@@ -121,11 +121,11 @@
"parsedown",
"parser"
],
"time": "2015-11-01 10:19:22"
"time": "2015-11-01T10:19:22+00:00"
},
{
"name": "jbroadway/urlify",
"version": "dev-master",
"version": "1.1.0-stable",
"source": {
"type": "git",
"url": "https://github.com/jbroadway/urlify.git",
@@ -175,7 +175,7 @@
"url",
"urlify"
],
"time": "2017-01-03 20:12:54"
"time": "2017-01-03T20:12:54+00:00"
},
{
"name": "nikic/fast-route",
@@ -222,25 +222,29 @@
},
{
"name": "pimple/pimple",
"version": "v3.0.2",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/silexphp/Pimple.git",
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a"
"reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a",
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a",
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/4d45fb62d96418396ec58ba76e6f065bca16e10a",
"reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
"php": ">=5.3.0",
"psr/container": "^1.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^3.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev"
"dev-master": "3.2.x-dev"
}
},
"autoload": {
@@ -264,7 +268,7 @@
"container",
"dependency injection"
],
"time": "2015-09-11T15:10:35+00:00"
"time": "2017-07-23T07:32:15+00:00"
},
{
"name": "psr/container",
@@ -367,16 +371,16 @@
},
{
"name": "slim/flash",
"version": "dev-master",
"version": "0.4.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim-Flash.git",
"reference": "3c9a26b3163820acc48080336c504d0a3cac6f30"
"reference": "9aaff5fded3b54f4e519ec3d4ac74d3d1f2cbbbc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim-Flash/zipball/3c9a26b3163820acc48080336c504d0a3cac6f30",
"reference": "3c9a26b3163820acc48080336c504d0a3cac6f30",
"url": "https://api.github.com/repos/slimphp/Slim-Flash/zipball/9aaff5fded3b54f4e519ec3d4ac74d3d1f2cbbbc",
"reference": "9aaff5fded3b54f4e519ec3d4ac74d3d1f2cbbbc",
"shasum": ""
},
"require": {
@@ -411,20 +415,20 @@
"provider",
"slim"
],
"time": "2016-11-11 16:29:19"
"time": "2017-10-22T10:35:05+00:00"
},
{
"name": "slim/slim",
"version": "3.8.1",
"version": "3.9.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
"reference": "5385302707530b2bccee1769613ad769859b826d"
"reference": "575a8b53a0a489447915029c69680156cd355304"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/5385302707530b2bccee1769613ad769859b826d",
"reference": "5385302707530b2bccee1769613ad769859b826d",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/575a8b53a0a489447915029c69680156cd355304",
"reference": "575a8b53a0a489447915029c69680156cd355304",
"shasum": ""
},
"require": {
@@ -482,20 +486,20 @@
"micro",
"router"
],
"time": "2017-03-19T17:55:20+00:00"
"time": "2017-11-04T08:46:46+00:00"
},
{
"name": "slim/twig-view",
"version": "dev-master",
"version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Twig-View.git",
"reference": "a743ac45e2a089942159dda499c5ef5bc5f6bfa6"
"reference": "f6ff5ec3a24e11866376b8ffa235fbbb7e1d1301"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Twig-View/zipball/a743ac45e2a089942159dda499c5ef5bc5f6bfa6",
"reference": "a743ac45e2a089942159dda499c5ef5bc5f6bfa6",
"url": "https://api.github.com/repos/slimphp/Twig-View/zipball/f6ff5ec3a24e11866376b8ffa235fbbb7e1d1301",
"reference": "f6ff5ec3a24e11866376b8ffa235fbbb7e1d1301",
"shasum": ""
},
"require": {
@@ -532,20 +536,20 @@
"twig",
"view"
],
"time": "2017-01-25 20:38:39"
"time": "2017-09-20T19:47:37+00:00"
},
{
"name": "symfony/yaml",
"version": "v2.8.22",
"version": "v2.8.30",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5"
"reference": "d819bf267e901727141fe828ae888486fd21236e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5",
"reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5",
"url": "https://api.github.com/repos/symfony/yaml/zipball/d819bf267e901727141fe828ae888486fd21236e",
"reference": "d819bf267e901727141fe828ae888486fd21236e",
"shasum": ""
},
"require": {
@@ -581,20 +585,20 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2017-06-01T20:52:29+00:00"
"time": "2017-11-05T15:25:56+00:00"
},
{
"name": "twig/twig",
"version": "v1.34.3",
"version": "v1.35.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "451c6f4197e113e24c1c85bc3fc8c2d77adeff2e"
"reference": "daa657073e55b0a78cce8fdd22682fddecc6385f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/451c6f4197e113e24c1c85bc3fc8c2d77adeff2e",
"reference": "451c6f4197e113e24c1c85bc3fc8c2d77adeff2e",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/daa657073e55b0a78cce8fdd22682fddecc6385f",
"reference": "daa657073e55b0a78cce8fdd22682fddecc6385f",
"shasum": ""
},
"require": {
@@ -608,7 +612,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.34-dev"
"dev-master": "1.35-dev"
}
},
"autoload": {
@@ -646,17 +650,14 @@
"keywords": [
"templating"
],
"time": "2017-06-07T18:45:17+00:00"
"time": "2017-09-27T18:06:46+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"slim/twig-view": 20,
"slim/flash": 20,
"erusev/parsedown-extra": 20,
"jbroadway/urlify": 20
"erusev/parsedown-extra": 20
},
"prefer-stable": false,
"prefer-lowest": false,

View File

@@ -15,7 +15,7 @@ return [
'settingsPath' => __DIR__ . DS . '..' . DS . 'settings',
'authorPath' => __DIR__ . DS . 'author' . DS,
'contentFolder' => 'content',
'displayErrorDetails' => false,
'displayErrorDetails' => true,
'version' => '1.0.2'
];

View File

@@ -96,106 +96,6 @@
"response"
]
},
{
"name": "pimple/pimple",
"version": "v3.0.2",
"version_normalized": "3.0.2.0",
"source": {
"type": "git",
"url": "https://github.com/silexphp/Pimple.git",
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a",
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2015-09-11T15:10:35+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Pimple": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Pimple, a simple Dependency Injection Container",
"homepage": "http://pimple.sensiolabs.org",
"keywords": [
"container",
"dependency injection"
]
},
{
"name": "slim/twig-view",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Twig-View.git",
"reference": "a743ac45e2a089942159dda499c5ef5bc5f6bfa6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Twig-View/zipball/a743ac45e2a089942159dda499c5ef5bc5f6bfa6",
"reference": "a743ac45e2a089942159dda499c5ef5bc5f6bfa6",
"shasum": ""
},
"require": {
"php": ">=5.5.0",
"psr/http-message": "^1.0",
"twig/twig": "^1.18|^2.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8|^5.7"
},
"time": "2017-01-25T20:38:39+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-4": {
"Slim\\Views\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Josh Lockhart",
"email": "hello@joshlockhart.com",
"homepage": "http://joshlockhart.com"
}
],
"description": "Slim Framework 3 view helper built on top of the Twig 2 templating component",
"homepage": "http://slimframework.com",
"keywords": [
"framework",
"slim",
"template",
"twig",
"view"
]
},
{
"name": "psr/container",
"version": "1.0.0",
@@ -280,10 +180,399 @@
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
"homepage": "https://github.com/container-interop/container-interop"
},
{
"name": "pimple/pimple",
"version": "v3.2.2",
"version_normalized": "3.2.2.0",
"source": {
"type": "git",
"url": "https://github.com/silexphp/Pimple.git",
"reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/4d45fb62d96418396ec58ba76e6f065bca16e10a",
"reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/container": "^1.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^3.2"
},
"time": "2017-07-23T07:32:15+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Pimple": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Pimple, a simple Dependency Injection Container",
"homepage": "http://pimple.sensiolabs.org",
"keywords": [
"container",
"dependency injection"
]
},
{
"name": "slim/slim",
"version": "3.9.0",
"version_normalized": "3.9.0.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
"reference": "575a8b53a0a489447915029c69680156cd355304"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/575a8b53a0a489447915029c69680156cd355304",
"reference": "575a8b53a0a489447915029c69680156cd355304",
"shasum": ""
},
"require": {
"container-interop/container-interop": "^1.2",
"nikic/fast-route": "^1.0",
"php": ">=5.5.0",
"pimple/pimple": "^3.0",
"psr/container": "^1.0",
"psr/http-message": "^1.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0",
"squizlabs/php_codesniffer": "^2.5"
},
"time": "2017-11-04T08:46:46+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Slim\\": "Slim"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rob Allen",
"email": "rob@akrabat.com",
"homepage": "http://akrabat.com"
},
{
"name": "Josh Lockhart",
"email": "hello@joshlockhart.com",
"homepage": "https://joshlockhart.com"
},
{
"name": "Gabriel Manricks",
"email": "gmanricks@me.com",
"homepage": "http://gabrielmanricks.com"
},
{
"name": "Andrew Smith",
"email": "a.smith@silentworks.co.uk",
"homepage": "http://silentworks.co.uk"
}
],
"description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
"homepage": "https://slimframework.com",
"keywords": [
"api",
"framework",
"micro",
"router"
]
},
{
"name": "twig/twig",
"version": "v1.35.0",
"version_normalized": "1.35.0.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "daa657073e55b0a78cce8fdd22682fddecc6385f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/daa657073e55b0a78cce8fdd22682fddecc6385f",
"reference": "daa657073e55b0a78cce8fdd22682fddecc6385f",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"psr/container": "^1.0",
"symfony/debug": "~2.7",
"symfony/phpunit-bridge": "~3.3@dev"
},
"time": "2017-09-27T18:06:46+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.35-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Twig_": "lib/"
},
"psr-4": {
"Twig\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
},
{
"name": "Twig Team",
"homepage": "http://twig.sensiolabs.org/contributors",
"role": "Contributors"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "http://twig.sensiolabs.org",
"keywords": [
"templating"
]
},
{
"name": "symfony/yaml",
"version": "v2.8.30",
"version_normalized": "2.8.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "d819bf267e901727141fe828ae888486fd21236e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/d819bf267e901727141fe828ae888486fd21236e",
"reference": "d819bf267e901727141fe828ae888486fd21236e",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"time": "2017-11-05T15:25:56+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com"
},
{
"name": "erusev/parsedown",
"version": "1.6.3",
"version_normalized": "1.6.3.0",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "728952b90a333b5c6f77f06ea9422b94b585878d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/728952b90a333b5c6f77f06ea9422b94b585878d",
"reference": "728952b90a333b5c6f77f06ea9422b94b585878d",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2017-05-14T14:47:48+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-0": {
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Parser for Markdown.",
"homepage": "http://parsedown.org",
"keywords": [
"markdown",
"parser"
]
},
{
"name": "slim/twig-view",
"version": "2.3.0",
"version_normalized": "2.3.0.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Twig-View.git",
"reference": "f6ff5ec3a24e11866376b8ffa235fbbb7e1d1301"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Twig-View/zipball/f6ff5ec3a24e11866376b8ffa235fbbb7e1d1301",
"reference": "f6ff5ec3a24e11866376b8ffa235fbbb7e1d1301",
"shasum": ""
},
"require": {
"php": ">=5.5.0",
"psr/http-message": "^1.0",
"twig/twig": "^1.18|^2.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8|^5.7"
},
"time": "2017-09-20T19:47:37+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-4": {
"Slim\\Views\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Josh Lockhart",
"email": "hello@joshlockhart.com",
"homepage": "http://joshlockhart.com"
}
],
"description": "Slim Framework 3 view helper built on top of the Twig 2 templating component",
"homepage": "http://slimframework.com",
"keywords": [
"framework",
"slim",
"template",
"twig",
"view"
]
},
{
"name": "slim/flash",
"version": "0.4.0",
"version_normalized": "0.4.0.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim-Flash.git",
"reference": "9aaff5fded3b54f4e519ec3d4ac74d3d1f2cbbbc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim-Flash/zipball/9aaff5fded3b54f4e519ec3d4ac74d3d1f2cbbbc",
"reference": "9aaff5fded3b54f4e519ec3d4ac74d3d1f2cbbbc",
"shasum": ""
},
"require": {
"php": ">=5.5.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0"
},
"time": "2017-10-22T10:35:05+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-4": {
"Slim\\Flash\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Josh Lockhart",
"email": "hello@joshlockhart.com",
"homepage": "http://joshlockhart.com"
}
],
"description": "Slim Framework Flash message service provider",
"homepage": "http://slimframework.com",
"keywords": [
"flash",
"framework",
"message",
"provider",
"slim"
]
},
{
"name": "jbroadway/urlify",
"version": "dev-master",
"version_normalized": "9999999-dev",
"version": "1.1.0-stable",
"version_normalized": "1.1.0.0",
"source": {
"type": "git",
"url": "https://github.com/jbroadway/urlify.git",
@@ -336,79 +625,6 @@
"urlify"
]
},
{
"name": "slim/slim",
"version": "3.8.1",
"version_normalized": "3.8.1.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
"reference": "5385302707530b2bccee1769613ad769859b826d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/5385302707530b2bccee1769613ad769859b826d",
"reference": "5385302707530b2bccee1769613ad769859b826d",
"shasum": ""
},
"require": {
"container-interop/container-interop": "^1.2",
"nikic/fast-route": "^1.0",
"php": ">=5.5.0",
"pimple/pimple": "^3.0",
"psr/container": "^1.0",
"psr/http-message": "^1.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0",
"squizlabs/php_codesniffer": "^2.5"
},
"time": "2017-03-19T17:55:20+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Slim\\": "Slim"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rob Allen",
"email": "rob@akrabat.com",
"homepage": "http://akrabat.com"
},
{
"name": "Josh Lockhart",
"email": "hello@joshlockhart.com",
"homepage": "https://joshlockhart.com"
},
{
"name": "Gabriel Manricks",
"email": "gmanricks@me.com",
"homepage": "http://gabrielmanricks.com"
},
{
"name": "Andrew Smith",
"email": "a.smith@silentworks.co.uk",
"homepage": "http://silentworks.co.uk"
}
],
"description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
"homepage": "https://slimframework.com",
"keywords": [
"api",
"framework",
"micro",
"router"
]
},
{
"name": "erusev/parsedown-extra",
"version": "dev-master",
@@ -454,217 +670,5 @@
"parsedown",
"parser"
]
},
{
"name": "erusev/parsedown",
"version": "1.6.2",
"version_normalized": "1.6.2.0",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "1bf24f7334fe16c88bf9d467863309ceaf285b01"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/1bf24f7334fe16c88bf9d467863309ceaf285b01",
"reference": "1bf24f7334fe16c88bf9d467863309ceaf285b01",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2017-03-29T16:04:15+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-0": {
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Parser for Markdown.",
"homepage": "http://parsedown.org",
"keywords": [
"markdown",
"parser"
]
},
{
"name": "slim/flash",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim-Flash.git",
"reference": "3c9a26b3163820acc48080336c504d0a3cac6f30"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim-Flash/zipball/3c9a26b3163820acc48080336c504d0a3cac6f30",
"reference": "3c9a26b3163820acc48080336c504d0a3cac6f30",
"shasum": ""
},
"require": {
"php": ">=5.5.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0"
},
"time": "2016-11-11T16:29:19+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-4": {
"Slim\\Flash\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Josh Lockhart",
"email": "hello@joshlockhart.com",
"homepage": "http://joshlockhart.com"
}
],
"description": "Slim Framework Flash message service provider",
"homepage": "http://slimframework.com",
"keywords": [
"flash",
"framework",
"message",
"provider",
"slim"
]
},
{
"name": "twig/twig",
"version": "v1.34.3",
"version_normalized": "1.34.3.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "451c6f4197e113e24c1c85bc3fc8c2d77adeff2e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/451c6f4197e113e24c1c85bc3fc8c2d77adeff2e",
"reference": "451c6f4197e113e24c1c85bc3fc8c2d77adeff2e",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"psr/container": "^1.0",
"symfony/debug": "~2.7",
"symfony/phpunit-bridge": "~3.3@dev"
},
"time": "2017-06-07T18:45:17+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.34-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Twig_": "lib/"
},
"psr-4": {
"Twig\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
},
{
"name": "Twig Team",
"homepage": "http://twig.sensiolabs.org/contributors",
"role": "Contributors"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "http://twig.sensiolabs.org",
"keywords": [
"templating"
]
},
{
"name": "symfony/yaml",
"version": "v2.8.22",
"version_normalized": "2.8.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5",
"reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"time": "2017-06-01T20:52:29+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com"
}
]

Submodule system/vendor/erusev/parsedown updated: 1bf24f7334...728952b90a

View File

@@ -12,21 +12,29 @@ php:
- 5.4
- 5.5
- 5.6
- hhvm
- 7.0
- 7.1
before_script:
- composer self-update
- COMPOSER_ROOT_VERSION=dev-master composer dump-autoload
- 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 ../..
- phpunit
- ./vendor/bin/simple-phpunit
matrix:
exclude:
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

@@ -1,3 +1,23 @@
* 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

View File

@@ -1,4 +1,4 @@
Copyright (c) 2009-2015 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

@@ -17,18 +17,7 @@ Before using Pimple in your project, add it to your ``composer.json`` file:
.. code-block:: bash
$ ./composer.phar require pimple/pimple ~3.0
Alternatively, Pimple is also available as a PHP C extension:
.. code-block:: bash
$ git clone https://github.com/silexphp/Pimple
$ cd Pimple/ext/pimple
$ phpize
$ ./configure
$ make
$ make install
$ ./composer.phar require pimple/pimple "^3.0"
Usage
-----
@@ -198,4 +187,140 @@ raw access to this function, you can use the ``raw()`` method:
$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

@@ -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": "src/" }
},
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev"
"dev-master": "3.2.x-dev"
}
}
}

View File

@@ -45,7 +45,7 @@ if test "$PHP_PIMPLE" != "no"; then
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 LIBSYMBOL=pimple # you most likely want to change this
dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
dnl [

View File

@@ -41,17 +41,31 @@ extern zend_module_entry pimple_module_entry;
#include "TSRM.h"
#endif
#define PIMPLE_VERSION "3.0.2"
#define PIMPLE_VERSION "3.2.2-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);
@@ -93,6 +107,8 @@ typedef struct _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);

View File

@@ -40,6 +40,15 @@
#include "main/php_output.h"
#include "SAPI.h"
static zend_class_entry *pimple_ce_PsrContainerInterface;
static zend_class_entry *pimple_ce_PsrContainerExceptionInterface;
static zend_class_entry *pimple_ce_PsrNotFoundExceptionInterface;
static zend_class_entry *pimple_ce_ExpectedInvokableException;
static zend_class_entry *pimple_ce_FrozenServiceException;
static zend_class_entry *pimple_ce_InvalidServiceIdentifierException;
static zend_class_entry *pimple_ce_UnknownIdentifierException;
static zend_class_entry *pimple_ce;
static zend_object_handlers pimple_object_handlers;
static zend_class_entry *pimple_closure_ce;
@@ -92,6 +101,63 @@ static zend_internal_function pimple_closure_invoker_function;
} \
} while(0);
/* Psr\Container\ContainerInterface */
ZEND_BEGIN_ARG_INFO_EX(arginfo_pimple_PsrContainerInterface_get, 0, 0, 1)
ZEND_ARG_INFO(0, id)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_pimple_PsrContainerInterface_has, 0, 0, 1)
ZEND_ARG_INFO(0, id)
ZEND_END_ARG_INFO()
static const zend_function_entry pimple_ce_PsrContainerInterface_functions[] = {
PHP_ABSTRACT_ME(ContainerInterface, get, arginfo_pimple_PsrContainerInterface_get)
PHP_ABSTRACT_ME(ContainerInterface, has, arginfo_pimple_PsrContainerInterface_has)
PHP_FE_END
};
/* Psr\Container\ContainerExceptionInterface */
static const zend_function_entry pimple_ce_PsrContainerExceptionInterface_functions[] = {
PHP_FE_END
};
/* Psr\Container\NotFoundExceptionInterface */
static const zend_function_entry pimple_ce_PsrNotFoundExceptionInterface_functions[] = {
PHP_FE_END
};
/* Pimple\Exception\FrozenServiceException */
ZEND_BEGIN_ARG_INFO_EX(arginfo_FrozenServiceException___construct, 0, 0, 1)
ZEND_ARG_INFO(0, id)
ZEND_END_ARG_INFO()
static const zend_function_entry pimple_ce_FrozenServiceException_functions[] = {
PHP_ME(FrozenServiceException, __construct, arginfo_FrozenServiceException___construct, ZEND_ACC_PUBLIC)
PHP_FE_END
};
/* Pimple\Exception\InvalidServiceIdentifierException */
ZEND_BEGIN_ARG_INFO_EX(arginfo_InvalidServiceIdentifierException___construct, 0, 0, 1)
ZEND_ARG_INFO(0, id)
ZEND_END_ARG_INFO()
static const zend_function_entry pimple_ce_InvalidServiceIdentifierException_functions[] = {
PHP_ME(InvalidServiceIdentifierException, __construct, arginfo_InvalidServiceIdentifierException___construct, ZEND_ACC_PUBLIC)
PHP_FE_END
};
/* Pimple\Exception\UnknownIdentifierException */
ZEND_BEGIN_ARG_INFO_EX(arginfo_UnknownIdentifierException___construct, 0, 0, 1)
ZEND_ARG_INFO(0, id)
ZEND_END_ARG_INFO()
static const zend_function_entry pimple_ce_UnknownIdentifierException_functions[] = {
PHP_ME(UnknownIdentifierException, __construct, arginfo_UnknownIdentifierException___construct, ZEND_ACC_PUBLIC)
PHP_FE_END
};
/* Pimple\Container */
ZEND_BEGIN_ARG_INFO_EX(arginfo___construct, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, value, 0)
ZEND_END_ARG_INFO()
@@ -138,10 +204,6 @@ ZEND_ARG_OBJ_INFO(0, provider, Pimple\\ServiceProviderInterface, 0)
ZEND_ARG_ARRAY_INFO(0, values, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_serviceprovider_register, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, pimple, Pimple\\Container, 0)
ZEND_END_ARG_INFO()
static const zend_function_entry pimple_ce_functions[] = {
PHP_ME(Pimple, __construct, arginfo___construct, ZEND_ACC_PUBLIC)
PHP_ME(Pimple, factory, arginfo_factory, ZEND_ACC_PUBLIC)
@@ -158,11 +220,54 @@ static const zend_function_entry pimple_ce_functions[] = {
PHP_FE_END
};
/* Pimple\ServiceProviderInterface */
ZEND_BEGIN_ARG_INFO_EX(arginfo_serviceprovider_register, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, pimple, Pimple\\Container, 0)
ZEND_END_ARG_INFO()
static const zend_function_entry pimple_serviceprovider_iface_ce_functions[] = {
PHP_ABSTRACT_ME(ServiceProviderInterface, register, arginfo_serviceprovider_register)
PHP_FE_END
};
/* parent::__construct(sprintf("Something with %s", $arg1)) */
static void pimple_exception_call_parent_constructor(zval *this_ptr, const char *format, const char *arg1 TSRMLS_DC)
{
zend_class_entry *ce = Z_OBJCE_P(this_ptr);
char *message = NULL;
int message_len;
zval *constructor_arg;
message_len = spprintf(&message, 0, format, arg1);
ALLOC_INIT_ZVAL(constructor_arg);
ZVAL_STRINGL(constructor_arg, message, message_len, 1);
zend_call_method_with_1_params(&this_ptr, ce, &ce->parent->constructor, "__construct", NULL, constructor_arg);
efree(message);
zval_ptr_dtor(&constructor_arg);
}
/**
* Pass a single string parameter to exception constructor and throw
*/
static void pimple_throw_exception_string(zend_class_entry *ce, const char *message, zend_uint message_len TSRMLS_DC)
{
zval *exception, *param;
ALLOC_INIT_ZVAL(exception);
object_init_ex(exception, ce);
ALLOC_INIT_ZVAL(param);
ZVAL_STRINGL(param, message, message_len, 1);
zend_call_method_with_1_params(&exception, ce, &ce->constructor, "__construct", NULL, param);
zend_throw_exception_object(exception TSRMLS_CC);
zval_ptr_dtor(&param);
}
static void pimple_closure_free_object_storage(pimple_closure_object *obj TSRMLS_DC)
{
zend_object_std_dtor(&obj->zobj TSRMLS_CC);
@@ -264,7 +369,7 @@ static void pimple_object_write_dimension(zval *object, zval *offset, zval *valu
zend_hash_quick_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void **)&found_value);
if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) {
pimple_free_bucket(&pimple_value);
zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot override frozen service \"%s\".", Z_STRVAL_P(offset));
pimple_throw_exception_string(pimple_ce_FrozenServiceException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
return;
}
if (zend_hash_quick_update(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) {
@@ -284,7 +389,8 @@ static void pimple_object_write_dimension(zval *object, zval *offset, zval *valu
zend_hash_index_find(&pimple_obj->values, index, (void **)&found_value);
if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) {
pimple_free_bucket(&pimple_value);
zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot override frozen service \"%ld\".", index);
convert_to_string(offset);
pimple_throw_exception_string(pimple_ce_FrozenServiceException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
return;
}
if (zend_hash_index_update(&pimple_obj->values, index, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) {
@@ -385,7 +491,8 @@ static zval *pimple_object_read_dimension(zval *object, zval *offset, int type T
switch (Z_TYPE_P(offset)) {
case IS_STRING:
if (zend_symtable_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **)&retval) == FAILURE) {
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
return EG(uninitialized_zval_ptr);
}
break;
@@ -419,7 +526,7 @@ static zval *pimple_object_read_dimension(zval *object, zval *offset, int type T
}
if (zend_hash_index_exists(&pimple_obj->factories, retval->handle_num)) {
/* Service is a factory, call it everytime and never cache its result */
/* Service is a factory, call it every time and never cache its result */
PIMPLE_CALL_CB
Z_DELREF_P(retval_ptr_ptr); /* fetch dim addr will increment refcount */
return retval_ptr_ptr;
@@ -482,6 +589,39 @@ static void pimple_bucket_dtor(pimple_bucket_value *bucket)
pimple_free_bucket(bucket);
}
PHP_METHOD(FrozenServiceException, __construct)
{
char *id = NULL;
int id_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) {
return;
}
pimple_exception_call_parent_constructor(getThis(), "Cannot override frozen service \"%s\".", id TSRMLS_CC);
}
PHP_METHOD(InvalidServiceIdentifierException, __construct)
{
char *id = NULL;
int id_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) {
return;
}
pimple_exception_call_parent_constructor(getThis(), "Identifier \"%s\" does not contain an object definition.", id TSRMLS_CC);
}
PHP_METHOD(UnknownIdentifierException, __construct)
{
char *id = NULL;
int id_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) {
return;
}
pimple_exception_call_parent_constructor(getThis(), "Identifier \"%s\" is not defined.", id TSRMLS_CC);
}
PHP_METHOD(Pimple, protect)
{
zval *protected = NULL;
@@ -494,7 +634,7 @@ PHP_METHOD(Pimple, protect)
if (pimple_zval_is_valid_callback(protected, &bucket TSRMLS_CC) == FAILURE) {
pimple_free_bucket(&bucket);
zend_throw_exception(spl_ce_InvalidArgumentException, "Callable is not a Closure or invokable object.", 0 TSRMLS_CC);
zend_throw_exception(pimple_ce_ExpectedInvokableException, "Callable is not a Closure or invokable object.", 0 TSRMLS_CC);
return;
}
@@ -526,7 +666,7 @@ PHP_METHOD(Pimple, raw)
switch (Z_TYPE_P(offset)) {
case IS_STRING:
if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) {
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
RETURN_NULL();
}
break;
@@ -571,13 +711,20 @@ PHP_METHOD(Pimple, extend)
switch (Z_TYPE_P(offset)) {
case IS_STRING:
if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) {
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
RETURN_NULL();
}
if (value->type != PIMPLE_IS_SERVICE) {
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" does not contain an object definition.", Z_STRVAL_P(offset));
pimple_throw_exception_string(pimple_ce_InvalidServiceIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
RETURN_NULL();
}
if (zend_hash_index_exists(&pobj->protected, value->handle_num)) {
int er = EG(error_reporting);
EG(error_reporting) = 0;
php_error(E_DEPRECATED, "How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure \"%s\" should be protected?", Z_STRVAL_P(offset));
EG(error_reporting) = er;
}
break;
case IS_DOUBLE:
case IS_BOOL:
@@ -588,13 +735,21 @@ PHP_METHOD(Pimple, extend)
index = Z_LVAL_P(offset);
}
if (zend_hash_index_find(&pobj->values, index, (void *)&value) == FAILURE) {
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%ld\" is not defined.", index);
convert_to_string(offset);
pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
RETURN_NULL();
}
if (value->type != PIMPLE_IS_SERVICE) {
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%ld\" does not contain an object definition.", index);
convert_to_string(offset);
pimple_throw_exception_string(pimple_ce_InvalidServiceIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
RETURN_NULL();
}
if (zend_hash_index_exists(&pobj->protected, value->handle_num)) {
int er = EG(error_reporting);
EG(error_reporting) = 0;
php_error(E_DEPRECATED, "How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure \"%ld\" should be protected?", index);
EG(error_reporting) = er;
}
break;
case IS_NULL:
default:
@@ -603,7 +758,7 @@ PHP_METHOD(Pimple, extend)
if (pimple_zval_is_valid_callback(callable, &bucket TSRMLS_CC) == FAILURE) {
pimple_free_bucket(&bucket);
zend_throw_exception(spl_ce_InvalidArgumentException, "Extension service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
zend_throw_exception(pimple_ce_ExpectedInvokableException, "Extension service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
RETURN_NULL();
}
pimple_free_bucket(&bucket);
@@ -676,7 +831,7 @@ PHP_METHOD(Pimple, factory)
if (pimple_zval_is_valid_callback(factory, &bucket TSRMLS_CC) == FAILURE) {
pimple_free_bucket(&bucket);
zend_throw_exception(spl_ce_InvalidArgumentException, "Service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
zend_throw_exception(pimple_ce_ExpectedInvokableException, "Service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
return;
}
@@ -782,7 +937,13 @@ PHP_METHOD(Pimple, __construct)
zend_uint str_length;
ulong num_index;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &values) == FAILURE || !values) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &values) == FAILURE) {
return;
}
PIMPLE_DEPRECATE
if (!values) {
return;
}
@@ -857,7 +1018,38 @@ PHP_METHOD(PimpleClosure, invoker)
PHP_MINIT_FUNCTION(pimple)
{
zend_class_entry tmp_ce_PsrContainerInterface, tmp_ce_PsrContainerExceptionInterface, tmp_ce_PsrNotFoundExceptionInterface;
zend_class_entry tmp_ce_ExpectedInvokableException, tmp_ce_FrozenServiceException, tmp_ce_InvalidServiceIdentifierException, tmp_ce_UnknownIdentifierException;
zend_class_entry tmp_pimple_ce, tmp_pimple_closure_ce, tmp_pimple_serviceprovider_iface_ce;
/* Psr\Container namespace */
INIT_NS_CLASS_ENTRY(tmp_ce_PsrContainerInterface, PSR_CONTAINER_NS, "ContainerInterface", pimple_ce_PsrContainerInterface_functions);
INIT_NS_CLASS_ENTRY(tmp_ce_PsrContainerExceptionInterface, PSR_CONTAINER_NS, "ContainerExceptionInterface", pimple_ce_PsrContainerExceptionInterface_functions);
INIT_NS_CLASS_ENTRY(tmp_ce_PsrNotFoundExceptionInterface, PSR_CONTAINER_NS, "NotFoundExceptionInterface", pimple_ce_PsrNotFoundExceptionInterface_functions);
pimple_ce_PsrContainerInterface = zend_register_internal_interface(&tmp_ce_PsrContainerInterface TSRMLS_CC);
pimple_ce_PsrContainerExceptionInterface = zend_register_internal_interface(&tmp_ce_PsrContainerExceptionInterface TSRMLS_CC);
pimple_ce_PsrNotFoundExceptionInterface = zend_register_internal_interface(&tmp_ce_PsrNotFoundExceptionInterface TSRMLS_CC);
zend_class_implements(pimple_ce_PsrNotFoundExceptionInterface TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
/* Pimple\Exception namespace */
INIT_NS_CLASS_ENTRY(tmp_ce_ExpectedInvokableException, PIMPLE_EXCEPTION_NS, "ExpectedInvokableException", NULL);
INIT_NS_CLASS_ENTRY(tmp_ce_FrozenServiceException, PIMPLE_EXCEPTION_NS, "FrozenServiceException", pimple_ce_FrozenServiceException_functions);
INIT_NS_CLASS_ENTRY(tmp_ce_InvalidServiceIdentifierException, PIMPLE_EXCEPTION_NS, "InvalidServiceIdentifierException", pimple_ce_InvalidServiceIdentifierException_functions);
INIT_NS_CLASS_ENTRY(tmp_ce_UnknownIdentifierException, PIMPLE_EXCEPTION_NS, "UnknownIdentifierException", pimple_ce_UnknownIdentifierException_functions);
pimple_ce_ExpectedInvokableException = zend_register_internal_class_ex(&tmp_ce_ExpectedInvokableException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
pimple_ce_FrozenServiceException = zend_register_internal_class_ex(&tmp_ce_FrozenServiceException, spl_ce_RuntimeException, NULL TSRMLS_CC);
pimple_ce_InvalidServiceIdentifierException = zend_register_internal_class_ex(&tmp_ce_InvalidServiceIdentifierException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
pimple_ce_UnknownIdentifierException = zend_register_internal_class_ex(&tmp_ce_UnknownIdentifierException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
zend_class_implements(pimple_ce_ExpectedInvokableException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
zend_class_implements(pimple_ce_FrozenServiceException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
zend_class_implements(pimple_ce_InvalidServiceIdentifierException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
zend_class_implements(pimple_ce_UnknownIdentifierException TSRMLS_CC, 1, pimple_ce_PsrNotFoundExceptionInterface);
/* Pimple namespace */
INIT_NS_CLASS_ENTRY(tmp_pimple_ce, PIMPLE_NS, "Container", pimple_ce_functions);
INIT_NS_CLASS_ENTRY(tmp_pimple_closure_ce, PIMPLE_NS, "ContainerClosure", NULL);
INIT_NS_CLASS_ENTRY(tmp_pimple_serviceprovider_iface_ce, PIMPLE_NS, "ServiceProviderInterface", pimple_serviceprovider_iface_ce_functions);

View File

@@ -26,10 +26,15 @@
namespace Pimple;
use Pimple\Exception\ExpectedInvokableException;
use Pimple\Exception\FrozenServiceException;
use Pimple\Exception\InvalidServiceIdentifierException;
use Pimple\Exception\UnknownIdentifierException;
/**
* Container main class.
*
* @author Fabien Potencier
* @author Fabien Potencier
*/
class Container implements \ArrayAccess
{
@@ -41,11 +46,11 @@ class Container implements \ArrayAccess
private $keys = array();
/**
* Instantiate the container.
* Instantiates the container.
*
* Objects and parameters can be passed as argument to the constructor.
*
* @param array $values The parameters or objects.
* @param array $values The parameters or objects
*/
public function __construct(array $values = array())
{
@@ -69,12 +74,12 @@ class Container implements \ArrayAccess
* @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 \RuntimeException Prevent override of a frozen service
* @throws FrozenServiceException Prevent override of a frozen service
*/
public function offsetSet($id, $value)
{
if (isset($this->frozen[$id])) {
throw new \RuntimeException(sprintf('Cannot override frozen service "%s".', $id));
throw new FrozenServiceException($id);
}
$this->values[$id] = $value;
@@ -88,12 +93,12 @@ class Container implements \ArrayAccess
*
* @return mixed The value of the parameter or an object
*
* @throws \InvalidArgumentException if the identifier is not defined
* @throws UnknownIdentifierException If the identifier is not defined
*/
public function offsetGet($id)
{
if (!isset($this->keys[$id])) {
throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
throw new UnknownIdentifierException($id);
}
if (
@@ -153,12 +158,12 @@ class Container implements \ArrayAccess
*
* @return callable The passed callable
*
* @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
* @throws ExpectedInvokableException Service definition has to be a closure or an invokable object
*/
public function factory($callable)
{
if (!method_exists($callable, '__invoke')) {
throw new \InvalidArgumentException('Service definition is not a Closure or invokable object.');
throw new ExpectedInvokableException('Service definition is not a Closure or invokable object.');
}
$this->factories->attach($callable);
@@ -175,12 +180,12 @@ class Container implements \ArrayAccess
*
* @return callable The passed callable
*
* @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
* @throws ExpectedInvokableException Service definition has to be a closure or an invokable object
*/
public function protect($callable)
{
if (!method_exists($callable, '__invoke')) {
throw new \InvalidArgumentException('Callable is not a Closure or invokable object.');
throw new ExpectedInvokableException('Callable is not a Closure or invokable object.');
}
$this->protected->attach($callable);
@@ -195,12 +200,12 @@ class Container implements \ArrayAccess
*
* @return mixed The value of the parameter or the closure defining an object
*
* @throws \InvalidArgumentException if the identifier is not defined
* @throws UnknownIdentifierException If the identifier is not defined
*/
public function raw($id)
{
if (!isset($this->keys[$id])) {
throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
throw new UnknownIdentifierException($id);
}
if (isset($this->raw[$id])) {
@@ -221,20 +226,31 @@ class Container implements \ArrayAccess
*
* @return callable The wrapped callable
*
* @throws \InvalidArgumentException if the identifier is not defined or not a service definition
* @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 \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $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 \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id));
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 \InvalidArgumentException('Extension service definition is not a Closure or invokable object.');
throw new ExpectedInvokableException('Extension service definition is not a Closure or invokable object.');
}
$factory = $this->values[$id];

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

@@ -29,7 +29,7 @@ namespace Pimple\Tests;
use Pimple\Container;
/**
* @author Igor Wiedler <igor@wiedler.ch>
* @author Igor Wiedler <igor@wiedler.ch>
*/
class PimpleTest extends \PHPUnit_Framework_TestCase
{
@@ -106,7 +106,7 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
}
/**
* @expectedException \InvalidArgumentException
* @expectedException \Pimple\Exception\UnknownIdentifierException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testOffsetGetValidatesKeyIsPresent()
@@ -115,6 +115,17 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
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();
@@ -187,11 +198,11 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
public function testFluentRegister()
{
$pimple = new Container();
$this->assertSame($pimple, $pimple->register($this->getMock('Pimple\ServiceProviderInterface')));
$this->assertSame($pimple, $pimple->register($this->getMockBuilder('Pimple\ServiceProviderInterface')->getMock()));
}
/**
* @expectedException \InvalidArgumentException
* @expectedException \Pimple\Exception\UnknownIdentifierException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testRawValidatesKeyIsPresent()
@@ -200,6 +211,17 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
$pimple->raw('foo');
}
/**
* @group legacy
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testLegacyRawValidatesKeyIsPresent()
{
$pimple = new Container();
$pimple->raw('foo');
}
/**
* @dataProvider serviceDefinitionProvider
*/
@@ -251,7 +273,7 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
}
/**
* @expectedException \InvalidArgumentException
* @expectedException \Pimple\Exception\UnknownIdentifierException
* @expectedExceptionMessage Identifier "foo" is not defined.
*/
public function testExtendValidatesKeyIsPresent()
@@ -260,6 +282,17 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
$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();
@@ -289,7 +322,7 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
/**
* @dataProvider badServiceDefinitionProvider
* @expectedException \InvalidArgumentException
* @expectedException \Pimple\Exception\ExpectedInvokableException
* @expectedExceptionMessage Service definition is not a Closure or invokable object.
*/
public function testFactoryFailsForInvalidServiceDefinitions($service)
@@ -299,8 +332,20 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
}
/**
* @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)
@@ -310,8 +355,20 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
}
/**
* @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)
@@ -322,8 +379,39 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
}
/**
* @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)
@@ -333,6 +421,49 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
$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.
*/
@@ -375,7 +506,7 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
}
/**
* @expectedException \RuntimeException
* @expectedException \Pimple\Exception\FrozenServiceException
* @expectedExceptionMessage Cannot override frozen service "foo".
*/
public function testOverridingServiceAfterFreeze()
@@ -391,6 +522,24 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
};
}
/**
* @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();

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));
}
}

Submodule system/vendor/slim/flash updated: 3c9a26b316...9aaff5fded

View File

@@ -52,7 +52,7 @@ class App
*
* @var string
*/
const VERSION = '3.8.1';
const VERSION = '3.9.0';
/**
* Container
@@ -388,6 +388,16 @@ class App
{
// Send response
if (!headers_sent()) {
// Headers
foreach ($response->getHeaders() as $name => $values) {
foreach ($values as $value) {
header(sprintf('%s: %s', $name, $value), false);
}
}
// Set the status _after_ the headers, because of PHP's "helpful" behavior with location headers.
// See https://github.com/slimphp/Slim/issues/1730
// Status
header(sprintf(
'HTTP/%s %s %s',
@@ -395,13 +405,6 @@ class App
$response->getStatusCode(),
$response->getReasonPhrase()
));
// Headers
foreach ($response->getHeaders() as $name => $values) {
foreach ($values as $value) {
header(sprintf('%s: %s', $name, $value), false);
}
}
}
// Body

View File

@@ -34,7 +34,7 @@ final class CallableResolver implements CallableResolverInterface
}
/**
* Resolve toResolve into a closure that that the router can dispatch.
* Resolve toResolve into a closure so that the router can dispatch.
*
* If toResolve is of the format 'class:method', then try to extract 'class'
* from the container otherwise instantiate it and then dispatch 'method'.

View File

@@ -17,7 +17,7 @@ use Slim\Exception\ContainerException as SlimContainerException;
/**
* Slim's default DI container is Pimple.
*
* Slim\App expects a container that implements Interop\Container\ContainerInterface
* Slim\App expects a container that implements Psr\Container\ContainerInterface
* with these service keys configured and ready for use:
*
* - settings: an array or instance of \ArrayAccess
@@ -101,7 +101,7 @@ class Container extends PimpleContainer implements ContainerInterface
}
/********************************************************************************
* Methods to satisfy Interop\Container\ContainerInterface
* Methods to satisfy Psr\Container\ContainerInterface
*******************************************************************************/
/**

View File

@@ -152,7 +152,10 @@ class DefaultServicesProvider
* @return callable
*/
$container['errorHandler'] = function ($container) {
return new Error($container->get('settings')['displayErrorDetails']);
return new Error(
$container->get('settings')['displayErrorDetails'],
$container->get('settings')['outputBuffering']
);
};
}

View File

@@ -18,14 +18,20 @@ abstract class AbstractError extends AbstractHandler
*/
protected $displayErrorDetails;
/**
* @var bool|string
*/
protected $outputBuffering;
/**
* Constructor
*
* @param bool $displayErrorDetails Set to true to display full details
*/
public function __construct($displayErrorDetails = false)
public function __construct($displayErrorDetails = false, $outputBuffering = false)
{
$this->displayErrorDetails = (bool) $displayErrorDetails;
$this->outputBuffering = $outputBuffering;
}
/**

View File

@@ -55,7 +55,19 @@ class Error extends AbstractError
$this->writeToErrorLog($exception);
$body = new Body(fopen('php://temp', 'r+'));
$body->write($output);
if ($this->outputBuffering === 'prepend') {
// prepend output buffer content
$body->write(ob_get_clean() . $output);
} elseif ($this->outputBuffering === 'append') {
// append output buffer content
$body->write($output . ob_get_clean());
} else {
// outputBuffering is false or some other unknown setting
// delete anything in the output buffer.
ob_get_clean();
$body->write($output);
}
return $response
->withStatus(500)

View File

@@ -36,7 +36,7 @@ class NotAllowed extends AbstractHandler
if ($request->getMethod() === 'OPTIONS') {
$status = 200;
$contentType = 'text/plain';
$output = $this->renderPlainNotAllowedMessage($methods);
$output = $this->renderPlainOptionsMessage($methods);
} else {
$status = 405;
$contentType = $this->determineContentType($request);
@@ -70,12 +70,12 @@ class NotAllowed extends AbstractHandler
}
/**
* Render PLAIN not allowed message
* Render PLAIN message for OPTIONS response
*
* @param array $methods
* @return string
*/
protected function renderPlainNotAllowedMessage($methods)
protected function renderPlainOptionsMessage($methods)
{
$allow = implode(', ', $methods);

View File

@@ -32,23 +32,28 @@ class NotFound extends AbstractHandler
*/
public function __invoke(ServerRequestInterface $request, ResponseInterface $response)
{
$contentType = $this->determineContentType($request);
switch ($contentType) {
case 'application/json':
$output = $this->renderJsonNotFoundOutput();
break;
if ($request->getMethod() === 'OPTIONS') {
$contentType = 'text/plain';
$output = $this->renderPlainNotFoundOutput();
} else {
$contentType = $this->determineContentType($request);
switch ($contentType) {
case 'application/json':
$output = $this->renderJsonNotFoundOutput();
break;
case 'text/xml':
case 'application/xml':
$output = $this->renderXmlNotFoundOutput();
break;
case 'text/xml':
case 'application/xml':
$output = $this->renderXmlNotFoundOutput();
break;
case 'text/html':
$output = $this->renderHtmlNotFoundOutput($request);
break;
case 'text/html':
$output = $this->renderHtmlNotFoundOutput($request);
break;
default:
throw new UnexpectedValueException('Cannot render unknown content type ' . $contentType);
default:
throw new UnexpectedValueException('Cannot render unknown content type ' . $contentType);
}
}
$body = new Body(fopen('php://temp', 'r+'));
@@ -59,6 +64,16 @@ class NotFound extends AbstractHandler
->withBody($body);
}
/**
* Render plain not found message
*
* @return ResponseInterface
*/
protected function renderPlainNotFoundOutput()
{
return 'Not found';
}
/**
* Return a response for application/json content not found
*

View File

@@ -29,14 +29,25 @@ class Environment extends Collection implements EnvironmentInterface
*/
public static function mock(array $userData = [])
{
//Validates if default protocol is HTTPS to set default port 443
if ((isset($userData['HTTPS']) && $userData['HTTPS'] !== 'off') ||
((isset($userData['REQUEST_SCHEME']) && $userData['REQUEST_SCHEME'] === 'https'))) {
$defscheme = 'https';
$defport = 443;
} else {
$defscheme = 'http';
$defport = 80;
}
$data = array_merge([
'SERVER_PROTOCOL' => 'HTTP/1.1',
'REQUEST_METHOD' => 'GET',
'REQUEST_SCHEME' => $defscheme,
'SCRIPT_NAME' => '',
'REQUEST_URI' => '',
'QUERY_STRING' => '',
'SERVER_NAME' => 'localhost',
'SERVER_PORT' => 80,
'SERVER_PORT' => $defport,
'HTTP_HOST' => 'localhost',
'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'HTTP_ACCEPT_LANGUAGE' => 'en-US,en;q=0.8',

View File

@@ -77,7 +77,7 @@ class Headers extends Collection implements HeadersInterface
{
$authorization = $environment->get('HTTP_AUTHORIZATION');
if (null === $authorization && is_callable('getallheaders')) {
if (empty($authorization) && is_callable('getallheaders')) {
$headers = getallheaders();
$headers = array_change_key_case($headers, CASE_LOWER);
if (isset($headers['authorization'])) {

View File

@@ -40,6 +40,7 @@ abstract class Message implements MessageInterface
'1.0' => true,
'1.1' => true,
'2.0' => true,
'2' => true,
];
/**

View File

@@ -17,7 +17,6 @@ use Psr\Http\Message\UriInterface;
use Psr\Http\Message\StreamInterface;
use Slim\Collection;
use Slim\Exception\InvalidMethodException;
use Slim\Exception\MethodNotAllowedException;
use Slim\Interfaces\Http\HeadersInterface;
/**
@@ -114,6 +113,7 @@ class Request extends Message implements ServerRequestInterface
* Valid request methods
*
* @var string[]
* @deprecated
*/
protected $validMethods = [
'CONNECT' => 1,
@@ -349,7 +349,7 @@ class Request extends Message implements ServerRequestInterface
}
$method = strtoupper($method);
if (!isset($this->validMethods[$method])) {
if (preg_match("/^[!#$%&'*+.^_`|~0-9a-z-]+$/i", $method) !== 1) {
throw new InvalidMethodException($this, $method);
}
@@ -1201,9 +1201,10 @@ class Request extends Message implements ServerRequestInterface
*
* Note: This method is not part of the PSR-7 standard.
*
* @return array
* @param array|null $only list the keys to retrieve.
* @return array|null
*/
public function getParams()
public function getParams(array $only = null)
{
$params = $this->getQueryParams();
$postParams = $this->getParsedBody();
@@ -1211,6 +1212,16 @@ class Request extends Message implements ServerRequestInterface
$params = array_merge($params, (array)$postParams);
}
if ($only) {
$onlyParams = [];
foreach ($only as $key) {
if (array_key_exists($key, $params)) {
$onlyParams[$key] = $params[$key];
}
}
return $onlyParams;
}
return $params;
}
}

View File

@@ -185,7 +185,7 @@ class Uri implements UriInterface
if (preg_match('/^(\[[a-fA-F0-9:.]+\])(:\d+)?\z/', $host, $matches)) {
$host = $matches[1];
if ($matches[2]) {
if (isset($matches[2])) {
$port = (int) substr($matches[2], 1);
}
} else {
@@ -378,12 +378,31 @@ class Uri implements UriInterface
public function withUserInfo($user, $password = null)
{
$clone = clone $this;
$clone->user = $user;
$clone->password = $password ? $password : '';
$clone->user = $this->filterUserInfo($user);
if ($clone->user) {
$clone->password = $password ? $this->filterUserInfo($password) : '';
}
return $clone;
}
/**
* Filters the user info string.
*
* @param string $query The raw uri query string.
* @return string The percent-encoded query string.
*/
protected function filterUserInfo($query)
{
return preg_replace_callback(
'/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=]+|%(?![A-Fa-f0-9]{2}))/u',
function ($match) {
return rawurlencode($match[0]);
},
$query
);
}
/**
* Retrieve the host component of the URI.
*

View File

@@ -71,6 +71,17 @@ interface RouteInterface
*/
public function setArguments(array $arguments);
/**
* Set output buffering mode
*
* One of: false, 'prepend' or 'append'
*
* @param boolean|string $mode
*
* @throws InvalidArgumentException If an unknown buffering mode is specified
*/
public function setOutputBuffering($mode);
/**
* Set route name
*

View File

@@ -9,8 +9,6 @@
namespace Slim;
use RuntimeException;
use SplStack;
use SplDoublyLinkedList;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use UnexpectedValueException;
@@ -25,12 +23,11 @@ use UnexpectedValueException;
trait MiddlewareAwareTrait
{
/**
* Middleware call stack
* Tip of the middleware call stack
*
* @var \SplStack
* @link http://php.net/manual/class.splstack.php
* @var callable
*/
protected $stack;
protected $tip;
/**
* Middleware stack lock
@@ -59,11 +56,11 @@ trait MiddlewareAwareTrait
throw new RuntimeException('Middleware cant be added once the stack is dequeuing');
}
if (is_null($this->stack)) {
if (is_null($this->tip)) {
$this->seedMiddlewareStack();
}
$next = $this->stack->top();
$this->stack[] = function (
$next = $this->tip;
$this->tip = function (
ServerRequestInterface $request,
ResponseInterface $response
) use (
@@ -92,15 +89,13 @@ trait MiddlewareAwareTrait
*/
protected function seedMiddlewareStack(callable $kernel = null)
{
if (!is_null($this->stack)) {
if (!is_null($this->tip)) {
throw new RuntimeException('MiddlewareStack can only be seeded once.');
}
if ($kernel === null) {
$kernel = $this;
}
$this->stack = new SplStack;
$this->stack->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
$this->stack[] = $kernel;
$this->tip = $kernel;
}
/**
@@ -113,11 +108,11 @@ trait MiddlewareAwareTrait
*/
public function callMiddlewareStack(ServerRequestInterface $request, ResponseInterface $response)
{
if (is_null($this->stack)) {
if (is_null($this->tip)) {
$this->seedMiddlewareStack();
}
/** @var callable $start */
$start = $this->stack->top();
$start = $this->tip;
$this->middlewareLock = true;
$response = $start($request, $response);
$this->middlewareLock = false;

View File

@@ -345,11 +345,9 @@ class Route extends Routable implements RouteInterface
$output = ob_get_clean();
// @codeCoverageIgnoreStart
} catch (Throwable $e) {
ob_end_clean();
throw $e;
// @codeCoverageIgnoreEnd
} catch (Exception $e) {
ob_end_clean();
throw $e;
}
}

View File

@@ -33,7 +33,7 @@ class RouteGroup extends Routable implements RouteGroupInterface
/**
* Invoke the group to register any Routable objects within it.
*
* @param App $app The App to bind the callable to.
* @param App $app The App instance to bind/pass to the group callable
*/
public function __invoke(App $app = null)
{
@@ -42,6 +42,6 @@ class RouteGroup extends Routable implements RouteGroupInterface
$callable = $callable->bindTo($app);
}
$callable();
$callable($app);
}
}

Submodule system/vendor/slim/twig-view updated: a743ac45e2...f6ff5ec3a2

View File

@@ -45,8 +45,8 @@ class Dumper
* @param mixed $input The PHP value
* @param int $inline The level where you switch to inline YAML
* @param int $indent The level of indentation (used internally)
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport true if object support is enabled, false otherwise
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
*
* @return string The YAML representation of the PHP value
*/

View File

@@ -24,8 +24,6 @@ class ParseException extends RuntimeException
private $rawMessage;
/**
* Constructor.
*
* @param string $message The error message
* @param int $parsedLine The line where the error occurred
* @param string|null $snippet The snippet of code near the problem

View File

@@ -31,9 +31,9 @@ class Inline
* Converts a YAML string to a PHP value.
*
* @param string $value A YAML string
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport true if object support is enabled, false otherwise
* @param bool $objectForMap true if maps should return a stdClass instead of array()
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
* @param bool $objectForMap True if maps should return a stdClass instead of array()
* @param array $references Mapping of variable names to values
*
* @return mixed A PHP value
@@ -87,8 +87,8 @@ class Inline
* Dumps a given PHP variable to a YAML string.
*
* @param mixed $value The PHP variable to convert
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport true if object support is enabled, false otherwise
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
*
* @return string The YAML string representing the PHP value
*
@@ -183,8 +183,8 @@ class Inline
* Dumps a PHP array to a YAML string.
*
* @param array $value The PHP array to dump
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport true if object support is enabled, false otherwise
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
*
* @return string The YAML string representing the PHP array
*/
@@ -491,7 +491,7 @@ class Inline
case 'false' === $scalarLower:
return false;
// Optimise for returning strings.
case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]):
case '+' === $scalar[0] || '-' === $scalar[0] || '.' === $scalar[0] || '!' === $scalar[0] || is_numeric($scalar[0]):
switch (true) {
case 0 === strpos($scalar, '!str'):
return (string) substr($scalar, 5);
@@ -547,6 +547,7 @@ class Inline
return $time;
}
// no break
default:
return (string) $scalar;
}

View File

@@ -34,8 +34,6 @@ class Parser
private $locallySkippedLineNumbers = array();
/**
* Constructor.
*
* @param int $offset The offset of YAML document (used for line numbers in error messages)
* @param int|null $totalNumberOfLines The overall number of lines being parsed
* @param int[] $skippedLineNumbers Number of comment lines that have been skipped by the parser
@@ -51,9 +49,9 @@ class Parser
* Parses a YAML string to a PHP value.
*
* @param string $value A YAML string
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport true if object support is enabled, false otherwise
* @param bool $objectForMap true if maps should return a stdClass instead of array()
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
* @param bool $objectForMap True if maps should return a stdClass instead of array()
*
* @return mixed A PHP value
*
@@ -183,7 +181,7 @@ class Parser
$key = (string) $key;
}
if ('<<' === $key) {
if ('<<' === $key && (!isset($values['value']) || !self::preg_match('#^&(?P<ref>[^ ]+)#u', $values['value'], $refMatches))) {
$mergeNode = true;
$allowOverwrite = true;
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
@@ -200,7 +198,7 @@ class Parser
$data += $refValue; // array union
} else {
if (isset($values['value']) && $values['value'] !== '') {
if (isset($values['value']) && '' !== $values['value']) {
$value = $values['value'];
} else {
$value = $this->getNextEmbedBlock();
@@ -228,14 +226,14 @@ class Parser
$data += $parsed; // array union
}
}
} elseif (isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
} elseif ('<<' !== $key && isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
$isRef = $matches['ref'];
$values['value'] = $matches['value'];
}
if ($mergeNode) {
// Merge keys
} elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
} elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#') || '<<' === $key) {
// hash
// if next line is less indented or equal, then it means that the current value is null
if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
@@ -246,9 +244,13 @@ class Parser
}
} else {
$value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
// Spec: Keys MUST be unique; first one wins.
// But overwriting is allowed when a merge node is used in current block.
if ($allowOverwrite || !isset($data[$key])) {
if ('<<' === $key) {
$this->refs[$refMatches['ref']] = $value;
$data += $value;
} elseif ($allowOverwrite || !isset($data[$key])) {
// Spec: Keys MUST be unique; first one wins.
// But overwriting is allowed when a merge node is used in current block.
$data[$key] = $value;
}
}
@@ -412,7 +414,7 @@ class Parser
$indent = $this->getCurrentLineIndentation();
// terminate all block scalars that are more indented than the current line
if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && trim($this->currentLine) !== '') {
if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && '' !== trim($this->currentLine)) {
foreach ($blockScalarIndentations as $key => $blockScalarIndentation) {
if ($blockScalarIndentation >= $this->getCurrentLineIndentation()) {
unset($blockScalarIndentations[$key]);
@@ -501,7 +503,7 @@ class Parser
* @param string $value A YAML value
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
* @param bool $objectForMap true if maps should return a stdClass instead of array()
* @param bool $objectForMap True if maps should return a stdClass instead of array()
* @param string $context The parser context (either sequence or mapping)
*
* @return mixed A PHP value
@@ -715,7 +717,7 @@ class Parser
//checking explicitly the first char of the trim is faster than loops or strpos
$ltrimmedLine = ltrim($this->currentLine, ' ');
return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#';
return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0];
}
private function isCurrentLineLastLineInDocument()
@@ -741,7 +743,7 @@ class Parser
// remove leading comments
$trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
if ($count == 1) {
if (1 == $count) {
// items have been removed, update the offset
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
$value = $trimmedValue;
@@ -749,7 +751,7 @@ class Parser
// remove start of the document marker (---)
$trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
if ($count == 1) {
if (1 == $count) {
// items have been removed, update the offset
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
$value = $trimmedValue;

View File

@@ -1252,6 +1252,34 @@ bar:
YAML;
$this->parser->parse($yaml);
}
public function testParseReferencesOnMergeKeys()
{
$yaml = <<<YAML
mergekeyrefdef:
a: foo
<<: &quux
b: bar
c: baz
mergekeyderef:
d: quux
<<: *quux
YAML;
$expected = array(
'mergekeyrefdef' => array(
'a' => 'foo',
'b' => 'bar',
'c' => 'baz',
),
'mergekeyderef' => array(
'd' => 'quux',
'b' => 'bar',
'c' => 'baz',
),
);
$this->assertSame($expected, $this->parser->parse($yaml));
}
}
class B

View File

@@ -48,7 +48,7 @@ class Yaml
{
// if input is a file, process it
$file = '';
if (strpos($input, "\n") === false && is_file($input)) {
if (false === strpos($input, "\n") && is_file($input)) {
@trigger_error('The ability to pass file names to the '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.', E_USER_DEPRECATED);
if (false === is_readable($input)) {
@@ -81,8 +81,8 @@ class Yaml
* @param mixed $input The PHP value
* @param int $inline The level where you switch to inline YAML
* @param int $indent The amount of spaces to use for indentation of nested nodes
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport true if object support is enabled, false otherwise
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
*
* @return string A YAML string representing the original PHP value
*/

View File

@@ -9,6 +9,7 @@ return PhpCsFixer\Config::create()
'no_unreachable_default_argument_value' => false,
'braces' => array('allow_single_line_closure' => true),
'heredoc_to_nowdoc' => false,
'dir_constant' => false,
))
->setRiskyAllowed(true)
->setFinder(PhpCsFixer\Finder::create()->in(__DIR__))

View File

@@ -21,7 +21,8 @@ env:
- TWIG_EXT=yes
before_install:
- phpenv config-rm xdebug.ini
# turn off XDebug
- phpenv config-rm xdebug.ini || return 0
install:
- travis_retry composer install

View File

@@ -1,3 +1,15 @@
* 1.35.0 (2017-09-27)
* added Twig_Profiler_Profile::reset()
* fixed use TokenParser to return an empty Node
* added RuntimeExtensionInterface
* added circular reference detection when loading templates
* 1.34.4 (2017-07-04)
* added support for runtime loaders in IntegrationTestCase
* fixed deprecation when using Twig_Profiler_Dumper_Html
* 1.34.3 (2017-06-07)
* fixed namespaces introduction
@@ -137,7 +149,7 @@
* fixed reserved keywords (forbids true, false, null and none keywords for variables names)
* fixed support for PHP7 (Throwable support)
* marked the following methods as being internals on Twig_Environment:
* marked the following methods as being internals on Twig_Environment:
getFunctions(), getFilters(), getTests(), getFunction(), getFilter(), getTest(),
getTokenParsers(), getTags(), getNodeVisitors(), getUnaryOperators(), getBinaryOperators(),
getFunctions(), getFilters(), getGlobals(), initGlobals(), initExtensions(), and initExtension()
@@ -221,7 +233,7 @@
* fixed limited RCEs when in sandbox mode
* deprecated Twig_Template::getEnvironment()
* deprecated the _self variable for usage outside of the from and import tags
* added Twig_BaseNodeVisitor to ease the compatibility of node visitors
* added Twig_BaseNodeVisitor to ease the compatibility of node visitors
between 1.x and 2.x
* 1.19.0 (2015-07-31)

View File

@@ -44,7 +44,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.34-dev"
"dev-master": "1.35-dev"
}
}
}

View File

@@ -24,7 +24,7 @@ Twig's :ref:`precedence of operators <twig-expressions>`:
.. code-block:: jinja
{{ -9800.333|number_format(2, '.', ',') }} {# outputs : -9 #}
{{ (-9800.333)|number_format(2, '.', ',') }} {# outputs : -9.800,33 #}
{{ (-9800.333)|number_format(2, '.', ',') }} {# outputs : -9,800.33 #}
If no formatting options are provided then Twig will use the default formatting
options of:

View File

@@ -128,7 +128,7 @@ using)::
{
// line 1
echo "Hello ";
echo twig_escape_filter($this->env, isset($context["name"]) ? $context["name"] : null), "html", null, true);
echo twig_escape_filter($this->env, (isset($context["name"]) ? $context["name"] : null), "html", null, true);
}
// some more code

View File

@@ -611,7 +611,8 @@ exist:
{ 2: 'foo', 4: 'bar' }
{# keys as expressions (the expression must be enclosed into parentheses) -- as of Twig 1.5 #}
{ (1 + 1): 'foo', (a ~ 'b'): 'bar' }
{% set foo = 'foo' %}
{ (foo): 'foo', (1 + 1): 'bar', (foo ~ 'b'): 'baz' }
* ``true`` / ``false``: ``true`` represents the true value, ``false``
represents the false value.

View File

@@ -15,7 +15,7 @@
#ifndef PHP_TWIG_H
#define PHP_TWIG_H
#define PHP_TWIG_VERSION "1.34.3"
#define PHP_TWIG_VERSION "1.35.0"
#include "php.h"

View File

@@ -16,11 +16,11 @@
*/
class Twig_Environment
{
const VERSION = '1.34.3';
const VERSION_ID = 13403;
const VERSION = '1.35.0';
const VERSION_ID = 13500;
const MAJOR_VERSION = 1;
const MINOR_VERSION = 34;
const RELEASE_VERSION = 3;
const MINOR_VERSION = 35;
const RELEASE_VERSION = 0;
const EXTRA_VERSION = '';
protected $charset;
@@ -58,6 +58,7 @@ class Twig_Environment
private $runtimeLoaders = array();
private $runtimes = array();
private $optionsHash;
private $loading = array();
/**
* Constructor.
@@ -382,6 +383,10 @@ class Twig_Environment
*
* @param string|Twig_TemplateWrapper|Twig_Template $name The template name
*
* @throws Twig_Error_Loader When the template cannot be found
* @throws Twig_Error_Runtime When a previously generated cache is corrupted
* @throws Twig_Error_Syntax When an error occurred during compilation
*
* @return Twig_TemplateWrapper
*/
public function load($name)
@@ -472,7 +477,22 @@ class Twig_Environment
$this->initRuntime();
}
return $this->loadedTemplates[$cls] = new $cls($this);
if (isset($this->loading[$cls])) {
throw new Twig_Error_Runtime(sprintf('Circular reference detected for Twig template "%s", path: %s.', $name, implode(' -> ', array_merge($this->loading, array($name)))));
}
$this->loading[$cls] = $name;
try {
$this->loadedTemplates[$cls] = new $cls($this);
unset($this->loading[$cls]);
} catch (\Exception $e) {
unset($this->loading[$cls]);
throw $e;
}
return $this->loadedTemplates[$cls];
}
/**

View File

@@ -0,0 +1,62 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @author Fabien Potencier <fabien@symfony.com>
*/
abstract class Twig_Profiler_Dumper_Base
{
private $root;
public function dump(Twig_Profiler_Profile $profile)
{
return $this->dumpProfile($profile);
}
abstract protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix);
abstract protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix);
abstract protected function formatTime(Twig_Profiler_Profile $profile, $percent);
private function dumpProfile(Twig_Profiler_Profile $profile, $prefix = '', $sibling = false)
{
if ($profile->isRoot()) {
$this->root = $profile->getDuration();
$start = $profile->getName();
} else {
if ($profile->isTemplate()) {
$start = $this->formatTemplate($profile, $prefix);
} else {
$start = $this->formatNonTemplate($profile, $prefix);
}
$prefix .= $sibling ? '│ ' : ' ';
}
$percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0;
if ($profile->getDuration() * 1000 < 1) {
$str = $start."\n";
} else {
$str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent));
}
$nCount = count($profile->getProfiles());
foreach ($profile as $i => $p) {
$str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount);
}
return $str;
}
}
class_alias('Twig_Profiler_Dumper_Base', 'Twig\Profiler\Dumper\BaseDumper', false);
class_exists('Twig_Profiler_Profile');

View File

@@ -14,7 +14,7 @@
*
* @final
*/
class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Text
class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Base
{
private static $colors = array(
'block' => '#dfd',

View File

@@ -14,15 +14,8 @@
*
* @final
*/
class Twig_Profiler_Dumper_Text
class Twig_Profiler_Dumper_Text extends Twig_Profiler_Dumper_Base
{
private $root;
public function dump(Twig_Profiler_Profile $profile)
{
return $this->dumpProfile($profile);
}
protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix)
{
return sprintf('%s└ %s', $prefix, $profile->getTemplate());
@@ -37,36 +30,6 @@ class Twig_Profiler_Dumper_Text
{
return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent);
}
private function dumpProfile(Twig_Profiler_Profile $profile, $prefix = '', $sibling = false)
{
if ($profile->isRoot()) {
$this->root = $profile->getDuration();
$start = $profile->getName();
} else {
if ($profile->isTemplate()) {
$start = $this->formatTemplate($profile, $prefix);
} else {
$start = $this->formatNonTemplate($profile, $prefix);
}
$prefix .= $sibling ? '│ ' : ' ';
}
$percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0;
if ($profile->getDuration() * 1000 < 1) {
$str = $start."\n";
} else {
$str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent));
}
$nCount = count($profile->getProfiles());
foreach ($profile as $i => $p) {
$str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount);
}
return $str;
}
}
class_alias('Twig_Profiler_Dumper_Text', 'Twig\Profiler\Dumper\TextDumper', false);

View File

@@ -145,6 +145,12 @@ class Twig_Profiler_Profile implements IteratorAggregate, Serializable
);
}
public function reset()
{
$this->starts = $this->ends = $this->profiles = array();
$this->enter();
}
public function getIterator()
{
return new ArrayIterator($this->profiles);

View File

@@ -24,6 +24,14 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
*/
abstract protected function getFixturesDir();
/**
* @return Twig_RuntimeLoaderInterface[]
*/
protected function getRuntimeLoaders()
{
return array();
}
/**
* @return Twig_ExtensionInterface[]
*/
@@ -143,6 +151,10 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
), $match[2] ? eval($match[2].';') : array());
$twig = new Twig_Environment($loader, $config);
$twig->addGlobal('global', 'global');
foreach ($this->getRuntimeLoaders() as $runtimeLoader) {
$twig->addRuntimeLoader($runtimeLoader);
}
foreach ($this->getExtensions() as $extension) {
$twig->addExtension($extension);
}

View File

@@ -57,6 +57,8 @@ class Twig_TokenParser_Use extends Twig_TokenParser
$stream->expect(Twig_Token::BLOCK_END_TYPE);
$this->parser->addTrait(new Twig_Node(array('template' => $template, 'targets' => new Twig_Node($targets))));
return new Twig_Node();
}
public function getTag()

View File

@@ -9,7 +9,7 @@
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="test/bootstrap.php"
bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="Twig Test Suite">

View File

@@ -0,0 +1,19 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Twig\Extension;
/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
interface RuntimeExtensionInterface
{
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Twig\Profiler\Dumper;
class_exists('Twig_Profiler_Dumper_Base');
if (\false) {
class BaseDumper extends \Twig_Profiler_Dumper_Base
{
}
}

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_AutoloaderTest extends PHPUnit_Framework_TestCase
class Twig_Tests_AutoloaderTest extends \PHPUnit\Framework\TestCase
{
/**
* @group legacy

View File

@@ -11,7 +11,7 @@
require_once dirname(dirname(__FILE__)).'/FilesystemHelper.php';
class Twig_Tests_Cache_FilesystemTest extends PHPUnit_Framework_TestCase
class Twig_Tests_Cache_FilesystemTest extends \PHPUnit\Framework\TestCase
{
private $classname;
private $directory;

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_CompilerTest extends PHPUnit_Framework_TestCase
class Twig_Tests_CompilerTest extends \PHPUnit\Framework\TestCase
{
public function testReprNumericValueWithLocale()
{

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_ContainerRuntimeLoaderTest extends PHPUnit_Framework_TestCase
class Twig_Tests_ContainerRuntimeLoaderTest extends \PHPUnit\Framework\TestCase
{
/**
* @requires PHP 5.3

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class CustomExtensionTest extends PHPUnit_Framework_TestCase
class CustomExtensionTest extends \PHPUnit\Framework\TestCase
{
/**
* @requires PHP 5.3

View File

@@ -11,7 +11,7 @@
require_once dirname(__FILE__).'/FilesystemHelper.php';
class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
{
private $deprecations = array();
@@ -480,6 +480,33 @@ EOF
$this->assertEquals('foo', $twig->render('func_string_named_args'));
}
/**
* @expectedException Twig_Error_Runtime
* @expectedExceptionMessage Circular reference detected for Twig template "base.html.twig", path: base.html.twig -> base.html.twig in "base.html.twig" at line 1
*/
public function testFailLoadTemplateOnCircularReference()
{
$twig = new Twig_Environment(new Twig_Loader_Array(array(
'base.html.twig' => '{% extends "base.html.twig" %}',
)));
$twig->loadTemplate('base.html.twig');
}
/**
* @expectedException Twig_Error_Runtime
* @expectedExceptionMessage Circular reference detected for Twig template "base1.html.twig", path: base1.html.twig -> base2.html.twig -> base1.html.twig in "base1.html.twig" at line 1
*/
public function testFailLoadTemplateOnComplexCircularReference()
{
$twig = new Twig_Environment(new Twig_Loader_Array(array(
'base1.html.twig' => '{% extends "base2.html.twig" %}',
'base2.html.twig' => '{% extends "base1.html.twig" %}',
)));
$twig->loadTemplate('base1.html.twig');
}
protected function getMockLoader($templateName, $templateContent)
{
// to be removed in 2.0

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
class Twig_Tests_ErrorTest extends \PHPUnit\Framework\TestCase
{
public function testErrorWithObjectFilename()
{

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
class Twig_Tests_ExpressionParserTest extends \PHPUnit\Framework\TestCase
{
/**
* @expectedException Twig_Error_Syntax

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_Extension_CoreTest extends PHPUnit_Framework_TestCase
class Twig_Tests_Extension_CoreTest extends \PHPUnit\Framework\TestCase
{
/**
* @dataProvider getRandomFunctionTestData
@@ -264,7 +264,7 @@ class Twig_Tests_Extension_CoreTest extends PHPUnit_Framework_TestCase
array(array(), new CoreTestIterator($i, $keys, true), count($keys) + 10),
array('de', 'abcdef', 3, 2),
array(array(), new SimpleXMLElement('<items><item>1</item><item>2</item></items>'), 3),
array(array(), new ArrayIterator(array(1, 2)), 3)
array(array(), new ArrayIterator(array(1, 2)), 3),
);
}
}
@@ -344,7 +344,7 @@ final class CoreTestIterator implements Iterator
{
++$this->position;
if ($this->position === $this->maxPosition) {
throw new LogicException(sprintf('Code should not iterate beyond %d.', $this->maxPosition));
throw new LogicException(sprintf('Code should not iterate beyond %d.', $this->maxPosition));
}
}

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase
class Twig_Tests_Extension_SandboxTest extends \PHPUnit\Framework\TestCase
{
protected static $params;
protected static $templates;

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_FactoryRuntimeLoaderTest extends PHPUnit_Framework_TestCase
class Twig_Tests_FactoryRuntimeLoaderTest extends \PHPUnit\Framework\TestCase
{
public function testLoad()
{

View File

@@ -11,7 +11,7 @@
require_once dirname(__FILE__).'/FilesystemHelper.php';
class Twig_Tests_FileCachingTest extends PHPUnit_Framework_TestCase
class Twig_Tests_FileCachingTest extends \PHPUnit\Framework\TestCase
{
private $env;
private $tmpDir;

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_FileExtensionEscapingStrategyTest extends PHPUnit_Framework_TestCase
class Twig_Tests_FileExtensionEscapingStrategyTest extends \PHPUnit\Framework\TestCase
{
/**
* @dataProvider getGuessData

View File

@@ -0,0 +1,24 @@
--TEST--
"use" tag with a parent block
--TEMPLATE--
{% extends "parent.twig" %}
{% use 'blocks.twig' %}
{% block body %}
{{ parent() -}}
CHILD
{{ block('content') }}
{% endblock %}
--TEMPLATE(parent.twig)--
{% block body %}
PARENT
{% endblock %}
--TEMPLATE(blocks.twig)--
{% block content 'BLOCK' %}
--DATA--
return array()
--EXPECT--
PARENT
CHILD
BLOCK

View File

@@ -8,7 +8,7 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
class Twig_Tests_LexerTest extends \PHPUnit\Framework\TestCase
{
/**
* @group legacy

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
class Twig_Tests_Loader_ArrayTest extends \PHPUnit\Framework\TestCase
{
/**
* @group legacy

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
class Twig_Tests_Loader_ChainTest extends \PHPUnit\Framework\TestCase
{
/**
* @group legacy

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
class Twig_Tests_Loader_FilesystemTest extends \PHPUnit\Framework\TestCase
{
public function testGetSourceContext()
{

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_NativeExtensionTest extends PHPUnit_Framework_TestCase
class Twig_Tests_NativeExtensionTest extends \PHPUnit\Framework\TestCase
{
/**
* @requires PHP 5.3

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_Node_Expression_CallTest extends PHPUnit_Framework_TestCase
class Twig_Tests_Node_Expression_CallTest extends \PHPUnit\Framework\TestCase
{
public function testGetArguments()
{

View File

@@ -8,7 +8,7 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
class Twig_Tests_NodeVisitor_OptimizerTest extends \PHPUnit\Framework\TestCase
{
public function testRenderBlockOptimizer()
{

View File

@@ -8,7 +8,7 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
class Twig_Tests_ParserTest extends \PHPUnit\Framework\TestCase
{
/**
* @expectedException Twig_Error_Syntax

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
abstract class Twig_Tests_Profiler_Dumper_AbstractTest extends PHPUnit_Framework_TestCase
abstract class Twig_Tests_Profiler_Dumper_AbstractTest extends \PHPUnit\Framework\TestCase
{
protected function getProfile()
{

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_Profiler_ProfileTest extends PHPUnit_Framework_TestCase
class Twig_Tests_Profiler_ProfileTest extends \PHPUnit\Framework\TestCase
{
public function testConstructor()
{
@@ -97,4 +97,14 @@ class Twig_Tests_Profiler_ProfileTest extends PHPUnit_Framework_TestCase
$this->assertEquals($profile1->getType(), $profile3->getType());
$this->assertEquals($profile1->getName(), $profile3->getName());
}
public function testReset()
{
$profile = new Twig_Profiler_Profile();
usleep(1);
$profile->leave();
$profile->reset();
$this->assertEquals(0, $profile->getDuration());
}
}

View File

@@ -8,7 +8,7 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
class Twig_Tests_TemplateTest extends \PHPUnit\Framework\TestCase
{
/**
* @expectedException LogicException

View File

@@ -8,7 +8,7 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Tests_TemplateWrapperTest extends PHPUnit_Framework_TestCase
class Twig_Tests_TemplateWrapperTest extends \PHPUnit\Framework\TestCase
{
public function testHasGetBlocks()
{

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_TokenStreamTest extends PHPUnit_Framework_TestCase
class Twig_Tests_TokenStreamTest extends \PHPUnit\Framework\TestCase
{
protected static $tokens;

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
class Twig_Tests_Util_DeprecationCollectorTest extends PHPUnit_Framework_TestCase
class Twig_Tests_Util_DeprecationCollectorTest extends \PHPUnit\Framework\TestCase
{
/**
* @requires PHP 5.3

View File

@@ -6,7 +6,7 @@
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Twig_Test_EscapingTest extends PHPUnit_Framework_TestCase
class Twig_Test_EscapingTest extends \PHPUnit\Framework\TestCase
{
/**
* All character encodings supported by htmlspecialchars().

View File

@@ -1,21 +0,0 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
if (PHP_VERSION_ID < 50300) {
require_once dirname(__FILE__).'/../lib/Twig/Autoloader.php';
Twig_Autoloader::register(true);
} else {
require __DIR__.'/../vendor/autoload.php';
if (!class_exists('\PHPUnit_Framework_TestCase') && class_exists('\PHPUnit\Framework\TestCase')) {
class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase');
}
}