Issue #2366043 by dawehner: Upgrade to Symfony 2.6
parent
150cbcf61f
commit
3b945fe250
|
|
@ -6,16 +6,17 @@
|
|||
"require": {
|
||||
"php": ">=5.4.5",
|
||||
"sdboyer/gliph": "0.1.*",
|
||||
"symfony/class-loader": "2.5.*",
|
||||
"symfony/css-selector": "2.5.*",
|
||||
"symfony/dependency-injection": "2.5.*",
|
||||
"symfony/event-dispatcher": "2.5.*",
|
||||
"symfony/http-foundation": "2.5.*",
|
||||
"symfony/http-kernel": "2.5.*",
|
||||
"symfony/routing": "2.5.*",
|
||||
"symfony/serializer": "2.5.*",
|
||||
"symfony/validator": "2.5.*",
|
||||
"symfony/yaml": "dev-master#499f7d7aa96747ad97940089bd7a1fb24ad8182a",
|
||||
"symfony/class-loader": "2.6.0-beta1",
|
||||
"symfony/css-selector": "2.6.0-beta1",
|
||||
"symfony/debug": "2.6.0-beta1",
|
||||
"symfony/dependency-injection": "2.6.0-beta1",
|
||||
"symfony/event-dispatcher": "2.6.0-beta1",
|
||||
"symfony/http-foundation": "2.6.0-beta1",
|
||||
"symfony/http-kernel": "2.6.0-beta1",
|
||||
"symfony/routing": "2.6.0-beta1",
|
||||
"symfony/serializer": "2.6.0-beta1",
|
||||
"symfony/validator": "2.6.0-beta1",
|
||||
"symfony/yaml": "2.6.0-beta1",
|
||||
"twig/twig": "1.16.*",
|
||||
"doctrine/common": "dev-master#a45d110f71c323e29f41eb0696fa230e3fa1b1b5",
|
||||
"doctrine/annotations": "1.2.*",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "2bd5814ec010b13a6997359736b58695",
|
||||
"hash": "34a4f5a56891e51217c305b97e8cc675",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
|
|
@ -518,16 +518,16 @@
|
|||
},
|
||||
{
|
||||
"name": "egulias/email-validator",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/egulias/EmailValidator.git",
|
||||
"reference": "39b451bb2bb0655d83d82a38a0bba7189298cfc5"
|
||||
"reference": "518f80a0ff7c1a35780e7702f4262c8c6f2b807f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/39b451bb2bb0655d83d82a38a0bba7189298cfc5",
|
||||
"reference": "39b451bb2bb0655d83d82a38a0bba7189298cfc5",
|
||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/518f80a0ff7c1a35780e7702f4262c8c6f2b807f",
|
||||
"reference": "518f80a0ff7c1a35780e7702f4262c8c6f2b807f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -540,7 +540,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "1.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -564,7 +564,7 @@
|
|||
"validation",
|
||||
"validator"
|
||||
],
|
||||
"time": "2014-09-01 22:35:48"
|
||||
"time": "2014-11-06 08:59:44"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
|
|
@ -626,16 +626,16 @@
|
|||
},
|
||||
{
|
||||
"name": "guzzlehttp/ringphp",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/RingPHP.git",
|
||||
"reference": "9e44b565d726d9614cd970319e6eea70ee15bff3"
|
||||
"reference": "e7c28f96c5ac12ab0e63412cfc15989756fcb964"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/RingPHP/zipball/9e44b565d726d9614cd970319e6eea70ee15bff3",
|
||||
"reference": "9e44b565d726d9614cd970319e6eea70ee15bff3",
|
||||
"url": "https://api.github.com/repos/guzzle/RingPHP/zipball/e7c28f96c5ac12ab0e63412cfc15989756fcb964",
|
||||
"reference": "e7c28f96c5ac12ab0e63412cfc15989756fcb964",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -672,7 +672,7 @@
|
|||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"time": "2014-10-13 00:59:38"
|
||||
"time": "2014-11-04 07:01:14"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/streams",
|
||||
|
|
@ -1386,16 +1386,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/environment.git",
|
||||
"reference": "6288ebbf6fa3ed2b2ff2d69c356fbaaf4f0971a7"
|
||||
"reference": "0d9bf79554d2a999da194a60416c15cf461eb67d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6288ebbf6fa3ed2b2ff2d69c356fbaaf4f0971a7",
|
||||
"reference": "6288ebbf6fa3ed2b2ff2d69c356fbaaf4f0971a7",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/0d9bf79554d2a999da194a60416c15cf461eb67d",
|
||||
"reference": "0d9bf79554d2a999da194a60416c15cf461eb67d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1407,7 +1407,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
"dev-master": "1.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -1432,7 +1432,7 @@
|
|||
"environment",
|
||||
"hhvm"
|
||||
],
|
||||
"time": "2014-10-07 09:23:16"
|
||||
"time": "2014-10-22 06:38:05"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
|
|
@ -1643,17 +1643,17 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/class-loader",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/ClassLoader",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/ClassLoader.git",
|
||||
"reference": "432561f655123b003b32f370ca812fed9a9340c6"
|
||||
"reference": "d1a16139ea522ec3cc20801b7e19cd3cafd12d8c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/ClassLoader/zipball/432561f655123b003b32f370ca812fed9a9340c6",
|
||||
"reference": "432561f655123b003b32f370ca812fed9a9340c6",
|
||||
"url": "https://api.github.com/repos/symfony/ClassLoader/zipball/d1a16139ea522ec3cc20801b7e19cd3cafd12d8c",
|
||||
"reference": "d1a16139ea522ec3cc20801b7e19cd3cafd12d8c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1665,7 +1665,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -1689,21 +1689,21 @@
|
|||
],
|
||||
"description": "Symfony ClassLoader Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-22 09:14:18"
|
||||
"time": "2014-11-03 03:55:50"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/CssSelector",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/CssSelector.git",
|
||||
"reference": "caf5ecc3face1f22884fb74b8edab65ac5ba9976"
|
||||
"reference": "41953ad30ffc5cd710d106cf01eff79f6effa117"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/CssSelector/zipball/caf5ecc3face1f22884fb74b8edab65ac5ba9976",
|
||||
"reference": "caf5ecc3face1f22884fb74b8edab65ac5ba9976",
|
||||
"url": "https://api.github.com/repos/symfony/CssSelector/zipball/41953ad30ffc5cd710d106cf01eff79f6effa117",
|
||||
"reference": "41953ad30ffc5cd710d106cf01eff79f6effa117",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1712,7 +1712,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -1740,25 +1740,26 @@
|
|||
],
|
||||
"description": "Symfony CssSelector Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-22 09:14:18"
|
||||
"time": "2014-10-26 07:46:28"
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/Debug",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Debug.git",
|
||||
"reference": "4a3dd4ef3fc0cee2fd9faaae12bd7af43afcf648"
|
||||
"reference": "3548595c26175fdaca19cbec204668c22cda41f0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Debug/zipball/4a3dd4ef3fc0cee2fd9faaae12bd7af43afcf648",
|
||||
"reference": "4a3dd4ef3fc0cee2fd9faaae12bd7af43afcf648",
|
||||
"url": "https://api.github.com/repos/symfony/Debug/zipball/3548595c26175fdaca19cbec204668c22cda41f0",
|
||||
"reference": "3548595c26175fdaca19cbec204668c22cda41f0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
"php": ">=5.3.3",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/http-foundation": "~2.1",
|
||||
|
|
@ -1771,7 +1772,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -1795,21 +1796,21 @@
|
|||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-28 15:22:14"
|
||||
"time": "2014-10-28 10:06:58"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dependency-injection",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/DependencyInjection",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/DependencyInjection.git",
|
||||
"reference": "1f01a64c9047909e40700a14ee34e8c446300618"
|
||||
"reference": "926500fe0b8a6562c4e8b8166a1cb664733804aa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/1f01a64c9047909e40700a14ee34e8c446300618",
|
||||
"reference": "1f01a64c9047909e40700a14ee34e8c446300618",
|
||||
"url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/926500fe0b8a6562c4e8b8166a1cb664733804aa",
|
||||
"reference": "926500fe0b8a6562c4e8b8166a1cb664733804aa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1828,7 +1829,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -1852,21 +1853,21 @@
|
|||
],
|
||||
"description": "Symfony DependencyInjection Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-27 08:35:39"
|
||||
"time": "2014-11-03 03:55:50"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/EventDispatcher",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/EventDispatcher.git",
|
||||
"reference": "f6281337bf5f985f585d1db6a83adb05ce531f46"
|
||||
"reference": "dcf345d5ed96bc6c3b4521c1989670d2c9e5014e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/f6281337bf5f985f585d1db6a83adb05ce531f46",
|
||||
"reference": "f6281337bf5f985f585d1db6a83adb05ce531f46",
|
||||
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/dcf345d5ed96bc6c3b4521c1989670d2c9e5014e",
|
||||
"reference": "dcf345d5ed96bc6c3b4521c1989670d2c9e5014e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1875,7 +1876,8 @@
|
|||
"require-dev": {
|
||||
"psr/log": "~1.0",
|
||||
"symfony/config": "~2.0",
|
||||
"symfony/dependency-injection": "~2.0,<2.6.0",
|
||||
"symfony/dependency-injection": "~2.6",
|
||||
"symfony/expression-language": "~2.6",
|
||||
"symfony/stopwatch": "~2.2"
|
||||
},
|
||||
"suggest": {
|
||||
|
|
@ -1885,7 +1887,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -1909,21 +1911,21 @@
|
|||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-28 15:56:11"
|
||||
"time": "2014-11-03 03:55:50"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/HttpFoundation",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/HttpFoundation.git",
|
||||
"reference": "650e115af152d7a5e857d01c2cdb9a22809de9b4"
|
||||
"reference": "4cd6c807598e560db7b3da50c4330fdb4808cfa1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/650e115af152d7a5e857d01c2cdb9a22809de9b4",
|
||||
"reference": "650e115af152d7a5e857d01c2cdb9a22809de9b4",
|
||||
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/4cd6c807598e560db7b3da50c4330fdb4808cfa1",
|
||||
"reference": "4cd6c807598e560db7b3da50c4330fdb4808cfa1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1935,7 +1937,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -1962,27 +1964,27 @@
|
|||
],
|
||||
"description": "Symfony HttpFoundation Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-25 09:52:29"
|
||||
"time": "2014-11-03 03:55:50"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/HttpKernel",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/HttpKernel.git",
|
||||
"reference": "6a3595611229def14d5e644f060cf372235532ec"
|
||||
"reference": "7fa0bd9220cd529ee78d8565bbf8d5a854bd72d2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/6a3595611229def14d5e644f060cf372235532ec",
|
||||
"reference": "6a3595611229def14d5e644f060cf372235532ec",
|
||||
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/7fa0bd9220cd529ee78d8565bbf8d5a854bd72d2",
|
||||
"reference": "7fa0bd9220cd529ee78d8565bbf8d5a854bd72d2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"psr/log": "~1.0",
|
||||
"symfony/debug": "~2.5",
|
||||
"symfony/debug": "~2.6",
|
||||
"symfony/event-dispatcher": "~2.5",
|
||||
"symfony/http-foundation": "~2.5"
|
||||
},
|
||||
|
|
@ -1997,7 +1999,9 @@
|
|||
"symfony/process": "~2.0",
|
||||
"symfony/routing": "~2.2",
|
||||
"symfony/stopwatch": "~2.2",
|
||||
"symfony/templating": "~2.2"
|
||||
"symfony/templating": "~2.2",
|
||||
"symfony/translation": "~2.0",
|
||||
"symfony/var-dumper": "~2.6"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/browser-kit": "",
|
||||
|
|
@ -2005,12 +2009,13 @@
|
|||
"symfony/config": "",
|
||||
"symfony/console": "",
|
||||
"symfony/dependency-injection": "",
|
||||
"symfony/finder": ""
|
||||
"symfony/finder": "",
|
||||
"symfony/var-dumper": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -2034,68 +2039,21 @@
|
|||
],
|
||||
"description": "Symfony HttpKernel Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-28 17:33:53"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v2.5.5",
|
||||
"target-dir": "Symfony/Component/Process",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Process.git",
|
||||
"reference": "8a1ec96c4e519cee0fb971ea48a1eb7369dda54b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Process/zipball/8a1ec96c4e519cee0fb971ea48a1eb7369dda54b",
|
||||
"reference": "8a1ec96c4e519cee0fb971ea48a1eb7369dda54b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Process\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-23 05:25:11"
|
||||
"time": "2014-11-03 20:15:26"
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/Routing",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Routing.git",
|
||||
"reference": "9bc38fe72e0eff61611e7cd4df3accbce20b1d36"
|
||||
"reference": "f0bb6f818f9a7ece41c7dfe14e08b13c2de55b0c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Routing/zipball/9bc38fe72e0eff61611e7cd4df3accbce20b1d36",
|
||||
"reference": "9bc38fe72e0eff61611e7cd4df3accbce20b1d36",
|
||||
"url": "https://api.github.com/repos/symfony/Routing/zipball/f0bb6f818f9a7ece41c7dfe14e08b13c2de55b0c",
|
||||
"reference": "f0bb6f818f9a7ece41c7dfe14e08b13c2de55b0c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2118,7 +2076,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -2148,21 +2106,21 @@
|
|||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2014-09-22 15:28:36"
|
||||
"time": "2014-11-03 19:16:49"
|
||||
},
|
||||
{
|
||||
"name": "symfony/serializer",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/Serializer",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Serializer.git",
|
||||
"reference": "a95c0471682778da2e02169fb2644d3b08d4470f"
|
||||
"reference": "e96b7ac54b3d75a458f76eab11b7cd2d757f09f1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Serializer/zipball/a95c0471682778da2e02169fb2644d3b08d4470f",
|
||||
"reference": "a95c0471682778da2e02169fb2644d3b08d4470f",
|
||||
"url": "https://api.github.com/repos/symfony/Serializer/zipball/e96b7ac54b3d75a458f76eab11b7cd2d757f09f1",
|
||||
"reference": "e96b7ac54b3d75a458f76eab11b7cd2d757f09f1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2171,7 +2129,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -2195,21 +2153,21 @@
|
|||
],
|
||||
"description": "Symfony Serializer Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-22 09:14:18"
|
||||
"time": "2014-11-03 03:55:50"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.5.6",
|
||||
"target-dir": "Symfony/Component/Translation",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Translation.git",
|
||||
"reference": "170c0d895616e1a6a35681ffb0b9e339f58ab928"
|
||||
"reference": "362fe4da2cfe587f72d57aaa2f89e6b61c05dedf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Translation/zipball/170c0d895616e1a6a35681ffb0b9e339f58ab928",
|
||||
"reference": "170c0d895616e1a6a35681ffb0b9e339f58ab928",
|
||||
"url": "https://api.github.com/repos/symfony/Translation/zipball/362fe4da2cfe587f72d57aaa2f89e6b61c05dedf",
|
||||
"reference": "362fe4da2cfe587f72d57aaa2f89e6b61c05dedf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2251,21 +2209,21 @@
|
|||
],
|
||||
"description": "Symfony Translation Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-23 05:25:11"
|
||||
"time": "2014-10-01 05:50:18"
|
||||
},
|
||||
{
|
||||
"name": "symfony/validator",
|
||||
"version": "v2.5.5",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/Validator",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Validator.git",
|
||||
"reference": "64f61505843ca5e6c647244f5a4b6812c1279427"
|
||||
"reference": "6e521cdbc963cef7daf9931a7bde48b56d67d10a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Validator/zipball/64f61505843ca5e6c647244f5a4b6812c1279427",
|
||||
"reference": "64f61505843ca5e6c647244f5a4b6812c1279427",
|
||||
"url": "https://api.github.com/repos/symfony/Validator/zipball/6e521cdbc963cef7daf9931a7bde48b56d67d10a",
|
||||
"reference": "6e521cdbc963cef7daf9931a7bde48b56d67d10a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2297,7 +2255,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -2321,21 +2279,21 @@
|
|||
],
|
||||
"description": "Symfony Validator Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-09-28 15:22:14"
|
||||
"time": "2014-11-03 03:55:50"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "dev-master",
|
||||
"version": "v2.6.0-BETA1",
|
||||
"target-dir": "Symfony/Component/Yaml",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Yaml.git",
|
||||
"reference": "499f7d7aa96747ad97940089bd7a1fb24ad8182a"
|
||||
"reference": "9da3813f36985a4089f7e83c601a1034d125ff69"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/499f7d7aa96747ad97940089bd7a1fb24ad8182a",
|
||||
"reference": "499f7d7aa96747ad97940089bd7a1fb24ad8182a",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/9da3813f36985a4089f7e83c601a1034d125ff69",
|
||||
"reference": "9da3813f36985a4089f7e83c601a1034d125ff69",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2368,7 +2326,7 @@
|
|||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-10-05 13:53:50"
|
||||
"time": "2014-11-03 03:55:50"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
|
|
@ -2564,7 +2522,17 @@
|
|||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"symfony/yaml": 20,
|
||||
"symfony/class-loader": 10,
|
||||
"symfony/css-selector": 10,
|
||||
"symfony/debug": 10,
|
||||
"symfony/dependency-injection": 10,
|
||||
"symfony/event-dispatcher": 10,
|
||||
"symfony/http-foundation": 10,
|
||||
"symfony/http-kernel": 10,
|
||||
"symfony/routing": 10,
|
||||
"symfony/serializer": 10,
|
||||
"symfony/validator": 10,
|
||||
"symfony/yaml": 10,
|
||||
"doctrine/common": 20,
|
||||
"phpunit/phpunit-mock-objects": 20
|
||||
},
|
||||
|
|
|
|||
|
|
@ -173,4 +173,30 @@ class CompiledRoute extends SymfonyCompiledRoute {
|
|||
return $this->route->getRequirements();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize() {
|
||||
$data = unserialize(parent::serialize());
|
||||
$data['fit'] = $this->fit;
|
||||
$data['patternOutline'] = $this->patternOutline;
|
||||
$data['numParts'] = $this->numParts;
|
||||
|
||||
return serialize($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
parent::unserialize($serialized);
|
||||
$data = unserialize($serialized);
|
||||
|
||||
$this->fit = $data['fit'];
|
||||
$this->patternOutline = $data['patternOutline'];
|
||||
$this->numParts = $data['numParts'];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ return array(
|
|||
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
|
||||
'Symfony\\Component\\Serializer\\' => array($vendorDir . '/symfony/serializer'),
|
||||
'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
|
||||
'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
|
||||
'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'),
|
||||
'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
|
||||
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,8 +1,13 @@
|
|||
EmailValidator [](https://travis-ci.org/egulias/EmailValidator) [](https://coveralls.io/r/egulias/EmailValidator?branch=master) [](https://insight.sensiolabs.com/projects/b18d473e-bd5a-4d88-a7b2-7aeaee0ebd7b)[](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master)
|
||||
EmailValidator [](https://travis-ci.org/egulias/EmailValidator) [](https://coveralls.io/r/egulias/EmailValidator?branch=master) [](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6)[](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master)
|
||||
=============================
|
||||
|
||||
##Installation##
|
||||
Install via composer. Add to your current compooser.json ```require``` key: ```"egulias/email-validator":"1.0.x-dev" ```
|
||||
|
||||
Run the command below to install via Composer
|
||||
|
||||
```shell
|
||||
composer require egulias/email-validator
|
||||
```
|
||||
|
||||
##Usage##
|
||||
|
||||
|
|
@ -24,7 +29,7 @@ More advanced example (returns detailed diagnostic error codes):
|
|||
```php
|
||||
<?php
|
||||
|
||||
use egulias\EmailValidator\EmailValidator;
|
||||
use Egulias\EmailValidator\EmailValidator;
|
||||
|
||||
$validator = new EmailValidator;
|
||||
$email = 'dominic@sayers.cc';
|
||||
|
|
@ -46,6 +51,6 @@ As this is a port from another library and work, here are other people related t
|
|||
* Josepf Bielawski [@stloyd](http://github.com/stloyd): For its first re-work of Dominic's lib
|
||||
* Dominic Sayers [@dominicsayers](http://github.com/dominicsayers): The original isemail function
|
||||
|
||||
##Licence##
|
||||
Released under the MIT Licence attached with this code.
|
||||
##License##
|
||||
Released under the MIT License attached with this code.
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
],
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "1.3.x-dev"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "cca347a6b95164b1121e034b95f824ec",
|
||||
"hash": "9e9dff0cc08c7292600453e681201e13",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/lexer",
|
||||
|
|
@ -61,16 +62,16 @@
|
|||
"packages-dev": [
|
||||
{
|
||||
"name": "guzzle/guzzle",
|
||||
"version": "v3.9.1",
|
||||
"version": "v3.9.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle3.git",
|
||||
"reference": "92d9934f2fca1da15178c91239576ae26e505e60"
|
||||
"reference": "54991459675c1a2924122afbb0e5609ade581155"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle3/zipball/92d9934f2fca1da15178c91239576ae26e505e60",
|
||||
"reference": "92d9934f2fca1da15178c91239576ae26e505e60",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle3/zipball/54991459675c1a2924122afbb0e5609ade581155",
|
||||
"reference": "54991459675c1a2924122afbb0e5609ade581155",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -114,7 +115,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.8-dev"
|
||||
"dev-master": "3.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -149,7 +150,7 @@
|
|||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"time": "2014-05-07 17:04:22"
|
||||
"time": "2014-08-11 04:32:36"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
|
|
@ -195,18 +196,18 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/satooshi/php-coveralls.git",
|
||||
"reference": "b7271847c84d160f5b0aae83e45c225e8ffc96f4"
|
||||
"reference": "94389a0ebdb64857d6899b5e0254dffa99e5aa96"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/b7271847c84d160f5b0aae83e45c225e8ffc96f4",
|
||||
"reference": "b7271847c84d160f5b0aae83e45c225e8ffc96f4",
|
||||
"url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/94389a0ebdb64857d6899b5e0254dffa99e5aa96",
|
||||
"reference": "94389a0ebdb64857d6899b5e0254dffa99e5aa96",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-simplexml": "*",
|
||||
"guzzle/guzzle": ">=3.0",
|
||||
"guzzle/guzzle": ">=2.7",
|
||||
"php": ">=5.3",
|
||||
"psr/log": "1.0.0",
|
||||
"symfony/config": ">=2.0",
|
||||
|
|
@ -216,7 +217,7 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"apigen/apigen": "2.8.*@stable",
|
||||
"pdepend/pdepend": "dev-master",
|
||||
"pdepend/pdepend": "dev-master as 2.0.0",
|
||||
"phpmd/phpmd": "dev-master",
|
||||
"phpunit/php-invoker": ">=1.1.0,<1.2.0",
|
||||
"phpunit/phpunit": "3.7.*@stable",
|
||||
|
|
@ -262,21 +263,21 @@
|
|||
"github",
|
||||
"test"
|
||||
],
|
||||
"time": "2014-05-14 13:09:37"
|
||||
"time": "2014-07-09 10:45:38"
|
||||
},
|
||||
{
|
||||
"name": "symfony/config",
|
||||
"version": "v2.4.5",
|
||||
"version": "v2.5.4",
|
||||
"target-dir": "Symfony/Component/Config",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Config.git",
|
||||
"reference": "2effc67af6f21a0d267210b72d0b0b691d113528"
|
||||
"reference": "080eabdc256c1d7a3a7cf6296271edb68eb1ab2b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Config/zipball/2effc67af6f21a0d267210b72d0b0b691d113528",
|
||||
"reference": "2effc67af6f21a0d267210b72d0b0b691d113528",
|
||||
"url": "https://api.github.com/repos/symfony/Config/zipball/080eabdc256c1d7a3a7cf6296271edb68eb1ab2b",
|
||||
"reference": "080eabdc256c1d7a3a7cf6296271edb68eb1ab2b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -286,7 +287,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
"dev-master": "2.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -299,49 +300,49 @@
|
|||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Config Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-04-22 08:11:06"
|
||||
"time": "2014-08-31 03:22:04"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.4.5",
|
||||
"version": "v2.5.4",
|
||||
"target-dir": "Symfony/Component/Console",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Console.git",
|
||||
"reference": "24f723436e62598c9dddee2a8573d6992504dc5d"
|
||||
"reference": "748beed2a1e73179c3f5154d33fe6ae100c1aeb1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/24f723436e62598c9dddee2a8573d6992504dc5d",
|
||||
"reference": "24f723436e62598c9dddee2a8573d6992504dc5d",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/748beed2a1e73179c3f5154d33fe6ae100c1aeb1",
|
||||
"reference": "748beed2a1e73179c3f5154d33fe6ae100c1aeb1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "~1.0",
|
||||
"symfony/event-dispatcher": "~2.1"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log": "For using the console logger",
|
||||
"symfony/event-dispatcher": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
"dev-master": "2.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -354,41 +355,42 @@
|
|||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-05-14 21:48:29"
|
||||
"time": "2014-08-14 16:10:54"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.4.5",
|
||||
"version": "v2.5.4",
|
||||
"target-dir": "Symfony/Component/EventDispatcher",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/EventDispatcher.git",
|
||||
"reference": "e539602e5455aa086c0e81e604745af7789e4d8a"
|
||||
"reference": "8faf5cc7e80fde74a650a36e60d32ce3c3e0457b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/e539602e5455aa086c0e81e604745af7789e4d8a",
|
||||
"reference": "e539602e5455aa086c0e81e604745af7789e4d8a",
|
||||
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/8faf5cc7e80fde74a650a36e60d32ce3c3e0457b",
|
||||
"reference": "8faf5cc7e80fde74a650a36e60d32ce3c3e0457b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/dependency-injection": "~2.0"
|
||||
"psr/log": "~1.0",
|
||||
"symfony/config": "~2.0",
|
||||
"symfony/dependency-injection": "~2.0",
|
||||
"symfony/stopwatch": "~2.2"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/dependency-injection": "",
|
||||
|
|
@ -397,7 +399,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
"dev-master": "2.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -410,34 +412,32 @@
|
|||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-04-16 10:34:31"
|
||||
"time": "2014-07-28 13:20:46"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v2.4.5",
|
||||
"version": "v2.5.4",
|
||||
"target-dir": "Symfony/Component/Filesystem",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Filesystem.git",
|
||||
"reference": "a3af8294bcce4a7c1b2892363b0c9d8109affad4"
|
||||
"reference": "a765efd199e02ff4001c115c318e219030be9364"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/a3af8294bcce4a7c1b2892363b0c9d8109affad4",
|
||||
"reference": "a3af8294bcce4a7c1b2892363b0c9d8109affad4",
|
||||
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/a765efd199e02ff4001c115c318e219030be9364",
|
||||
"reference": "a765efd199e02ff4001c115c318e219030be9364",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -446,7 +446,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
"dev-master": "2.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -459,34 +459,32 @@
|
|||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Filesystem Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-04-16 10:34:31"
|
||||
"time": "2014-09-03 09:00:14"
|
||||
},
|
||||
{
|
||||
"name": "symfony/stopwatch",
|
||||
"version": "v2.4.5",
|
||||
"version": "v2.5.4",
|
||||
"target-dir": "Symfony/Component/Stopwatch",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Stopwatch.git",
|
||||
"reference": "343bcc0360f2c22f371884b8f6a9fee8d1aa431a"
|
||||
"reference": "22ab4f76cdeefd38b00022a6be5709190a2fd046"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/343bcc0360f2c22f371884b8f6a9fee8d1aa431a",
|
||||
"reference": "343bcc0360f2c22f371884b8f6a9fee8d1aa431a",
|
||||
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/22ab4f76cdeefd38b00022a6be5709190a2fd046",
|
||||
"reference": "22ab4f76cdeefd38b00022a6be5709190a2fd046",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -495,7 +493,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
"dev-master": "2.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -508,34 +506,32 @@
|
|||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Stopwatch Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-04-18 20:37:09"
|
||||
"time": "2014-08-14 16:10:54"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.4.5",
|
||||
"version": "v2.5.4",
|
||||
"target-dir": "Symfony/Component/Yaml",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Yaml.git",
|
||||
"reference": "fd22bb88c3a6f73c898b39bec185a9e211b06265"
|
||||
"reference": "01a7695bcfb013d0a15c6757e15aae120342986f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/fd22bb88c3a6f73c898b39bec185a9e211b06265",
|
||||
"reference": "fd22bb88c3a6f73c898b39bec185a9e211b06265",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/01a7695bcfb013d0a15c6757e15aae120342986f",
|
||||
"reference": "01a7695bcfb013d0a15c6757e15aae120342986f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -544,7 +540,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
"dev-master": "2.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -557,20 +553,18 @@
|
|||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-05-12 09:27:48"
|
||||
"time": "2014-08-31 03:22:04"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
|
|
@ -580,6 +574,7 @@
|
|||
"stability-flags": {
|
||||
"satooshi/php-coveralls": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"platform": {
|
||||
"php": ">= 5.3.3"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -31,10 +31,13 @@ class EmailLexer extends AbstractLexer
|
|||
const S_SEMICOLON = 275;
|
||||
const S_OPENQBRACKET = 276;
|
||||
const S_CLOSEQBRACKET = 277;
|
||||
const S_SLASH = 278;
|
||||
const S_EMPTY = null;
|
||||
const GENERIC = 300;
|
||||
const CRLF = 301;
|
||||
const INVALID = 302;
|
||||
const ASCII_INVALID_FROM = 127;
|
||||
const ASCII_INVALID_TO = 199;
|
||||
|
||||
/**
|
||||
* US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3)
|
||||
|
|
@ -52,6 +55,7 @@ class EmailLexer extends AbstractLexer
|
|||
';' => self::S_SEMICOLON,
|
||||
'@' => self::S_AT,
|
||||
'\\' => self::S_BACKSLASH,
|
||||
'/' => self::S_SLASH,
|
||||
',' => self::S_COMMA,
|
||||
'.' => self::S_DOT,
|
||||
'"' => self::S_DQUOTE,
|
||||
|
|
@ -67,14 +71,31 @@ class EmailLexer extends AbstractLexer
|
|||
'>' => self::S_GREATERTHAN,
|
||||
'{' => self::S_OPENQBRACKET,
|
||||
'}' => self::S_CLOSEQBRACKET,
|
||||
'' => self::S_EMPTY
|
||||
'' => self::S_EMPTY,
|
||||
'\0' => self::C_NUL,
|
||||
);
|
||||
|
||||
protected $invalidASCII = array(226 => 1,);
|
||||
|
||||
protected $hasInvalidTokens = false;
|
||||
|
||||
protected $previous;
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->hasInvalidTokens = false;
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
public function hasInvalidTokens()
|
||||
{
|
||||
return $this->hasInvalidTokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @throws \UnexpectedValueException
|
||||
* @return boolean
|
||||
*/
|
||||
public function find($type)
|
||||
{
|
||||
|
|
@ -100,7 +121,7 @@ class EmailLexer extends AbstractLexer
|
|||
/**
|
||||
* moveNext
|
||||
*
|
||||
* @return mixed
|
||||
* @return boolean
|
||||
*/
|
||||
public function moveNext()
|
||||
{
|
||||
|
|
@ -112,7 +133,7 @@ class EmailLexer extends AbstractLexer
|
|||
/**
|
||||
* Lexical catchable patterns.
|
||||
*
|
||||
* @return array
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getCatchablePatterns()
|
||||
{
|
||||
|
|
@ -130,7 +151,7 @@ class EmailLexer extends AbstractLexer
|
|||
/**
|
||||
* Lexical non-catchable patterns.
|
||||
*
|
||||
* @return array
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getNonCatchablePatterns()
|
||||
{
|
||||
|
|
@ -146,14 +167,48 @@ class EmailLexer extends AbstractLexer
|
|||
*/
|
||||
protected function getType(&$value)
|
||||
{
|
||||
|
||||
if ($this->isNullType($value)) {
|
||||
return self::C_NUL;
|
||||
}
|
||||
|
||||
if (isset($this->charValue[$value])) {
|
||||
return $this->charValue[$value];
|
||||
}
|
||||
|
||||
if (preg_match('/[\x10-\x1F]+/', $value)) {
|
||||
if ($this->isInvalid($value)) {
|
||||
$this->hasInvalidTokens = true;
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
return self::GENERIC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
protected function isNullType($value)
|
||||
{
|
||||
if ($value === "\0") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
protected function isInvalid($value)
|
||||
{
|
||||
if (preg_match('/[\x10-\x1F]+/', $value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isset($this->invalidASCII[ord($value)])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ class EmailParser
|
|||
$this->domainPartParser = new DomainPart($this->lexer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
*/
|
||||
public function parse($str)
|
||||
{
|
||||
$this->lexer->setInput($str);
|
||||
|
|
@ -36,6 +39,10 @@ class EmailParser
|
|||
throw new \InvalidArgumentException('ERR_NOLOCALPART');
|
||||
}
|
||||
|
||||
if ($this->lexer->hasInvalidTokens()) {
|
||||
throw new \InvalidArgumentException('ERR_INVALID_ATEXT');
|
||||
}
|
||||
|
||||
$this->localPartParser->parse($str);
|
||||
$this->domainPartParser->parse($str);
|
||||
|
||||
|
|
@ -78,6 +85,10 @@ class EmailParser
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $localPart
|
||||
* @param string $parsedDomainPart
|
||||
*/
|
||||
protected function addLongEmailWarning($localPart, $parsedDomainPart)
|
||||
{
|
||||
if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAIL_MAX_LENGTH) {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Egulias\EmailValidator;
|
||||
|
||||
use Egulias\EmailValidator\Parser\LocalPart;
|
||||
|
||||
/**
|
||||
* EmailValidator
|
||||
*
|
||||
|
|
@ -97,7 +95,7 @@ class EmailValidator
|
|||
return false;
|
||||
}
|
||||
|
||||
return ($strict) ? (!$this->hasWarnings() && $dns) : true;
|
||||
return !$strict || (!$this->hasWarnings() && $dns);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -146,16 +144,9 @@ class EmailValidator
|
|||
|
||||
protected function checkDNS()
|
||||
{
|
||||
$checked = false;
|
||||
if (!function_exists('dns_get_record') && (
|
||||
in_array(self::DNSWARN_NO_RECORD, $this->warnings) &&
|
||||
in_array(self::DNSWARN_NO_MX_RECORD, $this->warnings)
|
||||
)) {
|
||||
return $checked;
|
||||
}
|
||||
$checked = true;
|
||||
|
||||
$result = checkdnsrr(trim($this->parser->getParsedDomainPart()), 'MX');
|
||||
$checked = true;
|
||||
|
||||
if (!$result) {
|
||||
$this->warnings[] = self::DNSWARN_NO_RECORD;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ class DomainPart extends Parser
|
|||
if ($this->lexer->token['type'] === EmailLexer::S_EMPTY) {
|
||||
throw new \InvalidArgumentException('ERR_NODOMAIN');
|
||||
}
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN) {
|
||||
throw new \InvalidArgumentException('ERR_DOMAINHYPHENEND');
|
||||
}
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
||||
$this->warnings[] = EmailValidator::DEPREC_COMMENT;
|
||||
|
|
@ -103,6 +106,10 @@ class DomainPart extends Parser
|
|||
do {
|
||||
$prev = $this->lexer->getPrevious();
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_SLASH) {
|
||||
throw new \InvalidArgumentException('ERR_DOMAIN_CHAR_NOT_ALLOWED');
|
||||
}
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
||||
$this->parseComments();
|
||||
$this->lexer->moveNext();
|
||||
|
|
@ -210,6 +217,9 @@ class DomainPart extends Parser
|
|||
return $addressLiteral;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $addressLiteral
|
||||
*/
|
||||
protected function checkIPV4Tag($addressLiteral)
|
||||
{
|
||||
$matchesIP = array();
|
||||
|
|
@ -295,5 +305,4 @@ class DomainPart extends Parser
|
|||
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ namespace Egulias\EmailValidator\Parser;
|
|||
|
||||
use Egulias\EmailValidator\EmailLexer;
|
||||
use Egulias\EmailValidator\EmailValidator;
|
||||
use \InvalidArgumentException;
|
||||
|
||||
|
||||
class LocalPart extends Parser
|
||||
|
|
@ -21,8 +22,7 @@ class LocalPart extends Parser
|
|||
|
||||
$closingQuote = $this->checkDQUOTE($closingQuote);
|
||||
if ($closingQuote && $parseDQuote) {
|
||||
$this->parseDoubleQuote();
|
||||
$parseDQuote = false;
|
||||
$parseDQuote = $this->parseDoubleQuote();
|
||||
}
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
||||
|
|
@ -56,23 +56,51 @@ class LocalPart extends Parser
|
|||
|
||||
protected function parseDoubleQuote()
|
||||
{
|
||||
$parseAgain = true;
|
||||
$special = array(
|
||||
EmailLexer::S_CR => true,
|
||||
EmailLexer::S_HTAB => true,
|
||||
EmailLexer::S_LF => true
|
||||
);
|
||||
|
||||
$invalid = array(
|
||||
EmailLexer::C_NUL => true,
|
||||
EmailLexer::S_HTAB => true,
|
||||
EmailLexer::S_CR => true,
|
||||
EmailLexer::S_LF => true
|
||||
);
|
||||
$setSpecialsWarning = true;
|
||||
|
||||
$this->lexer->moveNext();
|
||||
|
||||
while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && $this->lexer->token) {
|
||||
$parseAgain = false;
|
||||
if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
|
||||
$this->warnings[] = EmailValidator::CFWS_FWS;
|
||||
$setSpecialsWarning = false;
|
||||
}
|
||||
|
||||
$this->lexer->moveNext();
|
||||
|
||||
if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) {
|
||||
throw new InvalidArgumentException("ERR_EXPECTED_ATEXT");
|
||||
}
|
||||
}
|
||||
|
||||
$prev = $this->lexer->getPrevious();
|
||||
|
||||
if ($prev['type'] === EmailLexer::S_BACKSLASH) {
|
||||
if (!$this->checkDQUOTE(false)) {
|
||||
throw new \InvalidArgumentException("ERR_UNCLOSED_DQUOTE");
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) {
|
||||
throw new \InvalidArgumentException("ERR_EXPECED_AT");
|
||||
}
|
||||
|
||||
return $parseAgain;
|
||||
}
|
||||
|
||||
protected function isInvalidToken($token, $closingQuote)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -124,8 +124,7 @@ abstract class Parser
|
|||
|
||||
if ($previous['type'] === EmailLexer::S_BACKSLASH
|
||||
&&
|
||||
($this->lexer->token['type'] === EmailLexer::S_SP ||
|
||||
$this->lexer->token['type'] === EmailLexer::S_HTAB)
|
||||
$this->lexer->token['type'] !== EmailLexer::GENERIC
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -164,6 +163,7 @@ abstract class Parser
|
|||
if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] === EmailLexer::GENERIC) {
|
||||
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
||||
}
|
||||
|
||||
$this->warnings[] = EmailValidator::RFC5321_QUOTEDSTRING;
|
||||
try {
|
||||
$this->lexer->find(EmailLexer::S_DQUOTE);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,15 @@ class EmailLexerTests extends \PHPUnit_Framework_TestCase
|
|||
$this->assertTrue($lexer->find(EmailLexer::S_HTAB));
|
||||
}
|
||||
|
||||
public function testLexerHasInvalidTokens()
|
||||
{
|
||||
$lexer = new EmailLexer();
|
||||
$lexer->setInput(chr(226));
|
||||
$lexer->moveNext();
|
||||
$lexer->moveNext();
|
||||
$this->assertTrue($lexer->hasInvalidTokens());
|
||||
}
|
||||
|
||||
public function getTokens()
|
||||
{
|
||||
return array(
|
||||
|
|
@ -61,6 +70,7 @@ class EmailLexerTests extends \PHPUnit_Framework_TestCase
|
|||
array("\"", EmailLexer::S_DQUOTE),
|
||||
array("-", EmailLexer::S_HYPHEN),
|
||||
array("\\", EmailLexer::S_BACKSLASH),
|
||||
array("/", EmailLexer::S_SLASH),
|
||||
array("(", EmailLexer::S_OPENPARENTHESIS),
|
||||
array(")", EmailLexer::S_CLOSEPARENTHESIS),
|
||||
array('<', EmailLexer::S_LOWERTHAN),
|
||||
|
|
@ -74,7 +84,9 @@ class EmailLexerTests extends \PHPUnit_Framework_TestCase
|
|||
array('{', EmailLexer::S_OPENQBRACKET),
|
||||
array('}', EmailLexer::S_CLOSEQBRACKET),
|
||||
array('', EmailLexer::S_EMPTY),
|
||||
array(chr(31), EmailLexer::INVALID)
|
||||
array(chr(31), EmailLexer::INVALID),
|
||||
array(chr(226), EmailLexer::INVALID),
|
||||
array(chr(0), EmailLexer::C_NUL)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
array('"user,name"@example.com'),
|
||||
array('"user name"@example.com'),
|
||||
array('"user@name"@example.com'),
|
||||
array('"\a"@iana.org'),
|
||||
array('"test\ test"@iana.org'),
|
||||
array('""@iana.org'),
|
||||
array('"\""@iana.org'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -57,9 +61,10 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
public function getInvalidEmails()
|
||||
{
|
||||
return array(
|
||||
|
||||
array('example.@example.co.uk'),
|
||||
array('example@example@example.co.uk'),
|
||||
array('(fabien_potencier@example.fr)'),
|
||||
array('(test_exampel@example.fr)'),
|
||||
array('example(example)example@example.co.uk'),
|
||||
array('.example@localhost'),
|
||||
array('ex\ample@localhost'),
|
||||
|
|
@ -72,6 +77,27 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
array('username@example,com'),
|
||||
array('usern,ame@example.com'),
|
||||
array('user[na]me@example.com'),
|
||||
array('"""@iana.org'),
|
||||
array('"\"@iana.org'),
|
||||
array('"test"test@iana.org'),
|
||||
array('"test""test"@iana.org'),
|
||||
array('"test"."test"@iana.org'),
|
||||
array('"test".test@iana.org'),
|
||||
array('"test"' . chr(0) . '@iana.org'),
|
||||
array('"test\"@iana.org'),
|
||||
array(chr(226) . '@iana.org'),
|
||||
array('test@' . chr(226) . '.org'),
|
||||
array('\r\ntest@iana.org'),
|
||||
array('\r\n test@iana.org'),
|
||||
array('\r\n \r\ntest@iana.org'),
|
||||
array('\r\n \r\ntest@iana.org'),
|
||||
array('\r\n \r\n test@iana.org'),
|
||||
array('test@iana.org \r\n'),
|
||||
array('test@iana.org \r\n '),
|
||||
array('test@iana.org \r\n \r\n'),
|
||||
array('test@iana.org \r\n\r\n'),
|
||||
array('test@iana.org \r\n\r\n '),
|
||||
array('test@iana/icann.org'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -124,6 +150,16 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals($warnings, $this->validator->getWarnings());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getInvalidEmailsWithWarnings
|
||||
*/
|
||||
public function testInvalidEmailsWithDnsCheckAndStrictMode($warnings, $email)
|
||||
{
|
||||
$this->assertFalse($this->validator->isValid($email, true, true));
|
||||
|
||||
$this->assertEquals($warnings, $this->validator->getWarnings());
|
||||
}
|
||||
|
||||
public function getInvalidEmailsWithWarnings()
|
||||
{
|
||||
return array(
|
||||
|
|
@ -275,6 +311,17 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
'parttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart'.
|
||||
'toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpar'
|
||||
),
|
||||
array(
|
||||
array(
|
||||
EmailValidator::DNSWARN_NO_RECORD,
|
||||
),
|
||||
'test@test'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function testInvalidEmailsWithStrict()
|
||||
{
|
||||
$this->assertFalse($this->validator->isValid('"test"@test', false, true));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
# CHANGELOG
|
||||
|
||||
## 1.0.3 - 2014-11-03
|
||||
|
||||
* Setting the `header` stream option as a string to be compatible with GAE.
|
||||
* Header parsing now ensures that header order is maintained in the parsed
|
||||
message.
|
||||
|
||||
## 1.0.2 - 2014-10-28
|
||||
|
||||
* Now correctly honoring a `version` option is supplied in a request.
|
||||
See https://github.com/guzzle/RingPHP/pull/8
|
||||
|
||||
## 1.0.1 - 2014-10-26
|
||||
|
||||
* Fixed a header parsing issue with the `CurlHandler` and `CurlMultiHandler`
|
||||
that caused cURL requests with multiple responses to merge repsonses together
|
||||
(e.g., requests with digest authentication).
|
||||
|
||||
## 1.0.0 - 2014-10-12
|
||||
|
||||
* Initial release.
|
||||
|
|
@ -2,13 +2,45 @@
|
|||
RingPHP
|
||||
=======
|
||||
|
||||
Provides low level APIs used to power HTTP clients and servers through a
|
||||
simple, PHP ``callable`` that accepts a request hash and returns a future
|
||||
response hash. RingPHP supports both synchronous and asynchronous
|
||||
workflows by utilizing both futures and `promises <https://github.com/reactphp/promise>`_.
|
||||
Provides a simple API and specification that abstracts away the details of HTTP
|
||||
into a single PHP function. RingPHP be used to power HTTP clients and servers
|
||||
through a PHP function that accepts a request hash and returns a response hash
|
||||
that is fulfilled using a `promise <https://github.com/reactphp/promise>`_,
|
||||
allowing RingPHP to support both synchronous and asynchronous workflows.
|
||||
|
||||
By abstracting the implementation details of different HTTP clients and
|
||||
servers, RingPHP allows you to utilize pluggable HTTP clients and servers
|
||||
without tying your application to a specific implementation.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use GuzzleHttp\Ring\Client\CurlHandler;
|
||||
|
||||
$handler = new CurlHandler();
|
||||
$response = $handler([
|
||||
'http_method' => 'GET',
|
||||
'uri' => '/',
|
||||
'headers' => [
|
||||
'host' => ['www.google.com'],
|
||||
'x-foo' => ['baz']
|
||||
]
|
||||
]);
|
||||
|
||||
$response->then(function (array $response) {
|
||||
echo $response['status'];
|
||||
});
|
||||
|
||||
$response->wait();
|
||||
|
||||
RingPHP is inspired by Clojure's `Ring <https://github.com/ring-clojure/ring>`_,
|
||||
but has been modified to accommodate clients and servers for both blocking
|
||||
and non-blocking requests.
|
||||
which, in turn, was inspired by Python's WSGI and Ruby's Rack. RingPHP is
|
||||
utilized as the handler layer in `Guzzle <http://guzzlephp.org>`_ 5.0+ to send
|
||||
HTTP requests.
|
||||
|
||||
See http://guzzle-ring.readthedocs.org/ for the full online documentation.
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
See http://ringphp.readthedocs.org/ for the full online documentation.
|
||||
|
|
|
|||
|
|
@ -2,23 +2,49 @@
|
|||
RingPHP
|
||||
=======
|
||||
|
||||
Provides low level APIs used to power HTTP clients and servers through a
|
||||
simple, PHP ``callable`` that accepts a request hash and returns a future
|
||||
response hash. RingPHP supports both synchronous and asynchronous
|
||||
workflows by utilizing both futures and `promises <https://github.com/reactphp/promise>`_.
|
||||
Provides a simple API and specification that abstracts away the details of HTTP
|
||||
into a single PHP function. RingPHP be used to power HTTP clients and servers
|
||||
through a PHP function that accepts a request hash and returns a response hash
|
||||
that is fulfilled using a `promise <https://github.com/reactphp/promise>`_,
|
||||
allowing RingPHP to support both synchronous and asynchronous workflows.
|
||||
|
||||
RingPHP is inspired by Clojure's `Ring <https://github.com/ring-clojure/ring>`_,
|
||||
but has been modified to accommodate clients and servers for both blocking
|
||||
and non-blocking requests.
|
||||
|
||||
RingPHP is utilized as the handler layer in
|
||||
`Guzzle <http://guzzlephp.org>`_ 5.0+ to send HTTP requests.
|
||||
By abstracting the implementation details of different HTTP clients and
|
||||
servers, RingPHP allows you to utilize pluggable HTTP clients and servers
|
||||
without tying your application to a specific implementation.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:maxdepth: 2
|
||||
|
||||
spec
|
||||
futures
|
||||
client_middleware
|
||||
client_handlers
|
||||
testing
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use GuzzleHttp\Ring\Client\CurlHandler;
|
||||
|
||||
$handler = new CurlHandler();
|
||||
$response = $handler([
|
||||
'http_method' => 'GET',
|
||||
'uri' => '/',
|
||||
'headers' => [
|
||||
'host' => ['www.google.com'],
|
||||
'x-foo' => ['baz']
|
||||
]
|
||||
]);
|
||||
|
||||
$response->then(function (array $response) {
|
||||
echo $response['status'];
|
||||
});
|
||||
|
||||
$response->wait();
|
||||
|
||||
RingPHP is inspired by Clojure's `Ring <https://github.com/ring-clojure/ring>`_,
|
||||
which, in turn, was inspired by Python's WSGI and Ruby's Rack. RingPHP is
|
||||
utilized as the handler layer in `Guzzle <http://guzzlephp.org>`_ 5.0+ to send
|
||||
HTTP requests.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ middleware.
|
|||
Handlers
|
||||
--------
|
||||
|
||||
Handlers are implemented as a PHP ``callable`` that accept a request array and
|
||||
Handlers are implemented as a PHP ``callable`` that accept a request array
|
||||
and return a response array (``GuzzleHttp\Ring\Future\FutureArrayInterface``).
|
||||
|
||||
For example:
|
||||
|
|
|
|||
|
|
@ -76,20 +76,17 @@ class CurlFactory
|
|||
$response['effective_url'] = $response['transfer_stats']['url'];
|
||||
}
|
||||
|
||||
if (isset($headers[0])) {
|
||||
if (!empty($headers)) {
|
||||
$startLine = explode(' ', array_shift($headers), 3);
|
||||
// Trim out 100-Continue start-lines
|
||||
if ($startLine[1] == '100') {
|
||||
$startLine = explode(' ', array_shift($headers), 3);
|
||||
}
|
||||
$response['headers'] = Core::headersFromLines($headers);
|
||||
$headerList = Core::headersFromLines($headers);
|
||||
$response['headers'] = $headerList;
|
||||
$response['status'] = isset($startLine[1]) ? (int) $startLine[1] : null;
|
||||
$response['reason'] = isset($startLine[2]) ? $startLine[2] : null;
|
||||
$response['body'] = $body;
|
||||
Core::rewindBody($response);
|
||||
}
|
||||
|
||||
return !empty($response['curl']['errno']) || !isset($startLine[1])
|
||||
return !empty($response['curl']['errno']) || !isset($response['status'])
|
||||
? self::createErrorResponse($handler, $request, $response)
|
||||
: $response;
|
||||
}
|
||||
|
|
@ -159,6 +156,7 @@ class CurlFactory
|
|||
private function getDefaultOptions(array $request, array &$headers)
|
||||
{
|
||||
$url = Core::url($request);
|
||||
$startingResponse = false;
|
||||
|
||||
$options = [
|
||||
'_headers' => $request['headers'],
|
||||
|
|
@ -167,15 +165,24 @@ class CurlFactory
|
|||
CURLOPT_RETURNTRANSFER => false,
|
||||
CURLOPT_HEADER => false,
|
||||
CURLOPT_CONNECTTIMEOUT => 150,
|
||||
CURLOPT_HEADERFUNCTION => function ($ch, $h) use (&$headers) {
|
||||
$length = strlen($h);
|
||||
if ($value = trim($h)) {
|
||||
$headers[] = trim($h);
|
||||
CURLOPT_HEADERFUNCTION => function ($ch, $h) use (&$headers, &$startingResponse) {
|
||||
$value = trim($h);
|
||||
if ($value === '') {
|
||||
$startingResponse = true;
|
||||
} elseif ($startingResponse) {
|
||||
$startingResponse = false;
|
||||
$headers = [$value];
|
||||
} else {
|
||||
$headers[] = $value;
|
||||
}
|
||||
return $length;
|
||||
return strlen($h);
|
||||
},
|
||||
];
|
||||
|
||||
if (isset($request['version'])) {
|
||||
$options[CURLOPT_HTTP_VERSION] = $request['version'] == 1.1 ? CURL_HTTP_VERSION_1_1 : CURL_HTTP_VERSION_1_0;
|
||||
}
|
||||
|
||||
if (defined('CURLOPT_PROTOCOLS')) {
|
||||
$options[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,10 +214,10 @@ class StreamHandler
|
|||
|
||||
private function getDefaultOptions(array $request)
|
||||
{
|
||||
$headers = [];
|
||||
$headers = "";
|
||||
foreach ($request['headers'] as $name => $value) {
|
||||
foreach ((array) $value as $val) {
|
||||
$headers[] = "$name: $val";
|
||||
$headers .= "$name: $val\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ class StreamHandler
|
|||
'http' => [
|
||||
'method' => $request['http_method'],
|
||||
'header' => $headers,
|
||||
'protocol_version' => '1.1',
|
||||
'protocol_version' => isset($request['version']) ? $request['version'] : 1.1,
|
||||
'ignore_errors' => true,
|
||||
'follow_location' => 0,
|
||||
],
|
||||
|
|
@ -236,10 +236,12 @@ class StreamHandler
|
|||
$context['http']['content'] = $body;
|
||||
// Prevent the HTTP handler from adding a Content-Type header.
|
||||
if (!Core::hasHeader($request, 'Content-Type')) {
|
||||
$context['http']['header'][] .= "Content-Type:";
|
||||
$context['http']['header'] .= "Content-Type:\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
$context['http']['header'] = rtrim($context['http']['header']);
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,24 +41,17 @@ class Core
|
|||
*/
|
||||
public static function headerLines($message, $header)
|
||||
{
|
||||
// Slight optimization for exact matches.
|
||||
if (isset($message['headers'][$header])) {
|
||||
return $message['headers'][$header];
|
||||
}
|
||||
$result = [];
|
||||
|
||||
// Check for message with no headers after the "fast" isset check.
|
||||
if (!isset($message['headers'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Iterate and case-insensitively find the header by name.
|
||||
if (!empty($message['headers'])) {
|
||||
foreach ($message['headers'] as $name => $value) {
|
||||
if (!strcasecmp($name, $header)) {
|
||||
return $value;
|
||||
$result = array_merge($result, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -91,18 +84,17 @@ class Core
|
|||
*/
|
||||
public static function firstHeader($message, $header)
|
||||
{
|
||||
$match = self::headerLines($message, $header);
|
||||
|
||||
if (!isset($match[0])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!empty($message['headers'])) {
|
||||
foreach ($message['headers'] as $name => $value) {
|
||||
if (!strcasecmp($name, $header)) {
|
||||
// Return the match itself if it is a single value.
|
||||
if (!($pos = strpos($match[0], ','))) {
|
||||
return $match[0];
|
||||
$pos = strpos($value[0], ',');
|
||||
return $pos ? substr($value[0], 0, $pos) : $value[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return substr($match[0], 0, $pos);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -115,7 +107,15 @@ class Core
|
|||
*/
|
||||
public static function hasHeader($message, $header)
|
||||
{
|
||||
return (bool) self::headerLines($message, $header);
|
||||
if (!empty($message['headers'])) {
|
||||
foreach ($message['headers'] as $name => $value) {
|
||||
if (!strcasecmp($name, $header)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -28,9 +28,7 @@ trait BaseFutureTrait
|
|||
private $isRealized = false;
|
||||
|
||||
/**
|
||||
* @param PromiseInterface $promise Promise to shadow with the future. Only
|
||||
* supply if the promise is not owned
|
||||
* by the deferred value.
|
||||
* @param PromiseInterface $promise Promise to shadow with the future.
|
||||
* @param callable $wait Function that blocks until the deferred
|
||||
* computation has been resolved. This
|
||||
* function MUST resolve the deferred value
|
||||
|
|
|
|||
|
|
@ -404,6 +404,19 @@ class CurlFactoryTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals($content, Core::body($response));
|
||||
}
|
||||
|
||||
public function testProtocolVersion()
|
||||
{
|
||||
Server::flush();
|
||||
Server::enqueue([['status' => 200]]);
|
||||
$a = new CurlMultiHandler();
|
||||
$a([
|
||||
'http_method' => 'GET',
|
||||
'headers' => ['host' => [Server::$host]],
|
||||
'version' => 1.0,
|
||||
]);
|
||||
$this->assertEquals(CURL_HTTP_VERSION_1_0, $_SERVER['_curl'][CURLOPT_HTTP_VERSION]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
|
|
@ -570,7 +583,7 @@ class CurlFactoryTest extends \PHPUnit_Framework_TestCase
|
|||
'http_method' => 'GET',
|
||||
'headers' => [
|
||||
'host' => [Server::$host],
|
||||
'content-length' => 3,
|
||||
'content-length' => [3],
|
||||
],
|
||||
'body' => 'foo',
|
||||
]);
|
||||
|
|
@ -709,6 +722,71 @@ class CurlFactoryTest extends \PHPUnit_Framework_TestCase
|
|||
);
|
||||
$this->assertInstanceOf('GuzzleHttp\Ring\Exception\ConnectException', $response['error']);
|
||||
}
|
||||
|
||||
public function testParsesLastResponseOnly()
|
||||
{
|
||||
$response1 = [
|
||||
'status' => 301,
|
||||
'headers' => [
|
||||
'Content-Length' => ['0'],
|
||||
'Location' => ['/foo']
|
||||
]
|
||||
];
|
||||
|
||||
$response2 = [
|
||||
'status' => 200,
|
||||
'headers' => [
|
||||
'Content-Length' => ['0'],
|
||||
'Foo' => ['bar']
|
||||
]
|
||||
];
|
||||
|
||||
Server::flush();
|
||||
Server::enqueue([$response1, $response2]);
|
||||
|
||||
$a = new CurlMultiHandler();
|
||||
$response = $a([
|
||||
'http_method' => 'GET',
|
||||
'headers' => ['Host' => [Server::$host]],
|
||||
'client' => [
|
||||
'curl' => [
|
||||
CURLOPT_FOLLOWLOCATION => true
|
||||
]
|
||||
]
|
||||
])->wait();
|
||||
|
||||
$this->assertEquals(1, $response['transfer_stats']['redirect_count']);
|
||||
$this->assertEquals('http://127.0.0.1:8125/foo', $response['effective_url']);
|
||||
$this->assertEquals(['bar'], $response['headers']['Foo']);
|
||||
$this->assertEquals(200, $response['status']);
|
||||
$this->assertFalse(Core::hasHeader($response, 'Location'));
|
||||
}
|
||||
|
||||
public function testMaintainsMultiHeaderOrder()
|
||||
{
|
||||
Server::flush();
|
||||
Server::enqueue([
|
||||
[
|
||||
'status' => 200,
|
||||
'headers' => [
|
||||
'Content-Length' => ['0'],
|
||||
'Foo' => ['a', 'b'],
|
||||
'foo' => ['c', 'd'],
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$a = new CurlMultiHandler();
|
||||
$response = $a([
|
||||
'http_method' => 'GET',
|
||||
'headers' => ['Host' => [Server::$host]]
|
||||
])->wait();
|
||||
|
||||
$this->assertEquals(
|
||||
['a', 'b', 'c', 'd'],
|
||||
Core::headerLines($response, 'Foo')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,6 +202,20 @@ class StreamHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertSame($content, Core::body($response));
|
||||
}
|
||||
|
||||
public function testProtocolVersion()
|
||||
{
|
||||
$this->queueRes();
|
||||
$handler = new StreamHandler();
|
||||
$handler([
|
||||
'http_method' => 'GET',
|
||||
'uri' => '/',
|
||||
'headers' => ['host' => [Server::$host]],
|
||||
'version' => 1.0,
|
||||
]);
|
||||
|
||||
$this->assertEquals(1.0, Server::received()[0]['version']);
|
||||
}
|
||||
|
||||
protected function getSendResult(array $opts)
|
||||
{
|
||||
$this->queueRes();
|
||||
|
|
|
|||
|
|
@ -15,6 +15,22 @@ class CoreTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertNull(Core::firstHeader([], 'Foo'));
|
||||
}
|
||||
|
||||
public function testChecksIfHasHeader()
|
||||
{
|
||||
$message = [
|
||||
'headers' => [
|
||||
'Foo' => ['Bar', 'Baz'],
|
||||
'foo' => ['hello'],
|
||||
'bar' => ['1']
|
||||
]
|
||||
];
|
||||
$this->assertTrue(Core::hasHeader($message, 'Foo'));
|
||||
$this->assertTrue(Core::hasHeader($message, 'foo'));
|
||||
$this->assertTrue(Core::hasHeader($message, 'FoO'));
|
||||
$this->assertTrue(Core::hasHeader($message, 'bar'));
|
||||
$this->assertFalse(Core::hasHeader($message, 'barr'));
|
||||
}
|
||||
|
||||
public function testReturnsFirstHeaderWhenSimple()
|
||||
{
|
||||
$this->assertEquals('Bar', Core::firstHeader([
|
||||
|
|
@ -37,6 +53,19 @@ class CoreTest extends \PHPUnit_Framework_TestCase
|
|||
);
|
||||
}
|
||||
|
||||
public function testExtractsCaseInsensitiveHeaderLines()
|
||||
{
|
||||
$this->assertEquals(
|
||||
['a', 'b', 'c', 'd'],
|
||||
Core::headerLines([
|
||||
'headers' => [
|
||||
'foo' => ['a', 'b'],
|
||||
'Foo' => ['c', 'd']
|
||||
]
|
||||
], 'foo')
|
||||
);
|
||||
}
|
||||
|
||||
public function testExtractsHeaderLines()
|
||||
{
|
||||
$this->assertEquals(
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
"dev-master": "1.2.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,4 +68,28 @@ class Console
|
|||
|
||||
return function_exists('posix_isatty') && @posix_isatty(STDOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of columns of the terminal.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getNumberOfColumns()
|
||||
{
|
||||
// Windows terminals have a fixed size of 80
|
||||
// but one column is used for the cursor.
|
||||
if (DIRECTORY_SEPARATOR == '\\') {
|
||||
return 79;
|
||||
}
|
||||
|
||||
if (preg_match('#\d+ (\d+)#', shell_exec('stty size'), $match) === 1) {
|
||||
return (int) $match[1];
|
||||
}
|
||||
|
||||
if (preg_match('#columns = (\d+);#', shell_exec('stty'), $match) === 1) {
|
||||
return (int) $match[1];
|
||||
}
|
||||
|
||||
return 80;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,14 @@ class ConsoleTest extends PHPUnit_Framework_TestCase
|
|||
*/
|
||||
public function testCanDetectColorSupport()
|
||||
{
|
||||
$this->assertTrue($this->console->hasColorSupport());
|
||||
$this->assertInternalType('boolean', $this->console->hasColorSupport());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \SebastianBergmann\Environment\Console::hasColorSupport
|
||||
*/
|
||||
public function testCanDetectNumberOfColumns()
|
||||
{
|
||||
$this->assertInternalType('integer', $this->console->getNumberOfColumns());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class ClassLoader
|
|||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
$this->useIncludePath = (bool) $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -9,51 +9,63 @@ standard or the PEAR naming convention.
|
|||
|
||||
First, register the autoloader:
|
||||
|
||||
```php
|
||||
require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
|
||||
|
||||
use Symfony\Component\ClassLoader\UniversalClassLoader;
|
||||
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->register();
|
||||
```
|
||||
|
||||
Then, register some namespaces with the `registerNamespace()` method:
|
||||
|
||||
```php
|
||||
$loader->registerNamespace('Symfony', __DIR__.'/src');
|
||||
$loader->registerNamespace('Monolog', __DIR__.'/vendor/monolog/src');
|
||||
```
|
||||
|
||||
The `registerNamespace()` method takes a namespace prefix and a path where to
|
||||
look for the classes as arguments.
|
||||
|
||||
You can also register a sub-namespaces:
|
||||
|
||||
```php
|
||||
$loader->registerNamespace('Doctrine\\Common', __DIR__.'/vendor/doctrine-common/lib');
|
||||
```
|
||||
|
||||
The order of registration is significant and the first registered namespace
|
||||
takes precedence over later registered one.
|
||||
|
||||
You can also register more than one path for a given namespace:
|
||||
|
||||
```php
|
||||
$loader->registerNamespace('Symfony', array(__DIR__.'/src', __DIR__.'/symfony/src'));
|
||||
```
|
||||
|
||||
Alternatively, you can use the `registerNamespaces()` method to register more
|
||||
than one namespace at once:
|
||||
|
||||
```php
|
||||
$loader->registerNamespaces(array(
|
||||
'Symfony' => array(__DIR__.'/src', __DIR__.'/symfony/src'),
|
||||
'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib',
|
||||
'Doctrine' => __DIR__.'/vendor/doctrine/lib',
|
||||
'Monolog' => __DIR__.'/vendor/monolog/src',
|
||||
));
|
||||
```
|
||||
|
||||
For better performance, you can use the APC based version of the universal
|
||||
class loader:
|
||||
|
||||
```php
|
||||
require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
|
||||
require_once __DIR__.'/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php';
|
||||
|
||||
use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
|
||||
|
||||
$loader = new ApcUniversalClassLoader('apc.prefix.');
|
||||
```
|
||||
|
||||
Furthermore, the component provides tools to aggregate classes into a single
|
||||
file, which is especially useful to improve performance on servers that do not
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class UniversalClassLoader
|
|||
*/
|
||||
public function useIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
$this->useIncludePath = (bool) $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
"target-dir": "Symfony/Component/ClassLoader",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,4 +75,28 @@ class Specificity
|
|||
{
|
||||
return $this->a * self::A_FACTOR + $this->b * self::B_FACTOR + $this->c * self::C_FACTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns -1 if the object specificity is lower than the argument,
|
||||
* 0 if they are equal, and 1 if the argument is lower
|
||||
*
|
||||
* @param Specificity $specificity
|
||||
* @return int
|
||||
*/
|
||||
public function compareTo(Specificity $specificity)
|
||||
{
|
||||
if ($this->a !== $specificity->a) {
|
||||
return $this->a > $specificity->a ? 1 : -1;
|
||||
}
|
||||
|
||||
if ($this->b !== $specificity->b) {
|
||||
return $this->b > $specificity->b ? 1 : -1;
|
||||
}
|
||||
|
||||
if ($this->c !== $specificity->c) {
|
||||
return $this->c > $specificity->c ? 1 : -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ CssSelector converts CSS selectors to XPath expressions.
|
|||
The component only goal is to convert CSS selectors to their XPath
|
||||
equivalents:
|
||||
|
||||
```php
|
||||
use Symfony\Component\CssSelector\CssSelector;
|
||||
|
||||
print CssSelector::toXPath('div.item > h4 > a');
|
||||
```
|
||||
|
||||
HTML and XML are different
|
||||
--------------------------
|
||||
|
|
@ -18,11 +20,13 @@ default. If you need to use this component with `XML` documents, you have to
|
|||
disable this `HTML` extension. That's because, `HTML` tag & attribute names
|
||||
are always lower-cased, but case-sensitive in `XML`:
|
||||
|
||||
```php
|
||||
// disable `HTML` extension:
|
||||
CssSelector::disableHtmlExtension();
|
||||
|
||||
// re-enable `HTML` extension:
|
||||
CssSelector::enableHtmlExtension();
|
||||
```
|
||||
|
||||
When the `HTML` extension is enabled, tag names are lower-cased, attribute
|
||||
names are lower-cased, the following extra pseudo-classes are supported:
|
||||
|
|
|
|||
|
|
@ -37,4 +37,26 @@ class SpecificityTest extends \PHPUnit_Framework_TestCase
|
|||
array(new Specificity(4, 3, 2), 432),
|
||||
);
|
||||
}
|
||||
|
||||
/** @dataProvider getCompareTestData */
|
||||
public function testCompareTo(Specificity $a, Specificity $b, $result)
|
||||
{
|
||||
$this->assertEquals($result, $a->compareTo($b));
|
||||
}
|
||||
|
||||
public function getCompareTestData()
|
||||
{
|
||||
return array(
|
||||
array(new Specificity(0, 0, 0), new Specificity(0, 0, 0), 0),
|
||||
array(new Specificity(0, 0, 1), new Specificity(0, 0, 1), 0),
|
||||
array(new Specificity(0, 0, 2), new Specificity(0, 0, 1), 1),
|
||||
array(new Specificity(0, 0, 2), new Specificity(0, 0, 3), -1),
|
||||
array(new Specificity(0, 4, 0), new Specificity(0, 4, 0), 0),
|
||||
array(new Specificity(0, 6, 0), new Specificity(0, 5, 11), 1),
|
||||
array(new Specificity(0, 7, 0), new Specificity(0, 8, 0), -1),
|
||||
array(new Specificity(9, 0, 0), new Specificity(9, 0, 0), 0),
|
||||
array(new Specificity(11, 0, 0), new Specificity(10, 11, 0), 1),
|
||||
array(new Specificity(12, 11, 0), new Specificity(13, 0, 0), -1),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,17 +123,15 @@ class Translator implements TranslatorInterface
|
|||
$selectors = $this->parseSelectors($cssExpr);
|
||||
|
||||
/** @var SelectorNode $selector */
|
||||
foreach ($selectors as $selector) {
|
||||
foreach ($selectors as $index => $selector) {
|
||||
if (null !== $selector->getPseudoElement()) {
|
||||
throw new ExpressionErrorException('Pseudo-elements are not supported.');
|
||||
}
|
||||
|
||||
$selectors[$index] = $this->selectorToXPath($selector, $prefix);
|
||||
}
|
||||
|
||||
$translator = $this;
|
||||
|
||||
return implode(' | ', array_map(function (SelectorNode $selector) use ($translator, $prefix) {
|
||||
return $translator->selectorToXPath($selector, $prefix);
|
||||
}, $selectors));
|
||||
return implode(' | ', $selectors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.6.0
|
||||
-----
|
||||
|
||||
* generalized ErrorHandler and ExceptionHandler,
|
||||
with some new methods and others deprecated
|
||||
* enhanced error messages for uncaught exceptions
|
||||
|
||||
2.5.0
|
||||
-----
|
||||
|
||||
|
|
|
|||
|
|
@ -39,15 +39,23 @@ class Debug
|
|||
|
||||
static::$enabled = true;
|
||||
|
||||
if (null !== $errorReportingLevel) {
|
||||
error_reporting($errorReportingLevel);
|
||||
} else {
|
||||
error_reporting(-1);
|
||||
}
|
||||
|
||||
ErrorHandler::register($errorReportingLevel, $displayErrors);
|
||||
if ('cli' !== php_sapi_name()) {
|
||||
ini_set('display_errors', 0);
|
||||
ExceptionHandler::register();
|
||||
// CLI - display errors only if they're not already logged to STDERR
|
||||
} elseif ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) {
|
||||
// CLI - display errors only if they're not already logged to STDERR
|
||||
ini_set('display_errors', 1);
|
||||
}
|
||||
$handler = ErrorHandler::register();
|
||||
if (!$displayErrors) {
|
||||
$handler->throwAt(0, true);
|
||||
}
|
||||
|
||||
DebugClassLoader::enable();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,8 @@ class DebugClassLoader
|
|||
public static function enable()
|
||||
{
|
||||
// Ensures we don't hit https://bugs.php.net/42098
|
||||
class_exists(__NAMESPACE__.'\ErrorHandler', true);
|
||||
class_exists('Symfony\Component\Debug\ErrorHandler');
|
||||
class_exists('Psr\Log\LogLevel');
|
||||
|
||||
if (!is_array($functions = spl_autoload_functions())) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -22,141 +22,353 @@ use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
|
|||
use Symfony\Component\Debug\FatalErrorHandler\FatalErrorHandlerInterface;
|
||||
|
||||
/**
|
||||
* ErrorHandler.
|
||||
* A generic ErrorHandler for the PHP engine.
|
||||
*
|
||||
* Provides five bit fields that control how errors are handled:
|
||||
* - thrownErrors: errors thrown as \ErrorException
|
||||
* - loggedErrors: logged errors, when not @-silenced
|
||||
* - scopedErrors: errors thrown or logged with their local context
|
||||
* - tracedErrors: errors logged with their stack trace, only once for repeated errors
|
||||
* - screamedErrors: never @-silenced errors
|
||||
*
|
||||
* Each error level can be logged by a dedicated PSR-3 logger object.
|
||||
* Screaming only applies to logging.
|
||||
* Throwing takes precedence over logging.
|
||||
* Uncaught exceptions are logged as E_ERROR.
|
||||
* E_DEPRECATED and E_USER_DEPRECATED levels never throw.
|
||||
* E_RECOVERABLE_ERROR and E_USER_ERROR levels always throw.
|
||||
* Non catchable errors that can be detected at shutdown time are logged when the scream bit field allows so.
|
||||
* As errors have a performance cost, repeated errors are all logged, so that the developer
|
||||
* can see them and weight them as more important to fix than others of the same level.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Konstantin Myakshin <koc-dp@yandex.ru>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ErrorHandler
|
||||
{
|
||||
/**
|
||||
* @deprecated since 2.6, to be removed in 3.0.
|
||||
*/
|
||||
const TYPE_DEPRECATION = -100;
|
||||
|
||||
private $levels = array(
|
||||
E_WARNING => 'Warning',
|
||||
E_NOTICE => 'Notice',
|
||||
E_USER_ERROR => 'User Error',
|
||||
E_USER_WARNING => 'User Warning',
|
||||
E_USER_NOTICE => 'User Notice',
|
||||
E_STRICT => 'Runtime Notice',
|
||||
E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
|
||||
E_DEPRECATED => 'Deprecated',
|
||||
E_USER_DEPRECATED => 'User Deprecated',
|
||||
E_ERROR => 'Error',
|
||||
E_CORE_ERROR => 'Core Error',
|
||||
E_NOTICE => 'Notice',
|
||||
E_USER_NOTICE => 'User Notice',
|
||||
E_STRICT => 'Runtime Notice',
|
||||
E_WARNING => 'Warning',
|
||||
E_USER_WARNING => 'User Warning',
|
||||
E_COMPILE_WARNING => 'Compile Warning',
|
||||
E_CORE_WARNING => 'Core Warning',
|
||||
E_USER_ERROR => 'User Error',
|
||||
E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
|
||||
E_COMPILE_ERROR => 'Compile Error',
|
||||
E_PARSE => 'Parse Error',
|
||||
E_ERROR => 'Error',
|
||||
E_CORE_ERROR => 'Core Error',
|
||||
);
|
||||
|
||||
private $level;
|
||||
private $loggers = array(
|
||||
E_DEPRECATED => array(null, LogLevel::INFO),
|
||||
E_USER_DEPRECATED => array(null, LogLevel::INFO),
|
||||
E_NOTICE => array(null, LogLevel::NOTICE),
|
||||
E_USER_NOTICE => array(null, LogLevel::NOTICE),
|
||||
E_STRICT => array(null, LogLevel::NOTICE),
|
||||
E_WARNING => array(null, LogLevel::WARNING),
|
||||
E_USER_WARNING => array(null, LogLevel::WARNING),
|
||||
E_COMPILE_WARNING => array(null, LogLevel::WARNING),
|
||||
E_CORE_WARNING => array(null, LogLevel::WARNING),
|
||||
E_USER_ERROR => array(null, LogLevel::ERROR),
|
||||
E_RECOVERABLE_ERROR => array(null, LogLevel::ERROR),
|
||||
E_COMPILE_ERROR => array(null, LogLevel::EMERGENCY),
|
||||
E_PARSE => array(null, LogLevel::EMERGENCY),
|
||||
E_ERROR => array(null, LogLevel::EMERGENCY),
|
||||
E_CORE_ERROR => array(null, LogLevel::EMERGENCY),
|
||||
);
|
||||
|
||||
private $reservedMemory;
|
||||
private $thrownErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED
|
||||
private $scopedErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED
|
||||
private $tracedErrors = 0x77FB; // E_ALL - E_STRICT - E_PARSE
|
||||
private $screamedErrors = 0x55; // E_ERROR + E_CORE_ERROR + E_COMPILE_ERROR + E_PARSE
|
||||
private $loggedErrors = 0;
|
||||
|
||||
private $displayErrors;
|
||||
private $loggedTraces = array();
|
||||
private $isRecursive = 0;
|
||||
private $exceptionHandler;
|
||||
|
||||
private static $reservedMemory;
|
||||
private static $stackedErrors = array();
|
||||
private static $stackedErrorLevels = array();
|
||||
|
||||
/**
|
||||
* @var LoggerInterface[] Loggers for channels
|
||||
* Same init value as thrownErrors
|
||||
*
|
||||
* @deprecated since 2.6, to be removed in 3.0.
|
||||
*/
|
||||
private static $loggers = array();
|
||||
|
||||
private static $stackedErrors = array();
|
||||
|
||||
private static $stackedErrorLevels = array();
|
||||
private $displayErrors = 0x1FFF;
|
||||
|
||||
/**
|
||||
* Registers the error handler.
|
||||
*
|
||||
* @param int $level The level at which the conversion to Exception is done (null to use the error_reporting() value and 0 to disable)
|
||||
* @param bool $displayErrors Display errors (for dev environment) or just log them (production usage)
|
||||
* @param self|null|int $handler The handler to register, or @deprecated (since 2.6, to be removed in 3.0) bit field of thrown levels
|
||||
* @param bool $replace Whether to replace or not any existing handler
|
||||
*
|
||||
* @return ErrorHandler The registered error handler
|
||||
* @return self The registered error handler
|
||||
*/
|
||||
public static function register($level = null, $displayErrors = true)
|
||||
public static function register($handler = null, $replace = true)
|
||||
{
|
||||
$handler = new static();
|
||||
$handler->setLevel($level);
|
||||
$handler->setDisplayErrors($displayErrors);
|
||||
if (null === self::$reservedMemory) {
|
||||
self::$reservedMemory = str_repeat('x', 10240);
|
||||
register_shutdown_function(__CLASS__.'::handleFatalError');
|
||||
}
|
||||
|
||||
ini_set('display_errors', 0);
|
||||
set_error_handler(array($handler, 'handle'));
|
||||
register_shutdown_function(array($handler, 'handleFatal'));
|
||||
$handler->reservedMemory = str_repeat('x', 10240);
|
||||
$levels = -1;
|
||||
|
||||
if ($handlerIsNew = !$handler instanceof self) {
|
||||
// @deprecated polymorphism, to be removed in 3.0
|
||||
if (null !== $handler) {
|
||||
$levels = $replace ? $handler : 0;
|
||||
$replace = true;
|
||||
}
|
||||
$handler = new static();
|
||||
}
|
||||
|
||||
$prev = set_error_handler(array($handler, 'handleError'), $handler->thrownErrors | $handler->loggedErrors);
|
||||
|
||||
if ($handlerIsNew && is_array($prev) && $prev[0] instanceof self) {
|
||||
$handler = $prev[0];
|
||||
$replace = false;
|
||||
}
|
||||
if ($replace || !$prev) {
|
||||
$handler->setExceptionHandler(set_exception_handler(array($handler, 'handleException')));
|
||||
} else {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
$handler->throwAt($levels & $handler->thrownErrors, true);
|
||||
|
||||
return $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the level at which the conversion to Exception is done.
|
||||
* Sets a logger to non assigned errors levels.
|
||||
*
|
||||
* @param int|null $level The level (null to use the error_reporting() value and 0 to disable)
|
||||
* @param LoggerInterface $logger A PSR-3 logger to put as default for the given levels
|
||||
* @param array|int $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants
|
||||
* @param bool $replace Whether to replace or not any existing logger
|
||||
*/
|
||||
public function setLevel($level)
|
||||
public function setDefaultLogger(LoggerInterface $logger, $levels = null, $replace = false)
|
||||
{
|
||||
$this->level = null === $level ? error_reporting() : $level;
|
||||
}
|
||||
$loggers = array();
|
||||
|
||||
/**
|
||||
* Sets the display_errors flag value.
|
||||
*
|
||||
* @param int $displayErrors The display_errors flag value
|
||||
*/
|
||||
public function setDisplayErrors($displayErrors)
|
||||
{
|
||||
$this->displayErrors = $displayErrors;
|
||||
if (is_array($levels)) {
|
||||
foreach ($levels as $type => $logLevel) {
|
||||
if (empty($this->loggers[$type][0]) || $replace) {
|
||||
$loggers[$type] = array($logger, $logLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a logger for the given channel.
|
||||
*
|
||||
* @param LoggerInterface $logger A logger interface
|
||||
* @param string $channel The channel associated with the logger (deprecation, emergency or scream)
|
||||
*/
|
||||
public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
|
||||
{
|
||||
self::$loggers[$channel] = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \ErrorException When error_reporting returns error
|
||||
*/
|
||||
public function handle($level, $message, $file = 'unknown', $line = 0, $context = array())
|
||||
{
|
||||
if ($level & (E_USER_DEPRECATED | E_DEPRECATED)) {
|
||||
if (isset(self::$loggers['deprecation'])) {
|
||||
if (self::$stackedErrorLevels) {
|
||||
self::$stackedErrors[] = func_get_args();
|
||||
} else {
|
||||
if (version_compare(PHP_VERSION, '5.4', '<')) {
|
||||
$stack = array_map(
|
||||
function ($row) {
|
||||
unset($row['args']);
|
||||
if (null === $levels) {
|
||||
$levels = E_ALL | E_STRICT;
|
||||
}
|
||||
foreach ($this->loggers as $type => $log) {
|
||||
if (($type & $levels) && (empty($log[0]) || $replace)) {
|
||||
$log[0] = $logger;
|
||||
$loggers[$type] = $log;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $row;
|
||||
},
|
||||
array_slice(debug_backtrace(false), 0, 10)
|
||||
);
|
||||
$this->setLoggers($loggers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a logger for each error level.
|
||||
*
|
||||
* @param array $loggers Error levels to [LoggerInterface|null, LogLevel::*] map
|
||||
*
|
||||
* @return array The previous map
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setLoggers(array $loggers)
|
||||
{
|
||||
$prevLogged = $this->loggedErrors;
|
||||
$prev = $this->loggers;
|
||||
|
||||
foreach ($loggers as $type => $log) {
|
||||
if (!isset($prev[$type])) {
|
||||
throw new \InvalidArgumentException('Unknown error type: '.$type);
|
||||
}
|
||||
if (!is_array($log)) {
|
||||
$log = array($log);
|
||||
} elseif (!array_key_exists(0, $log)) {
|
||||
throw new \InvalidArgumentException('No logger provided');
|
||||
}
|
||||
if (null === $log[0]) {
|
||||
$this->loggedErrors &= ~$type;
|
||||
} elseif ($log[0] instanceof LoggerInterface) {
|
||||
$this->loggedErrors |= $type;
|
||||
} else {
|
||||
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
|
||||
throw new \InvalidArgumentException('Invalid logger provided');
|
||||
}
|
||||
$this->loggers[$type] = $log + $prev[$type];
|
||||
}
|
||||
$this->reRegister($prevLogged | $this->thrownErrors);
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
self::$loggers['deprecation']->warning($message, array('type' => self::TYPE_DEPRECATION, 'stack' => $stack));
|
||||
/**
|
||||
* Sets a user exception handler.
|
||||
*
|
||||
* @param callable $handler A handler that will be called on Exception
|
||||
*
|
||||
* @return callable|null The previous exception handler
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setExceptionHandler($handler)
|
||||
{
|
||||
if (null !== $handler && !is_callable($handler)) {
|
||||
throw new \LogicException('The exception handler must be a valid PHP callable.');
|
||||
}
|
||||
$prev = $this->exceptionHandler;
|
||||
$this->exceptionHandler = $handler;
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
return true;
|
||||
/**
|
||||
* Sets the error levels that are to be thrown.
|
||||
*
|
||||
* @param int $levels A bit field of E_* constants for thrown errors
|
||||
* @param bool $replace Replace or amend the previous value
|
||||
*
|
||||
* @return int The previous value
|
||||
*/
|
||||
public function throwAt($levels, $replace = false)
|
||||
{
|
||||
$prev = $this->thrownErrors;
|
||||
$this->thrownErrors = ($levels | E_RECOVERABLE_ERROR | E_USER_ERROR) & ~E_USER_DEPRECATED & ~E_DEPRECATED;
|
||||
if (!$replace) {
|
||||
$this->thrownErrors |= $prev;
|
||||
}
|
||||
} elseif ($this->displayErrors && error_reporting() & $level && $this->level & $level) {
|
||||
if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && is_array($context)) {
|
||||
$c = $context; // Whatever the signature of the method,
|
||||
unset($c['GLOBALS'], $context); // $context is always a reference in 5.3
|
||||
$context = $c;
|
||||
$this->reRegister($prev | $this->loggedErrors);
|
||||
|
||||
// $this->displayErrors is @deprecated since 2.6
|
||||
$this->displayErrors = $this->thrownErrors;
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
$exception = sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line);
|
||||
if ($context && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) {
|
||||
/**
|
||||
* Sets the error levels that are logged or thrown with their local scope.
|
||||
*
|
||||
* @param int $levels A bit field of E_* constants for scoped errors
|
||||
* @param bool $replace Replace or amend the previous value
|
||||
*
|
||||
* @return int The previous value
|
||||
*/
|
||||
public function scopeAt($levels, $replace = false)
|
||||
{
|
||||
$prev = $this->scopedErrors;
|
||||
$this->scopedErrors = (int) $levels;
|
||||
if (!$replace) {
|
||||
$this->scopedErrors |= $prev;
|
||||
}
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the error levels that are logged with their stack trace.
|
||||
*
|
||||
* @param int $levels A bit field of E_* constants for traced errors
|
||||
* @param bool $replace Replace or amend the previous value
|
||||
*
|
||||
* @return int The previous value
|
||||
*/
|
||||
public function traceAt($levels, $replace = false)
|
||||
{
|
||||
$prev = $this->tracedErrors;
|
||||
$this->tracedErrors = (int) $levels;
|
||||
if (!$replace) {
|
||||
$this->tracedErrors |= $prev;
|
||||
}
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the error levels where the @-operator is ignored.
|
||||
*
|
||||
* @param int $levels A bit field of E_* constants for screamed errors
|
||||
* @param bool $replace Replace or amend the previous value
|
||||
*
|
||||
* @return int The previous value
|
||||
*/
|
||||
public function screamAt($levels, $replace = false)
|
||||
{
|
||||
$prev = $this->screamedErrors;
|
||||
$this->screamedErrors = (int) $levels;
|
||||
if (!$replace) {
|
||||
$this->screamedErrors |= $prev;
|
||||
}
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-registers as a PHP error handler if levels changed.
|
||||
*/
|
||||
private function reRegister($prev)
|
||||
{
|
||||
if ($prev !== $this->thrownErrors | $this->loggedErrors) {
|
||||
$handler = set_error_handler('var_dump', 0);
|
||||
$handler = is_array($handler) ? $handler[0] : null;
|
||||
restore_error_handler();
|
||||
if ($handler === $this) {
|
||||
restore_error_handler();
|
||||
set_error_handler(array($this, 'handleError'), $this->thrownErrors | $this->loggedErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles errors by filtering then logging them according to the configured bit fields.
|
||||
*
|
||||
* @param int $type One of the E_* constants
|
||||
* @param string $file
|
||||
* @param int $line
|
||||
* @param array $context
|
||||
*
|
||||
* @return bool Returns false when no handling happens so that the PHP engine can handle the error itself.
|
||||
*
|
||||
* @throws \ErrorException When $this->thrownErrors requests so
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function handleError($type, $message, $file, $line, array $context)
|
||||
{
|
||||
$level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR;
|
||||
$log = $this->loggedErrors & $type;
|
||||
$throw = $this->thrownErrors & $type & $level;
|
||||
$type &= $level | $this->screamedErrors;
|
||||
|
||||
if ($type && ($log || $throw)) {
|
||||
if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && ($this->scopedErrors & $type)) {
|
||||
$e = $context; // Whatever the signature of the method,
|
||||
unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
|
||||
$context = $e;
|
||||
}
|
||||
|
||||
if ($throw) {
|
||||
if (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) {
|
||||
// Checking for class existence is a work around for https://bugs.php.net/42098
|
||||
$exception = new ContextErrorException($exception, 0, $level, $file, $line, $context);
|
||||
$throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
|
||||
} else {
|
||||
$exception = new \ErrorException($exception, 0, $level, $file, $line);
|
||||
$throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) {
|
||||
|
|
@ -164,46 +376,157 @@ class ErrorHandler
|
|||
// handler and shutdown handlers are bypassed before 5.4.8/5.3.18.
|
||||
// We temporarily re-enable display_errors to prevent any blank page related to this bug.
|
||||
|
||||
$exception->errorHandlerCanary = new ErrorHandlerCanary();
|
||||
$throw->errorHandlerCanary = new ErrorHandlerCanary();
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
throw $throw;
|
||||
}
|
||||
|
||||
if (isset(self::$loggers['scream']) && !(error_reporting() & $level)) {
|
||||
if (self::$stackedErrorLevels) {
|
||||
self::$stackedErrors[] = func_get_args();
|
||||
// For duplicated errors, log the trace only once
|
||||
$e = md5("{$type}/{$line}/{$file}\x00{$message}", true);
|
||||
$trace = true;
|
||||
|
||||
if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) {
|
||||
$trace = false;
|
||||
} else {
|
||||
switch ($level) {
|
||||
case E_USER_ERROR:
|
||||
case E_RECOVERABLE_ERROR:
|
||||
$logLevel = LogLevel::ERROR;
|
||||
break;
|
||||
|
||||
case E_WARNING:
|
||||
case E_USER_WARNING:
|
||||
$logLevel = LogLevel::WARNING;
|
||||
break;
|
||||
|
||||
default:
|
||||
$logLevel = LogLevel::NOTICE;
|
||||
break;
|
||||
$this->loggedTraces[$e] = 1;
|
||||
}
|
||||
|
||||
self::$loggers['scream']->log($logLevel, $message, array(
|
||||
'type' => $level,
|
||||
'file' => $file,
|
||||
'line' => $line,
|
||||
'scream' => error_reporting(),
|
||||
));
|
||||
$e = compact('type', 'file', 'line', 'level');
|
||||
|
||||
if ($type & $level) {
|
||||
if ($this->scopedErrors & $type) {
|
||||
$e['context'] = $context;
|
||||
if ($trace) {
|
||||
$e['stack'] = debug_backtrace(true); // Provide object
|
||||
}
|
||||
} elseif ($trace) {
|
||||
$e['stack'] = debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : false);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if ($this->isRecursive) {
|
||||
$log = 0;
|
||||
} elseif (self::$stackedErrorLevels) {
|
||||
self::$stackedErrors[] = array($this->loggers[$type], $message, $e);
|
||||
} else {
|
||||
try {
|
||||
$this->isRecursive = true;
|
||||
$this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e);
|
||||
$this->isRecursive = false;
|
||||
} catch (\Exception $e) {
|
||||
$this->isRecursive = false;
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $type && $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the error handler for delayed handling.
|
||||
* Handles an exception by logging then forwarding it to an other handler.
|
||||
*
|
||||
* @param \Exception $exception An exception to handle
|
||||
* @param array $error An array as returned by error_get_last()
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function handleException(\Exception $exception, array $error = null)
|
||||
{
|
||||
$level = error_reporting();
|
||||
if ($this->loggedErrors & E_ERROR & ($level | $this->screamedErrors)) {
|
||||
$e = array(
|
||||
'type' => E_ERROR,
|
||||
'file' => $exception->getFile(),
|
||||
'line' => $exception->getLine(),
|
||||
'level' => $level,
|
||||
'stack' => $exception->getTrace(),
|
||||
);
|
||||
if ($exception instanceof FatalErrorException) {
|
||||
$message = 'Fatal '.$exception->getMessage();
|
||||
} elseif ($exception instanceof \ErrorException) {
|
||||
$message = 'Uncaught '.$exception->getMessage();
|
||||
if ($exception instanceof ContextErrorException) {
|
||||
$e['context'] = $exception->getContext();
|
||||
}
|
||||
} else {
|
||||
$message = 'Uncaught Exception: '.$exception->getMessage();
|
||||
}
|
||||
if ($this->loggedErrors & $e['type']) {
|
||||
$this->loggers[$e['type']][0]->log($this->loggers[$e['type']][1], $message, $e);
|
||||
}
|
||||
}
|
||||
if ($exception instanceof FatalErrorException && !$exception instanceof OutOfMemoryException && $error) {
|
||||
foreach ($this->getFatalErrorHandlers() as $handler) {
|
||||
if ($e = $handler->handleError($error, $exception)) {
|
||||
$exception = $e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($this->exceptionHandler)) {
|
||||
throw $exception; // Give back $exception to the native handler
|
||||
}
|
||||
try {
|
||||
call_user_func($this->exceptionHandler, $exception);
|
||||
} catch (\Exception $handlerException) {
|
||||
$this->exceptionHandler = null;
|
||||
$this->handleException($handlerException);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown registered function for handling PHP fatal errors.
|
||||
*
|
||||
* @param array $error An array as returned by error_get_last()
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function handleFatalError(array $error = null)
|
||||
{
|
||||
self::$reservedMemory = '';
|
||||
gc_collect_cycles();
|
||||
$handler = set_error_handler('var_dump', 0);
|
||||
$handler = is_array($handler) ? $handler[0] : null;
|
||||
restore_error_handler();
|
||||
if ($handler instanceof self) {
|
||||
if (null === $error) {
|
||||
$error = error_get_last();
|
||||
}
|
||||
|
||||
try {
|
||||
while (self::$stackedErrorLevels) {
|
||||
static::unstackErrors();
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
// Handled below
|
||||
}
|
||||
|
||||
if ($error && ($error['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))) {
|
||||
// Let's not throw anymore but keep logging
|
||||
$handler->throwAt(0, true);
|
||||
|
||||
if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {
|
||||
$exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false);
|
||||
} else {
|
||||
$exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true);
|
||||
}
|
||||
} elseif (!isset($exception)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$handler->handleException($exception, $error);
|
||||
} catch (FatalErrorException $e) {
|
||||
// Ignore this re-throw
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the error handler for delayed handling.
|
||||
* Ensures also that non-catchable fatal errors are never silenced.
|
||||
*
|
||||
* As shown by http://bugs.php.net/42098 and http://bugs.php.net/60724
|
||||
|
|
@ -219,7 +542,7 @@ class ErrorHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* Unstacks stacked errors and forwards to the regular handler
|
||||
* Unstacks stacked errors and forwards to the logger
|
||||
*/
|
||||
public static function unstackErrors()
|
||||
{
|
||||
|
|
@ -237,63 +560,11 @@ class ErrorHandler
|
|||
$errors = self::$stackedErrors;
|
||||
self::$stackedErrors = array();
|
||||
|
||||
$errorHandler = set_error_handler('var_dump');
|
||||
restore_error_handler();
|
||||
|
||||
if ($errorHandler) {
|
||||
foreach ($errors as $e) {
|
||||
call_user_func_array($errorHandler, $e);
|
||||
$e[0][0]->log($e[0][1], $e[1], $e[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handleFatal()
|
||||
{
|
||||
$this->reservedMemory = '';
|
||||
gc_collect_cycles();
|
||||
$error = error_get_last();
|
||||
|
||||
// get current exception handler
|
||||
$exceptionHandler = set_exception_handler('var_dump');
|
||||
restore_exception_handler();
|
||||
|
||||
try {
|
||||
while (self::$stackedErrorLevels) {
|
||||
static::unstackErrors();
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
if ($exceptionHandler) {
|
||||
call_user_func($exceptionHandler, $exception);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->displayErrors) {
|
||||
ini_set('display_errors', 1);
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
if (!$error || !$this->level || !($error['type'] & (E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_PARSE))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset(self::$loggers['emergency'])) {
|
||||
$fatal = array(
|
||||
'type' => $error['type'],
|
||||
'file' => $error['file'],
|
||||
'line' => $error['line'],
|
||||
);
|
||||
|
||||
self::$loggers['emergency']->emergency($error['message'], $fatal);
|
||||
}
|
||||
|
||||
if ($this->displayErrors && $exceptionHandler) {
|
||||
$this->handleFatalError($exceptionHandler, $error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fatal error handlers.
|
||||
|
|
@ -311,33 +582,81 @@ class ErrorHandler
|
|||
);
|
||||
}
|
||||
|
||||
private function handleFatalError($exceptionHandler, array $error)
|
||||
/**
|
||||
* Sets the level at which the conversion to Exception is done.
|
||||
*
|
||||
* @param int|null $level The level (null to use the error_reporting() value and 0 to disable)
|
||||
*
|
||||
* @deprecated since 2.6, to be removed in 3.0. Use throwAt() instead.
|
||||
*/
|
||||
public function setLevel($level)
|
||||
{
|
||||
// Let PHP handle any further error
|
||||
set_error_handler('var_dump', 0);
|
||||
ini_set('display_errors', 1);
|
||||
$level = null === $level ? error_reporting() : $level;
|
||||
$this->throwAt($level, true);
|
||||
}
|
||||
|
||||
$level = isset($this->levels[$error['type']]) ? $this->levels[$error['type']] : $error['type'];
|
||||
$message = sprintf('%s: %s in %s line %d', $level, $error['message'], $error['file'], $error['line']);
|
||||
if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {
|
||||
$exception = new OutOfMemoryException($message, 0, $error['type'], $error['file'], $error['line'], 3, false);
|
||||
/**
|
||||
* Sets the display_errors flag value.
|
||||
*
|
||||
* @param int $displayErrors The display_errors flag value
|
||||
*
|
||||
* @deprecated since 2.6, to be removed in 3.0. Use throwAt() instead.
|
||||
*/
|
||||
public function setDisplayErrors($displayErrors)
|
||||
{
|
||||
if ($displayErrors) {
|
||||
$this->throwAt($this->displayErrors, true);
|
||||
} else {
|
||||
$exception = new FatalErrorException($message, 0, $error['type'], $error['file'], $error['line'], 3, true);
|
||||
|
||||
foreach ($this->getFatalErrorHandlers() as $handler) {
|
||||
if ($e = $handler->handleError($error, $exception)) {
|
||||
$exception = $e;
|
||||
break;
|
||||
}
|
||||
$displayErrors = $this->displayErrors;
|
||||
$this->throwAt(0, true);
|
||||
$this->displayErrors = $displayErrors;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
call_user_func($exceptionHandler, $exception);
|
||||
} catch (\Exception $e) {
|
||||
// The handler failed. Let PHP handle that now.
|
||||
throw $exception;
|
||||
/**
|
||||
* Sets a logger for the given channel.
|
||||
*
|
||||
* @param LoggerInterface $logger A logger interface
|
||||
* @param string $channel The channel associated with the logger (deprecation, emergency or scream)
|
||||
*
|
||||
* @deprecated since 2.6, to be removed in 3.0. Use setLoggers() or setDefaultLogger() instead.
|
||||
*/
|
||||
public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
|
||||
{
|
||||
$handler = set_error_handler('var_dump', 0);
|
||||
$handler = is_array($handler) ? $handler[0] : null;
|
||||
restore_error_handler();
|
||||
if (!$handler instanceof self) {
|
||||
return;
|
||||
}
|
||||
if ('deprecation' === $channel) {
|
||||
$handler->setDefaultLogger($logger, E_DEPRECATED | E_USER_DEPRECATED, true);
|
||||
$handler->screamAt(E_DEPRECATED | E_USER_DEPRECATED);
|
||||
} elseif ('scream' === $channel) {
|
||||
$handler->setDefaultLogger($logger, E_ALL | E_STRICT, false);
|
||||
$handler->screamAt(E_ALL | E_STRICT);
|
||||
} elseif ('emergency' === $channel) {
|
||||
$handler->setDefaultLogger($logger, E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR, true);
|
||||
$handler->screamAt(E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.6, to be removed in 3.0. Use handleError() instead.
|
||||
*/
|
||||
public function handle($level, $message, $file = 'unknown', $line = 0, $context = array())
|
||||
{
|
||||
return $this->handleError($level, $message, $file, $line, (array) $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles PHP fatal errors.
|
||||
*
|
||||
* @deprecated since 2.6, to be removed in 3.0. Use handleFatalError() instead.
|
||||
*/
|
||||
public function handleFatal()
|
||||
{
|
||||
static::handleFatalError();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,15 +34,15 @@ if (!defined('ENT_SUBSTITUTE')) {
|
|||
class ExceptionHandler
|
||||
{
|
||||
private $debug;
|
||||
private $charset;
|
||||
private $handler;
|
||||
private $caughtBuffer;
|
||||
private $caughtLength;
|
||||
private $fileLinkFormat;
|
||||
|
||||
public function __construct($debug = true, $charset = 'UTF-8')
|
||||
public function __construct($debug = true, $fileLinkFormat = null)
|
||||
{
|
||||
$this->debug = $debug;
|
||||
$this->charset = $charset;
|
||||
$this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -52,11 +52,15 @@ class ExceptionHandler
|
|||
*
|
||||
* @return ExceptionHandler The registered exception handler
|
||||
*/
|
||||
public static function register($debug = true)
|
||||
public static function register($debug = true, $fileLinkFormat = null)
|
||||
{
|
||||
$handler = new static($debug);
|
||||
$handler = new static($debug, $fileLinkFormat = null);
|
||||
|
||||
set_exception_handler(array($handler, 'handle'));
|
||||
$prev = set_exception_handler(array($handler, 'handle'));
|
||||
if (is_array($prev) && $prev[0] instanceof ErrorHandler) {
|
||||
restore_exception_handler();
|
||||
$prev[0]->setExceptionHandler(array($handler, 'handle'));
|
||||
}
|
||||
|
||||
return $handler;
|
||||
}
|
||||
|
|
@ -79,6 +83,21 @@ class ExceptionHandler
|
|||
return $old;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the format for links to source files.
|
||||
*
|
||||
* @param string $format The format for links to source files
|
||||
*
|
||||
* @return string The previous file link format.
|
||||
*/
|
||||
public function setFileLinkFormat($format)
|
||||
{
|
||||
$old = $this->fileLinkFormat;
|
||||
$this->fileLinkFormat = $format;
|
||||
|
||||
return $old;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a response for the given Exception.
|
||||
*
|
||||
|
|
@ -205,29 +224,26 @@ class ExceptionHandler
|
|||
$total = $count + 1;
|
||||
foreach ($exception->toArray() as $position => $e) {
|
||||
$ind = $count - $position + 1;
|
||||
$class = $this->abbrClass($e['class']);
|
||||
$message = nl2br($e['message']);
|
||||
$class = $this->formatClass($e['class']);
|
||||
$message = nl2br(self::utf8Htmlize($e['message']));
|
||||
$content .= sprintf(<<<EOF
|
||||
<div class="block_exception clear_fix">
|
||||
<h2><span>%d/%d</span> %s: %s</h2>
|
||||
</div>
|
||||
<h2 class="block_exception clear_fix">
|
||||
<span class="exception_counter">%d/%d</span>
|
||||
<span class="exception_title">%s%s:</span>
|
||||
<span class="exception_message">%s</span>
|
||||
</h2>
|
||||
<div class="block">
|
||||
<ol class="traces list_exception">
|
||||
|
||||
EOF
|
||||
, $ind, $total, $class, $message);
|
||||
, $ind, $total, $class, $this->formatPath($e['trace'][0]['file'], $e['trace'][0]['line']), $message);
|
||||
foreach ($e['trace'] as $trace) {
|
||||
$content .= ' <li>';
|
||||
if ($trace['function']) {
|
||||
$content .= sprintf('at %s%s%s(%s)', $this->abbrClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
|
||||
$content .= sprintf('at %s%s%s(%s)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
|
||||
}
|
||||
if (isset($trace['file']) && isset($trace['line'])) {
|
||||
if ($linkFormat = ini_get('xdebug.file_link_format')) {
|
||||
$link = str_replace(array('%f', '%l'), array($trace['file'], $trace['line']), $linkFormat);
|
||||
$content .= sprintf(' in <a href="%s" title="Go to source">%s line %s</a>', $link, $trace['file'], $trace['line']);
|
||||
} else {
|
||||
$content .= sprintf(' in %s line %s', $trace['file'], $trace['line']);
|
||||
}
|
||||
$content .= $this->formatPath($trace['file'], $trace['line']);
|
||||
}
|
||||
$content .= "</li>\n";
|
||||
}
|
||||
|
|
@ -272,12 +288,14 @@ EOF;
|
|||
.sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; }
|
||||
.sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px }
|
||||
.sf-reset strong { font-weight:bold; }
|
||||
.sf-reset a { color:#6c6159; }
|
||||
.sf-reset a { color:#6c6159; cursor: default; }
|
||||
.sf-reset a img { border:none; }
|
||||
.sf-reset a:hover { text-decoration:underline; }
|
||||
.sf-reset em { font-style:italic; }
|
||||
.sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif }
|
||||
.sf-reset h2 span { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; }
|
||||
.sf-reset .exception_counter { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; float: left; display: block; }
|
||||
.sf-reset .exception_title { margin-left: 3em; margin-bottom: 0.7em; display: block; }
|
||||
.sf-reset .exception_message { margin-left: 3em; display: block; }
|
||||
.sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; }
|
||||
.sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px;
|
||||
-webkit-border-bottom-right-radius: 16px;
|
||||
|
|
@ -303,8 +321,8 @@ EOF;
|
|||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.sf-reset li a { background:none; color:#868686; text-decoration:none; }
|
||||
.sf-reset li a:hover { background:none; color:#313131; text-decoration:underline; }
|
||||
.sf-reset a { background:none; color:#868686; text-decoration:none; }
|
||||
.sf-reset a:hover { background:none; color:#313131; text-decoration:underline; }
|
||||
.sf-reset ol { padding: 10px 0; }
|
||||
.sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px;
|
||||
-webkit-border-radius: 10px;
|
||||
|
|
@ -321,7 +339,7 @@ EOF;
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
<style>
|
||||
/* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */
|
||||
|
|
@ -340,13 +358,27 @@ EOF;
|
|||
EOF;
|
||||
}
|
||||
|
||||
private function abbrClass($class)
|
||||
private function formatClass($class)
|
||||
{
|
||||
$parts = explode('\\', $class);
|
||||
|
||||
return sprintf("<abbr title=\"%s\">%s</abbr>", $class, array_pop($parts));
|
||||
}
|
||||
|
||||
private function formatPath($path, $line)
|
||||
{
|
||||
$path = self::utf8Htmlize($path);
|
||||
$file = preg_match('#[^/\\\\]*$#', $path, $file) ? $file[0] : $path;
|
||||
|
||||
if ($linkFormat = $this->fileLinkFormat) {
|
||||
$link = str_replace(array('%f', '%l'), array($path, $line), $linkFormat);
|
||||
|
||||
return sprintf(' in <a href="%s" title="Go to source">%s line %d</a>', $link, $file, $line);
|
||||
}
|
||||
|
||||
return sprintf(' in <a title="%s line %3$d" ondblclick="var f=this.innerHTML;this.innerHTML=this.title;this.title=f;">%s line %d</a>', $path, $file, $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an array as a string.
|
||||
*
|
||||
|
|
@ -359,11 +391,11 @@ EOF;
|
|||
$result = array();
|
||||
foreach ($args as $key => $item) {
|
||||
if ('object' === $item[0]) {
|
||||
$formattedValue = sprintf("<em>object</em>(%s)", $this->abbrClass($item[1]));
|
||||
$formattedValue = sprintf("<em>object</em>(%s)", $this->formatClass($item[1]));
|
||||
} elseif ('array' === $item[0]) {
|
||||
$formattedValue = sprintf("<em>array</em>(%s)", is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
|
||||
} elseif ('string' === $item[0]) {
|
||||
$formattedValue = sprintf("'%s'", htmlspecialchars($item[1], ENT_QUOTES | ENT_SUBSTITUTE, $this->charset));
|
||||
$formattedValue = sprintf("'%s'", self::utf8Htmlize($item[1]));
|
||||
} elseif ('null' === $item[0]) {
|
||||
$formattedValue = '<em>null</em>';
|
||||
} elseif ('boolean' === $item[0]) {
|
||||
|
|
@ -371,7 +403,7 @@ EOF;
|
|||
} elseif ('resource' === $item[0]) {
|
||||
$formattedValue = '<em>resource</em>';
|
||||
} else {
|
||||
$formattedValue = str_replace("\n", '', var_export(htmlspecialchars((string) $item[1], ENT_QUOTES | ENT_SUBSTITUTE, $this->charset), true));
|
||||
$formattedValue = str_replace("\n", '', var_export(self::utf8Htmlize((string) $item[1]), true));
|
||||
}
|
||||
|
||||
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
|
||||
|
|
@ -380,6 +412,25 @@ EOF;
|
|||
return implode(', ', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an UTF-8 and HTML encoded string
|
||||
*/
|
||||
protected static function utf8Htmlize($str)
|
||||
{
|
||||
if (!preg_match('//u', $str) && function_exists('iconv')) {
|
||||
set_error_handler('var_dump', 0);
|
||||
$charset = ini_get('default_charset');
|
||||
if ('UTF-8' === $charset || $str !== @iconv($charset, $charset, $str)) {
|
||||
$charset = 'CP1252';
|
||||
}
|
||||
restore_error_handler();
|
||||
|
||||
$str = iconv($charset, 'UTF-8', $str);
|
||||
}
|
||||
|
||||
return htmlspecialchars($str, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -51,29 +51,23 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
|
|||
if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) {
|
||||
$className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1);
|
||||
$namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex);
|
||||
$message = sprintf(
|
||||
'Attempted to load %s "%s" from namespace "%s" in %s line %d. Do you need to "use" it from another namespace?',
|
||||
$typeName,
|
||||
$className,
|
||||
$namespacePrefix,
|
||||
$error['file'],
|
||||
$error['line']
|
||||
);
|
||||
$message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix);
|
||||
$tail = ' for another namespace?';
|
||||
} else {
|
||||
$className = $fullyQualifiedClassName;
|
||||
$message = sprintf(
|
||||
'Attempted to load %s "%s" from the global namespace in %s line %d. Did you forget a use statement for this %s?',
|
||||
$typeName,
|
||||
$className,
|
||||
$error['file'],
|
||||
$error['line'],
|
||||
$typeName
|
||||
);
|
||||
$message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className);
|
||||
$tail = '?';
|
||||
}
|
||||
|
||||
if ($classes = $this->getClassCandidates($className)) {
|
||||
$message .= sprintf(' Perhaps you need to add a use statement for one of the following: %s.', implode(', ', $classes));
|
||||
if ($candidates = $this->getClassCandidates($className)) {
|
||||
$tail = array_pop($candidates).'"?';
|
||||
if ($candidates) {
|
||||
$tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail;
|
||||
} else {
|
||||
$tail = ' for "'.$tail;
|
||||
}
|
||||
}
|
||||
$message .= "\nDid you forget a \"use\" statement".$tail;
|
||||
|
||||
return new ClassNotFoundException($message, $exception);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,21 +47,10 @@ class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface
|
|||
if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedFunctionName, '\\')) {
|
||||
$functionName = substr($fullyQualifiedFunctionName, $namespaceSeparatorIndex + 1);
|
||||
$namespacePrefix = substr($fullyQualifiedFunctionName, 0, $namespaceSeparatorIndex);
|
||||
$message = sprintf(
|
||||
'Attempted to call function "%s" from namespace "%s" in %s line %d.',
|
||||
$functionName,
|
||||
$namespacePrefix,
|
||||
$error['file'],
|
||||
$error['line']
|
||||
);
|
||||
$message = sprintf('Attempted to call function "%s" from namespace "%s".', $functionName, $namespacePrefix);
|
||||
} else {
|
||||
$functionName = $fullyQualifiedFunctionName;
|
||||
$message = sprintf(
|
||||
'Attempted to call function "%s" from the global namespace in %s line %d.',
|
||||
$functionName,
|
||||
$error['file'],
|
||||
$error['line']
|
||||
);
|
||||
$message = sprintf('Attempted to call function "%s" from the global namespace.', $functionName);
|
||||
}
|
||||
|
||||
$candidates = array();
|
||||
|
|
@ -81,9 +70,13 @@ class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface
|
|||
|
||||
if ($candidates) {
|
||||
sort($candidates);
|
||||
$message .= ' Did you mean to call: '.implode(', ', array_map(function ($val) {
|
||||
return '"'.$val.'"';
|
||||
}, $candidates)).'?';
|
||||
$last = array_pop($candidates).'"?';
|
||||
if ($candidates) {
|
||||
$candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last;
|
||||
} else {
|
||||
$candidates = '"'.$last;
|
||||
}
|
||||
$message .= "\nDid you mean to call ".$candidates;
|
||||
}
|
||||
|
||||
return new UndefinedFunctionException($message, $exception);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface
|
|||
$className = $matches[1];
|
||||
$methodName = $matches[2];
|
||||
|
||||
$message = sprintf('Attempted to call method "%s" on class "%s" in %s line %d.', $methodName, $className, $error['file'], $error['line']);
|
||||
$message = sprintf('Attempted to call method "%s" on class "%s".', $methodName, $className);
|
||||
|
||||
$candidates = array();
|
||||
foreach (get_class_methods($className) as $definedMethodName) {
|
||||
|
|
@ -46,7 +46,13 @@ class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface
|
|||
|
||||
if ($candidates) {
|
||||
sort($candidates);
|
||||
$message .= sprintf(' Did you mean to call: "%s"?', implode('", "', $candidates));
|
||||
$last = array_pop($candidates).'"?';
|
||||
if ($candidates) {
|
||||
$candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last;
|
||||
} else {
|
||||
$candidates = '"'.$last;
|
||||
}
|
||||
$message .= "\nDid you mean to call ".$candidates;
|
||||
}
|
||||
|
||||
return new UndefinedMethodException($message, $exception);
|
||||
|
|
|
|||
|
|
@ -6,23 +6,26 @@ Debug provides tools to make debugging easier.
|
|||
Enabling all debug tools is as easy as calling the `enable()` method on the
|
||||
main `Debug` class:
|
||||
|
||||
```php
|
||||
use Symfony\Component\Debug\Debug;
|
||||
|
||||
Debug::enable();
|
||||
```
|
||||
|
||||
You can also use the tools individually:
|
||||
|
||||
```php
|
||||
use Symfony\Component\Debug\ErrorHandler;
|
||||
use Symfony\Component\Debug\ExceptionHandler;
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
ErrorHandler::register($errorReportingLevel);
|
||||
if ('cli' !== php_sapi_name()) {
|
||||
ini_set('display_errors', 0);
|
||||
ExceptionHandler::register();
|
||||
} elseif (!ini_get('log_errors') || ini_get('error_log')) {
|
||||
ini_set('display_errors', 1);
|
||||
}
|
||||
ErrorHandler::register($errorReportingLevel);
|
||||
```
|
||||
|
||||
Note that the `Debug::enable()` call also registers the debug class loader
|
||||
from the Symfony ClassLoader component when available.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
Symfony Debug Extension
|
||||
=======================
|
||||
|
||||
This extension adds a ``symfony_zval_info($key, $array, $options = 0)`` function that:
|
||||
|
||||
- exposes zval_hash/refcounts, allowing e.g. efficient exploration of arbitrary structures in PHP,
|
||||
- does work with references, preventing memory copying.
|
||||
|
||||
Its behavior is about the same as:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
function symfony_zval_info($key, $array, $options = 0)
|
||||
{
|
||||
// $options is currently not used, but could be in future version.
|
||||
|
||||
if (!array_key_exists($key, $array)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$info = array(
|
||||
'type' => gettype($array[$key]),
|
||||
'zval_hash' => /* hashed memory address of $array[$key] */,
|
||||
'zval_refcount' => /* internal zval refcount of $array[$key] */,
|
||||
'zval_isref' => /* is_ref status of $array[$key] */,
|
||||
);
|
||||
|
||||
switch ($info['type']) {
|
||||
case 'object':
|
||||
$info += array(
|
||||
'object_class' => get_class($array[$key]),
|
||||
'object_refcount' => /* internal object refcount of $array[$key] */,
|
||||
'object_hash' => spl_object_hash($array[$key]),
|
||||
'object_handle' => /* internal object handle $array[$key] */,
|
||||
);
|
||||
break;
|
||||
|
||||
case 'resource':
|
||||
$info += array(
|
||||
'resource_handle' => (int) $array[$key],
|
||||
'resource_type' => get_resource_type($array[$key]),
|
||||
'resource_refcount' => /* internal resource refcount of $array[$key] */,
|
||||
);
|
||||
break;
|
||||
|
||||
case 'array':
|
||||
$info += array(
|
||||
'array_count' => count($array[$key]),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
$info += array(
|
||||
'strlen' => strlen($array[$key]),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
To enable the extension from source, run:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
phpize
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
dnl $Id$
|
||||
dnl config.m4 for extension symfony_debug
|
||||
|
||||
dnl Comments in this file start with the string 'dnl'.
|
||||
dnl Remove where necessary. This file will not work
|
||||
dnl without editing.
|
||||
|
||||
dnl If your extension references something external, use with:
|
||||
|
||||
dnl PHP_ARG_WITH(symfony_debug, for symfony_debug support,
|
||||
dnl Make sure that the comment is aligned:
|
||||
dnl [ --with-symfony_debug Include symfony_debug support])
|
||||
|
||||
dnl Otherwise use enable:
|
||||
|
||||
PHP_ARG_ENABLE(symfony_debug, whether to enable symfony_debug support,
|
||||
dnl Make sure that the comment is aligned:
|
||||
[ --enable-symfony_debug Enable symfony_debug support])
|
||||
|
||||
if test "$PHP_SYMFONY_DEBUG" != "no"; then
|
||||
dnl Write more examples of tests here...
|
||||
|
||||
dnl # --with-symfony_debug -> check with-path
|
||||
dnl SEARCH_PATH="/usr/local /usr" # you might want to change this
|
||||
dnl SEARCH_FOR="/include/symfony_debug.h" # you most likely want to change this
|
||||
dnl if test -r $PHP_SYMFONY_DEBUG/$SEARCH_FOR; then # path given as parameter
|
||||
dnl SYMFONY_DEBUG_DIR=$PHP_SYMFONY_DEBUG
|
||||
dnl else # search default path list
|
||||
dnl AC_MSG_CHECKING([for symfony_debug files in default path])
|
||||
dnl for i in $SEARCH_PATH ; do
|
||||
dnl if test -r $i/$SEARCH_FOR; then
|
||||
dnl SYMFONY_DEBUG_DIR=$i
|
||||
dnl AC_MSG_RESULT(found in $i)
|
||||
dnl fi
|
||||
dnl done
|
||||
dnl fi
|
||||
dnl
|
||||
dnl if test -z "$SYMFONY_DEBUG_DIR"; then
|
||||
dnl AC_MSG_RESULT([not found])
|
||||
dnl AC_MSG_ERROR([Please reinstall the symfony_debug distribution])
|
||||
dnl fi
|
||||
|
||||
dnl # --with-symfony_debug -> add include path
|
||||
dnl PHP_ADD_INCLUDE($SYMFONY_DEBUG_DIR/include)
|
||||
|
||||
dnl # --with-symfony_debug -> check for lib and symbol presence
|
||||
dnl LIBNAME=symfony_debug # you may want to change this
|
||||
dnl LIBSYMBOL=symfony_debug # you most likely want to change this
|
||||
|
||||
dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
|
||||
dnl [
|
||||
dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $SYMFONY_DEBUG_DIR/lib, SYMFONY_DEBUG_SHARED_LIBADD)
|
||||
dnl AC_DEFINE(HAVE_SYMFONY_DEBUGLIB,1,[ ])
|
||||
dnl ],[
|
||||
dnl AC_MSG_ERROR([wrong symfony_debug lib version or lib not found])
|
||||
dnl ],[
|
||||
dnl -L$SYMFONY_DEBUG_DIR/lib -lm
|
||||
dnl ])
|
||||
dnl
|
||||
dnl PHP_SUBST(SYMFONY_DEBUG_SHARED_LIBADD)
|
||||
|
||||
PHP_NEW_EXTENSION(symfony_debug, symfony_debug.c, $ext_shared)
|
||||
fi
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
// If your extension references something external, use ARG_WITH
|
||||
// ARG_WITH("symfony_debug", "for symfony_debug support", "no");
|
||||
|
||||
// Otherwise, use ARG_ENABLE
|
||||
// ARG_ENABLE("symfony_debug", "enable symfony_debug support", "no");
|
||||
|
||||
if (PHP_SYMFONY_DEBUG != "no") {
|
||||
EXTENSION("symfony_debug", "symfony_debug.c");
|
||||
}
|
||||
|
||||
55
core/vendor/symfony/debug/Symfony/Component/Debug/Resources/ext/php_symfony_debug.h
vendored
Normal file
55
core/vendor/symfony/debug/Symfony/Component/Debug/Resources/ext/php_symfony_debug.h
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#ifndef PHP_SYMFONY_DEBUG_H
|
||||
#define PHP_SYMFONY_DEBUG_H
|
||||
|
||||
extern zend_module_entry symfony_debug_module_entry;
|
||||
#define phpext_symfony_debug_ptr &symfony_debug_module_entry
|
||||
|
||||
#define PHP_SYMFONY_DEBUG_VERSION "1.0"
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# define PHP_SYMFONY_DEBUG_API __declspec(dllexport)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define PHP_SYMFONY_DEBUG_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
# define PHP_SYMFONY_DEBUG_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(symfony_debug)
|
||||
intptr_t req_rand_init;
|
||||
ZEND_END_MODULE_GLOBALS(symfony_debug)
|
||||
|
||||
PHP_MINIT_FUNCTION(symfony_debug);
|
||||
PHP_MSHUTDOWN_FUNCTION(symfony_debug);
|
||||
PHP_RINIT_FUNCTION(symfony_debug);
|
||||
PHP_RSHUTDOWN_FUNCTION(symfony_debug);
|
||||
PHP_MINFO_FUNCTION(symfony_debug);
|
||||
PHP_GINIT_FUNCTION(symfony_debug);
|
||||
PHP_GSHUTDOWN_FUNCTION(symfony_debug);
|
||||
|
||||
PHP_FUNCTION(symfony_zval_info);
|
||||
|
||||
static char *_symfony_debug_memory_address_hash(void *);
|
||||
static const char *_symfony_debug_zval_type(zval *);
|
||||
static const char* _symfony_debug_get_resource_type(long);
|
||||
static int _symfony_debug_get_resource_refcount(long);
|
||||
|
||||
#ifdef ZTS
|
||||
#define SYMFONY_DEBUG_G(v) TSRMG(symfony_debug_globals_id, zend_symfony_debug_globals *, v)
|
||||
#else
|
||||
#define SYMFONY_DEBUG_G(v) (symfony_debug_globals.v)
|
||||
#endif
|
||||
|
||||
#endif /* PHP_SYMFONY_DEBUG_H */
|
||||
224
core/vendor/symfony/debug/Symfony/Component/Debug/Resources/ext/symfony_debug.c
vendored
Normal file
224
core/vendor/symfony/debug/Symfony/Component/Debug/Resources/ext/symfony_debug.c
vendored
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "php_symfony_debug.h"
|
||||
#include "ext/standard/php_rand.h"
|
||||
#include "ext/standard/php_lcg.h"
|
||||
#include "ext/spl/php_spl.h"
|
||||
#include "Zend/zend_gc.h"
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(symfony_debug)
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(symfony_zval_arginfo, 0, 0, 2)
|
||||
ZEND_ARG_INFO(0, key)
|
||||
ZEND_ARG_ARRAY_INFO(0, array, 0)
|
||||
ZEND_ARG_INFO(0, options)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
const zend_function_entry symfony_debug_functions[] = {
|
||||
PHP_FE(symfony_zval_info, symfony_zval_arginfo)
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
PHP_FUNCTION(symfony_zval_info)
|
||||
{
|
||||
zval *key = NULL, *arg = NULL;
|
||||
zval **data = NULL;
|
||||
HashTable *array = NULL;
|
||||
long options = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zh|l", &key, &array, &options) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Z_TYPE_P(key)) {
|
||||
case IS_STRING:
|
||||
if (zend_symtable_find(array, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&data) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case IS_LONG:
|
||||
if (zend_hash_index_find(array, Z_LVAL_P(key), (void **)&data)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
arg = *data;
|
||||
|
||||
array_init(return_value);
|
||||
|
||||
add_assoc_string(return_value, "type", (char *)_symfony_debug_zval_type(arg), 1);
|
||||
add_assoc_stringl(return_value, "zval_hash", _symfony_debug_memory_address_hash((void *)arg), 16, 1);
|
||||
add_assoc_long(return_value, "zval_refcount", Z_REFCOUNT_P(arg));
|
||||
add_assoc_bool(return_value, "zval_isref", (zend_bool)Z_ISREF_P(arg));
|
||||
|
||||
if (Z_TYPE_P(arg) == IS_OBJECT) {
|
||||
static char hash[33] = {0};
|
||||
php_spl_object_hash(arg, (char *)hash);
|
||||
add_assoc_stringl(return_value, "object_class", (char *)Z_OBJCE_P(arg)->name, Z_OBJCE_P(arg)->name_length, 1);
|
||||
add_assoc_long(return_value, "object_refcount", EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(arg)].bucket.obj.refcount);
|
||||
add_assoc_string(return_value, "object_hash", hash, 1);
|
||||
add_assoc_long(return_value, "object_handle", Z_OBJ_HANDLE_P(arg));
|
||||
} else if (Z_TYPE_P(arg) == IS_ARRAY) {
|
||||
add_assoc_long(return_value, "array_count", zend_hash_num_elements(Z_ARRVAL_P(arg)));
|
||||
} else if(Z_TYPE_P(arg) == IS_RESOURCE) {
|
||||
add_assoc_long(return_value, "resource_handle", Z_LVAL_P(arg));
|
||||
add_assoc_string(return_value, "resource_type", (char *)_symfony_debug_get_resource_type(Z_LVAL_P(arg)), 1);
|
||||
add_assoc_long(return_value, "resource_refcount", _symfony_debug_get_resource_refcount(Z_LVAL_P(arg)));
|
||||
} else if (Z_TYPE_P(arg) == IS_STRING) {
|
||||
add_assoc_long(return_value, "strlen", Z_STRLEN_P(arg));
|
||||
}
|
||||
}
|
||||
|
||||
static const char* _symfony_debug_get_resource_type(long rsid)
|
||||
{
|
||||
const char *res_type;
|
||||
res_type = zend_rsrc_list_get_rsrc_type(rsid);
|
||||
|
||||
if (!res_type) {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
return res_type;
|
||||
}
|
||||
|
||||
static int _symfony_debug_get_resource_refcount(long rsid)
|
||||
{
|
||||
zend_rsrc_list_entry *le;
|
||||
|
||||
if (zend_hash_index_find(&EG(regular_list), rsid, (void **) &le)==SUCCESS) {
|
||||
return le->refcount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *_symfony_debug_memory_address_hash(void *address)
|
||||
{
|
||||
static char result[17] = {0};
|
||||
intptr_t address_rand;
|
||||
|
||||
if (!SYMFONY_DEBUG_G(req_rand_init)) {
|
||||
if (!BG(mt_rand_is_seeded)) {
|
||||
php_mt_srand(GENERATE_SEED() TSRMLS_CC);
|
||||
}
|
||||
SYMFONY_DEBUG_G(req_rand_init) = (intptr_t)php_mt_rand();
|
||||
}
|
||||
|
||||
address_rand = (intptr_t)address ^ SYMFONY_DEBUG_G(req_rand_init);
|
||||
|
||||
snprintf(result, 17, "%016zx", address_rand);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const char *_symfony_debug_zval_type(zval *zv)
|
||||
{
|
||||
switch (Z_TYPE_P(zv)) {
|
||||
case IS_NULL:
|
||||
return "NULL";
|
||||
break;
|
||||
|
||||
case IS_BOOL:
|
||||
return "boolean";
|
||||
break;
|
||||
|
||||
case IS_LONG:
|
||||
return "integer";
|
||||
break;
|
||||
|
||||
case IS_DOUBLE:
|
||||
return "double";
|
||||
break;
|
||||
|
||||
case IS_STRING:
|
||||
return "string";
|
||||
break;
|
||||
|
||||
case IS_ARRAY:
|
||||
return "array";
|
||||
break;
|
||||
|
||||
case IS_OBJECT:
|
||||
return "object";
|
||||
|
||||
case IS_RESOURCE:
|
||||
return "resource";
|
||||
|
||||
default:
|
||||
return "unknown type";
|
||||
}
|
||||
}
|
||||
|
||||
zend_module_entry symfony_debug_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"symfony_debug",
|
||||
symfony_debug_functions,
|
||||
PHP_MINIT(symfony_debug),
|
||||
PHP_MSHUTDOWN(symfony_debug),
|
||||
PHP_RINIT(symfony_debug),
|
||||
PHP_RSHUTDOWN(symfony_debug),
|
||||
PHP_MINFO(symfony_debug),
|
||||
PHP_SYMFONY_DEBUG_VERSION,
|
||||
PHP_MODULE_GLOBALS(symfony_debug),
|
||||
PHP_GINIT(symfony_debug),
|
||||
PHP_GSHUTDOWN(symfony_debug),
|
||||
NULL,
|
||||
STANDARD_MODULE_PROPERTIES_EX
|
||||
};
|
||||
|
||||
#ifdef COMPILE_DL_SYMFONY_DEBUG
|
||||
ZEND_GET_MODULE(symfony_debug)
|
||||
#endif
|
||||
|
||||
PHP_GINIT_FUNCTION(symfony_debug)
|
||||
{
|
||||
symfony_debug_globals->req_rand_init = 0;
|
||||
}
|
||||
|
||||
PHP_GSHUTDOWN_FUNCTION(symfony_debug)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PHP_MINIT_FUNCTION(symfony_debug)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
PHP_MSHUTDOWN_FUNCTION(symfony_debug)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
PHP_RINIT_FUNCTION(symfony_debug)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
PHP_RSHUTDOWN_FUNCTION(symfony_debug)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
PHP_MINFO_FUNCTION(symfony_debug)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "Symfony Debug support", "enabled");
|
||||
php_info_print_table_header(2, "Symfony Debug version", PHP_SYMFONY_DEBUG_VERSION);
|
||||
php_info_print_table_end();
|
||||
}
|
||||
151
core/vendor/symfony/debug/Symfony/Component/Debug/Resources/ext/tests/001.phpt
vendored
Normal file
151
core/vendor/symfony/debug/Symfony/Component/Debug/Resources/ext/tests/001.phpt
vendored
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
--TEST--
|
||||
Test symfony_zval_info API
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("symfony_debug")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$int = 42;
|
||||
$float = 42.42;
|
||||
$str = "foobar";
|
||||
$object = new StdClass;
|
||||
$array = array('foo', 'bar');
|
||||
$resource = tmpfile();
|
||||
$null = null;
|
||||
$bool = true;
|
||||
|
||||
$anotherint = 42;
|
||||
$refcount2 = &$anotherint;
|
||||
|
||||
$var = array('int' => $int,
|
||||
'float' => $float,
|
||||
'str' => $str,
|
||||
'object' => $object,
|
||||
'array' => $array,
|
||||
'resource' => $resource,
|
||||
'null' => $null,
|
||||
'bool' => $bool,
|
||||
'refcount' => &$refcount2);
|
||||
|
||||
var_dump(symfony_zval_info('int', $var));
|
||||
var_dump(symfony_zval_info('float', $var));
|
||||
var_dump(symfony_zval_info('str', $var));
|
||||
var_dump(symfony_zval_info('object', $var));
|
||||
var_dump(symfony_zval_info('array', $var));
|
||||
var_dump(symfony_zval_info('resource', $var));
|
||||
var_dump(symfony_zval_info('null', $var));
|
||||
var_dump(symfony_zval_info('bool', $var));
|
||||
|
||||
var_dump(symfony_zval_info('refcount', $var));
|
||||
var_dump(symfony_zval_info('not-exist', $var));
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(4) {
|
||||
["type"]=>
|
||||
string(7) "integer"
|
||||
["zval_hash"]=>
|
||||
string(16) "%s"
|
||||
["zval_refcount"]=>
|
||||
int(2)
|
||||
["zval_isref"]=>
|
||||
bool(false)
|
||||
}
|
||||
array(4) {
|
||||
["type"]=>
|
||||
string(6) "double"
|
||||
["zval_hash"]=>
|
||||
string(16) "%s"
|
||||
["zval_refcount"]=>
|
||||
int(2)
|
||||
["zval_isref"]=>
|
||||
bool(false)
|
||||
}
|
||||
array(5) {
|
||||
["type"]=>
|
||||
string(6) "string"
|
||||
["zval_hash"]=>
|
||||
string(16) "%s"
|
||||
["zval_refcount"]=>
|
||||
int(2)
|
||||
["zval_isref"]=>
|
||||
bool(false)
|
||||
["strlen"]=>
|
||||
int(6)
|
||||
}
|
||||
array(8) {
|
||||
["type"]=>
|
||||
string(6) "object"
|
||||
["zval_hash"]=>
|
||||
string(16) "%s"
|
||||
["zval_refcount"]=>
|
||||
int(2)
|
||||
["zval_isref"]=>
|
||||
bool(false)
|
||||
["object_class"]=>
|
||||
string(8) "stdClass"
|
||||
["object_refcount"]=>
|
||||
int(1)
|
||||
["object_hash"]=>
|
||||
string(32) "%s"
|
||||
["object_handle"]=>
|
||||
int(1)
|
||||
}
|
||||
array(5) {
|
||||
["type"]=>
|
||||
string(5) "array"
|
||||
["zval_hash"]=>
|
||||
string(16) "%s"
|
||||
["zval_refcount"]=>
|
||||
int(2)
|
||||
["zval_isref"]=>
|
||||
bool(false)
|
||||
["array_count"]=>
|
||||
int(2)
|
||||
}
|
||||
array(7) {
|
||||
["type"]=>
|
||||
string(8) "resource"
|
||||
["zval_hash"]=>
|
||||
string(16) "%s"
|
||||
["zval_refcount"]=>
|
||||
int(2)
|
||||
["zval_isref"]=>
|
||||
bool(false)
|
||||
["resource_handle"]=>
|
||||
int(4)
|
||||
["resource_type"]=>
|
||||
string(6) "stream"
|
||||
["resource_refcount"]=>
|
||||
int(1)
|
||||
}
|
||||
array(4) {
|
||||
["type"]=>
|
||||
string(4) "NULL"
|
||||
["zval_hash"]=>
|
||||
string(16) "%s"
|
||||
["zval_refcount"]=>
|
||||
int(2)
|
||||
["zval_isref"]=>
|
||||
bool(false)
|
||||
}
|
||||
array(4) {
|
||||
["type"]=>
|
||||
string(7) "boolean"
|
||||
["zval_hash"]=>
|
||||
string(16) "%s"
|
||||
["zval_refcount"]=>
|
||||
int(2)
|
||||
["zval_isref"]=>
|
||||
bool(false)
|
||||
}
|
||||
array(4) {
|
||||
["type"]=>
|
||||
string(7) "integer"
|
||||
["zval_hash"]=>
|
||||
string(16) "%s"
|
||||
["zval_refcount"]=>
|
||||
int(3)
|
||||
["zval_isref"]=>
|
||||
bool(true)
|
||||
}
|
||||
NULL
|
||||
|
|
@ -106,11 +106,11 @@ class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals(E_STRICT, $exception->getSeverity());
|
||||
$this->assertStringStartsWith(__FILE__, $exception->getFile());
|
||||
$this->assertRegexp('/^Runtime Notice: Declaration/', $exception->getMessage());
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Exception $exception) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
throw $e;
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Symfony\Component\Debug\Tests;
|
||||
|
||||
use Psr\Log\LogLevel;
|
||||
use Symfony\Component\Debug\ErrorHandler;
|
||||
use Symfony\Component\Debug\Exception\ContextErrorException;
|
||||
|
||||
|
|
@ -18,6 +19,7 @@ use Symfony\Component\Debug\Exception\ContextErrorException;
|
|||
* ErrorHandlerTest
|
||||
*
|
||||
* @author Robert Schönthal <seroscho@googlemail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
|
@ -44,6 +46,46 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
error_reporting($this->errorReporting);
|
||||
}
|
||||
|
||||
public function testRegister()
|
||||
{
|
||||
$handler = ErrorHandler::register();
|
||||
|
||||
try {
|
||||
$this->assertInstanceOf('Symfony\Component\Debug\ErrorHandler', $handler);
|
||||
$this->assertSame($handler, ErrorHandler::register());
|
||||
|
||||
$newHandler = new ErrorHandler();
|
||||
|
||||
$this->assertSame($newHandler, ErrorHandler::register($newHandler, false));
|
||||
$h = set_error_handler('var_dump');
|
||||
restore_error_handler();
|
||||
$this->assertSame(array($handler, 'handleError'), $h);
|
||||
|
||||
try {
|
||||
$this->assertSame($newHandler, ErrorHandler::register($newHandler, true));
|
||||
$h = set_error_handler('var_dump');
|
||||
restore_error_handler();
|
||||
$this->assertSame(array($newHandler, 'handleError'), $h);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
if (isset($e)) {
|
||||
throw $e;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
if (isset($e)) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function testNotice()
|
||||
{
|
||||
ErrorHandler::register();
|
||||
|
|
@ -54,6 +96,8 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
} catch (ContextErrorException $exception) {
|
||||
// if an exception is thrown, the test passed
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
$this->assertEquals(E_NOTICE, $exception->getSeverity());
|
||||
$this->assertEquals(__FILE__, $exception->getFile());
|
||||
$this->assertRegexp('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());
|
||||
|
|
@ -62,7 +106,7 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
$trace = $exception->getTrace();
|
||||
$this->assertEquals(__FILE__, $trace[0]['file']);
|
||||
$this->assertEquals('Symfony\Component\Debug\ErrorHandler', $trace[0]['class']);
|
||||
$this->assertEquals('handle', $trace[0]['function']);
|
||||
$this->assertEquals('handleError', $trace[0]['function']);
|
||||
$this->assertEquals('->', $trace[0]['type']);
|
||||
|
||||
$this->assertEquals(__FILE__, $trace[1]['file']);
|
||||
|
|
@ -70,16 +114,16 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals('triggerNotice', $trace[1]['function']);
|
||||
$this->assertEquals('::', $trace[1]['type']);
|
||||
|
||||
$this->assertEquals(__FILE__, $trace[1]['file']);
|
||||
$this->assertEquals(__CLASS__, $trace[2]['class']);
|
||||
$this->assertEquals('testNotice', $trace[2]['function']);
|
||||
$this->assertEquals(__FUNCTION__, $trace[2]['function']);
|
||||
$this->assertEquals('->', $trace[2]['type']);
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
// dummy function to test trace in error handler.
|
||||
|
|
@ -93,78 +137,257 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
public function testConstruct()
|
||||
{
|
||||
try {
|
||||
$handler = ErrorHandler::register(3);
|
||||
|
||||
$level = new \ReflectionProperty($handler, 'level');
|
||||
$level->setAccessible(true);
|
||||
|
||||
$this->assertEquals(3, $level->getValue($handler));
|
||||
$handler = ErrorHandler::register();
|
||||
$handler->throwAt(3, true);
|
||||
$this->assertEquals(3 | E_RECOVERABLE_ERROR | E_USER_ERROR, $handler->throwAt(0));
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function testHandle()
|
||||
public function testDefaultLogger()
|
||||
{
|
||||
try {
|
||||
$handler = ErrorHandler::register(0);
|
||||
$this->assertFalse($handler->handle(0, 'foo', 'foo.php', 12, array()));
|
||||
$handler = ErrorHandler::register();
|
||||
|
||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
||||
|
||||
$handler->setDefaultLogger($logger, E_NOTICE);
|
||||
$handler->setDefaultLogger($logger, array(E_USER_NOTICE => LogLevel::CRITICAL));
|
||||
|
||||
$loggers = array(
|
||||
E_DEPRECATED => array(null, LogLevel::INFO),
|
||||
E_USER_DEPRECATED => array(null, LogLevel::INFO),
|
||||
E_NOTICE => array($logger, LogLevel::NOTICE),
|
||||
E_USER_NOTICE => array($logger, LogLevel::CRITICAL),
|
||||
E_STRICT => array(null, LogLevel::NOTICE),
|
||||
E_WARNING => array(null, LogLevel::WARNING),
|
||||
E_USER_WARNING => array(null, LogLevel::WARNING),
|
||||
E_COMPILE_WARNING => array(null, LogLevel::WARNING),
|
||||
E_CORE_WARNING => array(null, LogLevel::WARNING),
|
||||
E_USER_ERROR => array(null, LogLevel::ERROR),
|
||||
E_RECOVERABLE_ERROR => array(null, LogLevel::ERROR),
|
||||
E_COMPILE_ERROR => array(null, LogLevel::EMERGENCY),
|
||||
E_PARSE => array(null, LogLevel::EMERGENCY),
|
||||
E_ERROR => array(null, LogLevel::EMERGENCY),
|
||||
E_CORE_ERROR => array(null, LogLevel::EMERGENCY),
|
||||
);
|
||||
$this->assertSame($loggers, $handler->setLoggers(array()));
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
$handler = ErrorHandler::register(3);
|
||||
$this->assertFalse($handler->handle(4, 'foo', 'foo.php', 12, array()));
|
||||
|
||||
restore_exception_handler();
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
$handler = ErrorHandler::register(3);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function testHandleError()
|
||||
{
|
||||
try {
|
||||
$handler->handle(111, 'foo', 'foo.php', 12, array());
|
||||
$handler = ErrorHandler::register();
|
||||
$handler->throwAt(0, true);
|
||||
$this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, array()));
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
$handler = ErrorHandler::register();
|
||||
$handler->throwAt(3, true);
|
||||
$this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, array()));
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
$handler = ErrorHandler::register();
|
||||
$handler->throwAt(3, true);
|
||||
try {
|
||||
$handler->handleError(4, 'foo', 'foo.php', 12, array());
|
||||
} catch (\ErrorException $e) {
|
||||
$this->assertSame('111: foo in foo.php line 12', $e->getMessage());
|
||||
$this->assertSame(111, $e->getSeverity());
|
||||
$this->assertSame('Parse Error: foo', $e->getMessage());
|
||||
$this->assertSame(4, $e->getSeverity());
|
||||
$this->assertSame('foo.php', $e->getFile());
|
||||
$this->assertSame(12, $e->getLine());
|
||||
}
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
$handler = ErrorHandler::register(E_USER_DEPRECATED);
|
||||
$this->assertFalse($handler->handle(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array()));
|
||||
$handler = ErrorHandler::register();
|
||||
$handler->throwAt(E_USER_DEPRECATED, true);
|
||||
$this->assertFalse($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array()));
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
$handler = ErrorHandler::register(E_DEPRECATED);
|
||||
$this->assertFalse($handler->handle(E_DEPRECATED, 'foo', 'foo.php', 12, array()));
|
||||
$handler = ErrorHandler::register();
|
||||
$handler->throwAt(E_DEPRECATED, true);
|
||||
$this->assertFalse($handler->handleError(E_DEPRECATED, 'foo', 'foo.php', 12, array()));
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
||||
|
||||
$that = $this;
|
||||
$warnArgCheck = function ($message, $context) use ($that) {
|
||||
$warnArgCheck = function ($logLevel, $message, $context) use ($that) {
|
||||
$that->assertEquals('info', $logLevel);
|
||||
$that->assertEquals('foo', $message);
|
||||
$that->assertArrayHasKey('type', $context);
|
||||
$that->assertEquals($context['type'], ErrorHandler::TYPE_DEPRECATION);
|
||||
$that->assertEquals($context['type'], E_USER_DEPRECATED);
|
||||
$that->assertArrayHasKey('stack', $context);
|
||||
$that->assertInternalType('array', $context['stack']);
|
||||
};
|
||||
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('warning')
|
||||
->method('log')
|
||||
->will($this->returnCallback($warnArgCheck))
|
||||
;
|
||||
|
||||
$handler = ErrorHandler::register(E_USER_DEPRECATED);
|
||||
$handler->setLogger($logger);
|
||||
$this->assertTrue($handler->handle(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array()));
|
||||
$handler = ErrorHandler::register();
|
||||
$handler->setDefaultLogger($logger, E_USER_DEPRECATED);
|
||||
$this->assertTrue($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array()));
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
||||
|
||||
$that = $this;
|
||||
$logArgCheck = function ($level, $message, $context) use ($that) {
|
||||
$that->assertEquals('Undefined variable: undefVar', $message);
|
||||
$that->assertArrayHasKey('type', $context);
|
||||
$that->assertEquals($context['type'], E_NOTICE);
|
||||
};
|
||||
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('log')
|
||||
->will($this->returnCallback($logArgCheck))
|
||||
;
|
||||
|
||||
$handler = ErrorHandler::register();
|
||||
$handler->setDefaultLogger($logger, E_NOTICE);
|
||||
$handler->screamAt(E_NOTICE);
|
||||
unset($undefVar);
|
||||
@$undefVar++;
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function testHandleException()
|
||||
{
|
||||
try {
|
||||
$handler = ErrorHandler::register();
|
||||
|
||||
$exception = new \Exception('foo');
|
||||
|
||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
||||
|
||||
$that = $this;
|
||||
$logArgCheck = function ($level, $message, $context) use ($that) {
|
||||
$that->assertEquals('Uncaught Exception: foo', $message);
|
||||
$that->assertArrayHasKey('type', $context);
|
||||
$that->assertEquals($context['type'], E_ERROR);
|
||||
};
|
||||
|
||||
$logger
|
||||
->expects($this->exactly(2))
|
||||
->method('log')
|
||||
->will($this->returnCallback($logArgCheck))
|
||||
;
|
||||
|
||||
$handler->setDefaultLogger($logger, E_ERROR);
|
||||
|
||||
try {
|
||||
$handler->handleException($exception);
|
||||
$this->fail('Exception expected');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertSame($exception, $e);
|
||||
}
|
||||
|
||||
$that = $this;
|
||||
$handler->setExceptionHandler(function ($e) use ($exception, $that) {
|
||||
$that->assertSame($exception, $e);
|
||||
});
|
||||
|
||||
$handler->handleException($exception);
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function testHandleFatalError()
|
||||
{
|
||||
try {
|
||||
$handler = ErrorHandler::register();
|
||||
|
||||
$error = array(
|
||||
'type' => E_PARSE,
|
||||
'message' => 'foo',
|
||||
'file' => 'bar',
|
||||
'line' => 123,
|
||||
);
|
||||
|
||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
||||
|
||||
$that = $this;
|
||||
$logArgCheck = function ($level, $message, $context) use ($that) {
|
||||
$that->assertEquals('Fatal Parse Error: foo', $message);
|
||||
$that->assertArrayHasKey('type', $context);
|
||||
$that->assertEquals($context['type'], E_ERROR);
|
||||
};
|
||||
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('log')
|
||||
->will($this->returnCallback($logArgCheck))
|
||||
;
|
||||
|
||||
$handler->setDefaultLogger($logger, E_ERROR);
|
||||
|
||||
$handler->handleFatalError($error);
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function testDeprecatedInterface()
|
||||
{
|
||||
try {
|
||||
$handler = ErrorHandler::register(0);
|
||||
$this->assertFalse($handler->handle(0, 'foo', 'foo.php', 12, array()));
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
||||
|
||||
|
|
@ -187,63 +410,12 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
@$undefVar++;
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFatalErrorHandlersData
|
||||
*/
|
||||
public function testFatalErrorHandlers($error, $class, $translatedMessage)
|
||||
{
|
||||
$handler = new ErrorHandler();
|
||||
$exceptionHandler = new MockExceptionHandler();
|
||||
|
||||
$m = new \ReflectionMethod($handler, 'handleFatalError');
|
||||
$m->setAccessible(true);
|
||||
$m->invoke($handler, array($exceptionHandler, 'handle'), $error);
|
||||
|
||||
restore_error_handler();
|
||||
$this->assertInstanceof($class, $exceptionHandler->e);
|
||||
// class names are case insensitive and PHP/HHVM do not return the same
|
||||
$this->assertSame(strtolower($translatedMessage), strtolower($exceptionHandler->e->getMessage()));
|
||||
$this->assertSame($error['type'], $exceptionHandler->e->getSeverity());
|
||||
$this->assertSame($error['file'], $exceptionHandler->e->getFile());
|
||||
$this->assertSame($error['line'], $exceptionHandler->e->getLine());
|
||||
}
|
||||
|
||||
public function provideFatalErrorHandlersData()
|
||||
{
|
||||
return array(
|
||||
// undefined function
|
||||
array(
|
||||
array(
|
||||
'type' => 1,
|
||||
'line' => 12,
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined function test_namespaced_function_again()',
|
||||
),
|
||||
'Symfony\Component\Debug\Exception\UndefinedFunctionException',
|
||||
'Attempted to call function "test_namespaced_function_again" from the global namespace in foo.php line 12. Did you mean to call: "\\symfony\\component\\debug\\tests\\test_namespaced_function_again"?',
|
||||
),
|
||||
// class not found
|
||||
array(
|
||||
array(
|
||||
'type' => 1,
|
||||
'line' => 12,
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Class \'WhizBangFactory\' not found',
|
||||
),
|
||||
'Symfony\Component\Debug\Exception\ClassNotFoundException',
|
||||
'Attempted to load class "WhizBangFactory" from the global namespace in foo.php line 12. Did you forget a use statement for this class?',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function test_namespaced_function_again()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
namespace Symfony\Component\Debug\Tests;
|
||||
|
||||
use Symfony\Component\Debug\ExceptionHandler;
|
||||
use Symfony\Component\Debug\Exception\OutOfMemoryException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||
|
||||
|
|
@ -23,13 +25,13 @@ class ExceptionHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
$response = $handler->createResponse(new \RuntimeException('Foo'));
|
||||
|
||||
$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response->getContent());
|
||||
$this->assertNotContains('<div class="block_exception clear_fix">', $response->getContent());
|
||||
$this->assertNotContains('<h2 class="block_exception clear_fix">', $response->getContent());
|
||||
|
||||
$handler = new ExceptionHandler(true);
|
||||
$response = $handler->createResponse(new \RuntimeException('Foo'));
|
||||
|
||||
$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response->getContent());
|
||||
$this->assertContains('<div class="block_exception clear_fix">', $response->getContent());
|
||||
$this->assertContains('<h2 class="block_exception clear_fix">', $response->getContent());
|
||||
}
|
||||
|
||||
public function testStatusCode()
|
||||
|
|
@ -59,4 +61,56 @@ class ExceptionHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
$handler = new ExceptionHandler(true);
|
||||
$response = $handler->createResponse(new \RuntimeException('Foo', 0, new \RuntimeException('Bar')));
|
||||
}
|
||||
|
||||
public function testHandle()
|
||||
{
|
||||
$exception = new \Exception('foo');
|
||||
|
||||
if (class_exists('Symfony\Component\HttpFoundation\Response')) {
|
||||
$handler = $this->getMock('Symfony\Component\Debug\ExceptionHandler', array('createResponse'));
|
||||
$handler
|
||||
->expects($this->exactly(2))
|
||||
->method('createResponse')
|
||||
->will($this->returnValue(new Response()));
|
||||
} else {
|
||||
$handler = $this->getMock('Symfony\Component\Debug\ExceptionHandler', array('sendPhpResponse'));
|
||||
$handler
|
||||
->expects($this->exactly(2))
|
||||
->method('sendPhpResponse');
|
||||
}
|
||||
|
||||
$handler->handle($exception);
|
||||
|
||||
$that = $this;
|
||||
$handler->setHandler(function ($e) use ($exception, $that) {
|
||||
$that->assertSame($exception, $e);
|
||||
});
|
||||
|
||||
$handler->handle($exception);
|
||||
}
|
||||
|
||||
public function testHandleOutOfMemoryException()
|
||||
{
|
||||
$exception = new OutOfMemoryException('foo', 0, E_ERROR, __FILE__, __LINE__);
|
||||
|
||||
if (class_exists('Symfony\Component\HttpFoundation\Response')) {
|
||||
$handler = $this->getMock('Symfony\Component\Debug\ExceptionHandler', array('createResponse'));
|
||||
$handler
|
||||
->expects($this->once())
|
||||
->method('createResponse')
|
||||
->will($this->returnValue(new Response()));
|
||||
} else {
|
||||
$handler = $this->getMock('Symfony\Component\Debug\ExceptionHandler', array('sendPhpResponse'));
|
||||
$handler
|
||||
->expects($this->once())
|
||||
->method('sendPhpResponse');
|
||||
}
|
||||
|
||||
$that = $this;
|
||||
$handler->setHandler(function ($e) use ($that) {
|
||||
$that->fail('OutOfMemoryException should bypass the handler');
|
||||
});
|
||||
|
||||
$handler->handle($exception);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Class \'WhizBangFactory\' not found',
|
||||
),
|
||||
'Attempted to load class "WhizBangFactory" from the global namespace in foo.php line 12. Did you forget a use statement for this class?',
|
||||
"Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
|
|
@ -50,7 +50,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Class \'Foo\\Bar\\WhizBangFactory\' not found',
|
||||
),
|
||||
'Attempted to load class "WhizBangFactory" from namespace "Foo\\Bar" in foo.php line 12. Do you need to "use" it from another namespace?',
|
||||
"Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
|
|
@ -59,7 +59,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Class \'UndefinedFunctionException\' not found',
|
||||
),
|
||||
'Attempted to load class "UndefinedFunctionException" from the global namespace in foo.php line 12. Did you forget a use statement for this class? Perhaps you need to add a use statement for one of the following: Symfony\Component\Debug\Exception\UndefinedFunctionException.',
|
||||
"Attempted to load class \"UndefinedFunctionException\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
|
|
@ -68,7 +68,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Class \'PEARClass\' not found',
|
||||
),
|
||||
'Attempted to load class "PEARClass" from the global namespace in foo.php line 12. Did you forget a use statement for this class? Perhaps you need to add a use statement for one of the following: Symfony_Component_Debug_Tests_Fixtures_PEARClass.',
|
||||
"Attempted to load class \"PEARClass\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony_Component_Debug_Tests_Fixtures_PEARClass\"?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
|
|
@ -77,7 +77,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
|
||||
),
|
||||
'Attempted to load class "UndefinedFunctionException" from namespace "Foo\Bar" in foo.php line 12. Do you need to "use" it from another namespace? Perhaps you need to add a use statement for one of the following: Symfony\Component\Debug\Exception\UndefinedFunctionException.',
|
||||
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class UndefinedFunctionFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined function test_namespaced_function()',
|
||||
),
|
||||
'Attempted to call function "test_namespaced_function" from the global namespace in foo.php line 12. Did you mean to call: "\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function"?',
|
||||
"Attempted to call function \"test_namespaced_function\" from the global namespace.\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
|
|
@ -51,7 +51,7 @@ class UndefinedFunctionFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined function Foo\\Bar\\Baz\\test_namespaced_function()',
|
||||
),
|
||||
'Attempted to call function "test_namespaced_function" from namespace "Foo\\Bar\\Baz" in foo.php line 12. Did you mean to call: "\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function"?',
|
||||
"Attempted to call function \"test_namespaced_function\" from namespace \"Foo\\Bar\\Baz\".\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
|
|
@ -60,7 +60,7 @@ class UndefinedFunctionFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined function foo()',
|
||||
),
|
||||
'Attempted to call function "foo" from the global namespace in foo.php line 12.',
|
||||
'Attempted to call function "foo" from the global namespace.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
|
|
@ -69,7 +69,7 @@ class UndefinedFunctionFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined function Foo\\Bar\\Baz\\foo()',
|
||||
),
|
||||
'Attempted to call function "foo" from namespace "Foo\Bar\Baz" in foo.php line 12.',
|
||||
'Attempted to call function "foo" from namespace "Foo\Bar\Baz".',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class UndefinedMethodFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined method SplObjectStorage::what()',
|
||||
),
|
||||
'Attempted to call method "what" on class "SplObjectStorage" in foo.php line 12.',
|
||||
'Attempted to call method "what" on class "SplObjectStorage".',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
|
|
@ -50,7 +50,7 @@ class UndefinedMethodFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined method SplObjectStorage::walid()',
|
||||
),
|
||||
'Attempted to call method "walid" on class "SplObjectStorage" in foo.php line 12. Did you mean to call: "valid"?',
|
||||
"Attempted to call method \"walid\" on class \"SplObjectStorage\".\nDid you mean to call \"valid\"?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
|
|
@ -59,7 +59,7 @@ class UndefinedMethodFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined method SplObjectStorage::offsetFet()',
|
||||
),
|
||||
'Attempted to call method "offsetFet" on class "SplObjectStorage" in foo.php line 12. Did you mean to call: "offsetGet", "offsetSet", "offsetUnset"?',
|
||||
"Attempted to call method \"offsetFet\" on class \"SplObjectStorage\".\nDid you mean to call e.g. \"offsetGet\", \"offsetSet\" or \"offsetUnset\"?",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
"php": ">=5.3.3",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/http-kernel": "~2.1",
|
||||
|
|
@ -33,7 +34,7 @@
|
|||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.6.0
|
||||
-----
|
||||
|
||||
* added new factory syntax and deprecated the old one
|
||||
|
||||
2.5.0
|
||||
-----
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface
|
|||
if ($definition->getConfigurator()) {
|
||||
$this->processArguments(array($definition->getConfigurator()));
|
||||
}
|
||||
if ($definition->getFactory()) {
|
||||
$this->processArguments(array($definition->getFactory()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,28 +42,22 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
|
|||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
// synthetic service is public
|
||||
if ($definition->isSynthetic() && !$definition->isPublic()) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'A synthetic service ("%s") must be public.',
|
||||
$id
|
||||
));
|
||||
throw new RuntimeException(sprintf('A synthetic service ("%s") must be public.', $id));
|
||||
}
|
||||
|
||||
// synthetic service has non-prototype scope
|
||||
if ($definition->isSynthetic() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'A synthetic service ("%s") cannot be of scope "prototype".',
|
||||
$id
|
||||
));
|
||||
throw new RuntimeException(sprintf('A synthetic service ("%s") cannot be of scope "prototype".', $id));
|
||||
}
|
||||
|
||||
if ($definition->getFactory() && ($definition->getFactoryClass() || $definition->getFactoryService() || $definition->getFactoryMethod())) {
|
||||
throw new RuntimeException(sprintf('A service ("%s") can use either the old or the new factory syntax, not both.', $id));
|
||||
}
|
||||
|
||||
// non-synthetic, non-abstract service has class
|
||||
if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) {
|
||||
if ($definition->getFactoryClass() || $definition->getFactoryService()) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'Please add the class to service "%s" even if it is constructed by a factory '
|
||||
.'since we might need to add method calls based on compile-time checks.',
|
||||
$id
|
||||
));
|
||||
if ($definition->getFactory() || $definition->getFactoryClass() || $definition->getFactoryService()) {
|
||||
throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id));
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf(
|
||||
|
|
|
|||
|
|
@ -64,9 +64,10 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
);
|
||||
|
||||
$configurator = $this->inlineArguments($container, array($definition->getConfigurator()));
|
||||
$definition->setConfigurator(
|
||||
$configurator[0]
|
||||
);
|
||||
$definition->setConfigurator($configurator[0]);
|
||||
|
||||
$factory = $this->inlineArguments($container, array($definition->getFactory()));
|
||||
$definition->setFactory($factory[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,9 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
|||
if (isset($changes['factory_service'])) {
|
||||
$def->setFactoryService($definition->getFactoryService());
|
||||
}
|
||||
if (isset($changes['factory'])) {
|
||||
$def->setFactory($definition->getFactory());
|
||||
}
|
||||
if (isset($changes['configurator'])) {
|
||||
$def->setConfigurator($definition->getConfigurator());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
|
|
@ -84,7 +85,12 @@ class ResolveReferencesToAliasesPass implements CompilerPassInterface
|
|||
*/
|
||||
private function getDefinitionId($id)
|
||||
{
|
||||
$seen = array();
|
||||
while ($this->container->hasAlias($id)) {
|
||||
if (isset($seen[$id])) {
|
||||
throw new ServiceCircularReferenceException($id, array_keys($seen));
|
||||
}
|
||||
$seen[$id] = true;
|
||||
$id = (string) $this->container->getAlias($id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -217,11 +217,11 @@ class Container implements IntrospectableContainerInterface
|
|||
$this->$method();
|
||||
}
|
||||
|
||||
if (self::SCOPE_CONTAINER !== $scope && null === $service) {
|
||||
if (null === $service) {
|
||||
if (self::SCOPE_CONTAINER !== $scope) {
|
||||
unset($this->scopedServices[$scope][$id]);
|
||||
}
|
||||
|
||||
if (null === $service) {
|
||||
unset($this->services[$id]);
|
||||
}
|
||||
}
|
||||
|
|
@ -450,14 +450,15 @@ class Container implements IntrospectableContainerInterface
|
|||
// the global service map
|
||||
$services = array($this->services, $this->scopedServices[$name]);
|
||||
unset($this->scopedServices[$name]);
|
||||
foreach ($this->scopeChildren[$name] as $child) {
|
||||
if (!isset($this->scopedServices[$child])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($this->scopeChildren[$name] as $child) {
|
||||
if (isset($this->scopedServices[$child])) {
|
||||
$services[] = $this->scopedServices[$child];
|
||||
unset($this->scopedServices[$child]);
|
||||
}
|
||||
}
|
||||
|
||||
// update global map
|
||||
$this->services = call_user_func_array('array_diff_key', $services);
|
||||
|
||||
// check if we need to restore services of a previous scope of this type
|
||||
|
|
@ -465,6 +466,10 @@ class Container implements IntrospectableContainerInterface
|
|||
$services = $this->scopeStacks[$name]->pop();
|
||||
$this->scopedServices += $services;
|
||||
|
||||
if ($this->scopeStacks[$name]->isEmpty()) {
|
||||
unset($this->scopeStacks[$name]);
|
||||
}
|
||||
|
||||
foreach ($services as $array) {
|
||||
foreach ($array as $id => $service) {
|
||||
$this->set($id, $service, $name);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ use Symfony\Component\Config\Resource\ResourceInterface;
|
|||
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
||||
|
||||
/**
|
||||
* ContainerBuilder is a DI container that provides an API to easily describe services.
|
||||
|
|
@ -84,6 +85,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||
*/
|
||||
private $expressionLanguage;
|
||||
|
||||
/**
|
||||
* @var ExpressionFunctionProviderInterface[]
|
||||
*/
|
||||
private $expressionLanguageProviders = array();
|
||||
|
||||
/**
|
||||
* Sets the track resources flag.
|
||||
*
|
||||
|
|
@ -464,10 +470,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||
return $service;
|
||||
}
|
||||
|
||||
if (isset($this->loading[$id])) {
|
||||
throw new LogicException(sprintf('The service "%s" has a circular reference to itself.', $id), 0, $e);
|
||||
}
|
||||
|
||||
if (!$this->hasDefinition($id) && isset($this->aliasDefinitions[$id])) {
|
||||
return $this->get($this->aliasDefinitions[$id]);
|
||||
}
|
||||
|
|
@ -939,7 +941,19 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||
|
||||
$arguments = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())));
|
||||
|
||||
if (null !== $definition->getFactoryMethod()) {
|
||||
if (null !== $definition->getFactory()) {
|
||||
$factory = $definition->getFactory();
|
||||
|
||||
if (is_string($factory)) {
|
||||
$callable = $definition->getFactory();
|
||||
} elseif (is_array($factory)) {
|
||||
$callable = array($this->resolveServices($factory[0]), $factory[1]);
|
||||
} else {
|
||||
throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id));
|
||||
}
|
||||
|
||||
$service = call_user_func_array($callable, $arguments);
|
||||
} elseif (null !== $definition->getFactoryMethod()) {
|
||||
if (null !== $definition->getFactoryClass()) {
|
||||
$factory = $parameterBag->resolveValue($definition->getFactoryClass());
|
||||
} elseif (null !== $definition->getFactoryService()) {
|
||||
|
|
@ -1056,6 +1070,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||
return array_unique($tags);
|
||||
}
|
||||
|
||||
public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
|
||||
{
|
||||
$this->expressionLanguageProviders[] = $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Service Conditionals.
|
||||
*
|
||||
|
|
@ -1161,7 +1180,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||
if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
|
||||
throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
|
||||
}
|
||||
$this->expressionLanguage = new ExpressionLanguage();
|
||||
$this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
|
||||
}
|
||||
|
||||
return $this->expressionLanguage;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class Definition
|
|||
{
|
||||
private $class;
|
||||
private $file;
|
||||
private $factory;
|
||||
private $factoryClass;
|
||||
private $factoryMethod;
|
||||
private $factoryService;
|
||||
|
|
@ -56,6 +57,34 @@ class Definition
|
|||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a factory.
|
||||
*
|
||||
* @param string|array $factory A PHP function or an array containing a class/Reference and a method to call
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*/
|
||||
public function setFactory($factory)
|
||||
{
|
||||
if (is_string($factory) && strpos($factory, '::') !== false) {
|
||||
$factory = explode('::', $factory, 2);
|
||||
}
|
||||
|
||||
$this->factory = $factory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the factory.
|
||||
*
|
||||
* @return string|array The PHP function or an array containing a class/Reference and a method to call
|
||||
*/
|
||||
public function getFactory()
|
||||
{
|
||||
return $this->factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the class that acts as a factory using the factory method,
|
||||
* which will be invoked statically.
|
||||
|
|
@ -65,6 +94,7 @@ class Definition
|
|||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
* @deprecated Deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function setFactoryClass($factoryClass)
|
||||
{
|
||||
|
|
@ -79,6 +109,7 @@ class Definition
|
|||
* @return string|null The factory class name
|
||||
*
|
||||
* @api
|
||||
* @deprecated Deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function getFactoryClass()
|
||||
{
|
||||
|
|
@ -93,6 +124,7 @@ class Definition
|
|||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
* @deprecated Deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function setFactoryMethod($factoryMethod)
|
||||
{
|
||||
|
|
@ -142,6 +174,7 @@ class Definition
|
|||
* @return string|null The factory method name
|
||||
*
|
||||
* @api
|
||||
* @deprecated Deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function getFactoryMethod()
|
||||
{
|
||||
|
|
@ -156,6 +189,7 @@ class Definition
|
|||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
* @deprecated Deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function setFactoryService($factoryService)
|
||||
{
|
||||
|
|
@ -170,6 +204,7 @@ class Definition
|
|||
* @return string|null The factory service id
|
||||
*
|
||||
* @api
|
||||
* @deprecated Deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function getFactoryService()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -76,6 +76,16 @@ class DefinitionDecorator extends Definition
|
|||
return parent::setClass($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setFactory($callable)
|
||||
{
|
||||
$this->changes['factory'] = true;
|
||||
|
||||
return parent::setFactory($callable);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as
|
|||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;
|
||||
use Symfony\Component\DependencyInjection\ExpressionLanguage;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
||||
|
||||
/**
|
||||
* PhpDumper dumps a service container as a PHP class.
|
||||
|
|
@ -55,6 +56,11 @@ class PhpDumper extends Dumper
|
|||
private $reservedVariables = array('instance', 'class');
|
||||
private $expressionLanguage;
|
||||
|
||||
/**
|
||||
* @var ExpressionFunctionProviderInterface[]
|
||||
*/
|
||||
private $expressionLanguageProviders = array();
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface
|
||||
*/
|
||||
|
|
@ -109,6 +115,7 @@ class PhpDumper extends Dumper
|
|||
|
||||
if ($this->container->isFrozen()) {
|
||||
$code .= $this->addFrozenConstructor();
|
||||
$code .= $this->addFrozenCompile();
|
||||
} else {
|
||||
$code .= $this->addConstructor();
|
||||
}
|
||||
|
|
@ -160,6 +167,7 @@ class PhpDumper extends Dumper
|
|||
$this->getServiceCallsFromArguments($iDefinition->getMethodCalls(), $calls, $behavior);
|
||||
$this->getServiceCallsFromArguments($iDefinition->getProperties(), $calls, $behavior);
|
||||
$this->getServiceCallsFromArguments(array($iDefinition->getConfigurator()), $calls, $behavior);
|
||||
$this->getServiceCallsFromArguments(array($iDefinition->getFactory()), $calls, $behavior);
|
||||
}
|
||||
|
||||
$code = '';
|
||||
|
|
@ -522,6 +530,17 @@ class PhpDumper extends Dumper
|
|||
$return[] = '@throws RuntimeException always since this service is expected to be injected dynamically';
|
||||
} elseif ($class = $definition->getClass()) {
|
||||
$return[] = sprintf("@return %s A %s instance.", 0 === strpos($class, '%') ? 'object' : "\\".$class, $class);
|
||||
} elseif ($definition->getFactory()) {
|
||||
$factory = $definition->getFactory();
|
||||
if (is_string($factory)) {
|
||||
$return[] = sprintf('@return object An instance returned by %s().', $factory);
|
||||
} elseif (is_array($factory) && (is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) {
|
||||
if (is_string($factory[0]) || $factory[0] instanceof Reference) {
|
||||
$return[] = sprintf('@return object An instance returned by %s::%s().', (string) $factory[0], $factory[1]);
|
||||
} elseif ($factory[0] instanceof Definition) {
|
||||
$return[] = sprintf('@return object An instance returned by %s::%s().', $factory[0]->getClass(), $factory[1]);
|
||||
}
|
||||
}
|
||||
} elseif ($definition->getFactoryClass()) {
|
||||
$return[] = sprintf('@return object An instance returned by %s::%s().', $definition->getFactoryClass(), $definition->getFactoryMethod());
|
||||
} elseif ($definition->getFactoryService()) {
|
||||
|
|
@ -700,7 +719,25 @@ EOF;
|
|||
$arguments[] = $this->dumpValue($value);
|
||||
}
|
||||
|
||||
if (null !== $definition->getFactoryMethod()) {
|
||||
if (null !== $definition->getFactory()) {
|
||||
$callable = $definition->getFactory();
|
||||
if (is_array($callable)) {
|
||||
if ($callable[0] instanceof Reference
|
||||
|| ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) {
|
||||
return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '');
|
||||
}
|
||||
|
||||
$class = $this->dumpValue($callable[0]);
|
||||
// If the class is a string we can optimize call_user_func away
|
||||
if (strpos($class, "'") === 0) {
|
||||
return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '');
|
||||
}
|
||||
|
||||
return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : '');
|
||||
}
|
||||
|
||||
return sprintf(" $return{$instantiation}\\%s(%s);\n", $callable, $arguments ? implode(', ', $arguments) : '');
|
||||
} elseif (null !== $definition->getFactoryMethod()) {
|
||||
if (null !== $definition->getFactoryClass()) {
|
||||
$class = $this->dumpValue($definition->getFactoryClass());
|
||||
|
||||
|
|
@ -769,16 +806,18 @@ EOF;
|
|||
*/
|
||||
private function addConstructor()
|
||||
{
|
||||
$arguments = $this->container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null;
|
||||
$parameters = $this->exportParameters($this->container->getParameterBag()->all());
|
||||
|
||||
$code = <<<EOF
|
||||
|
||||
private static \$parameters = $parameters;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct($arguments);
|
||||
parent::__construct(new ParameterBag(self::\$parameters));
|
||||
|
||||
EOF;
|
||||
|
||||
|
|
@ -806,23 +845,17 @@ EOF;
|
|||
*/
|
||||
private function addFrozenConstructor()
|
||||
{
|
||||
$parameters = $this->exportParameters($this->container->getParameterBag()->all());
|
||||
|
||||
$code = <<<EOF
|
||||
|
||||
private \$parameters;
|
||||
private static \$parameters = $parameters;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
EOF;
|
||||
|
||||
if ($this->container->getParameterBag()->all()) {
|
||||
$code .= "\n \$this->parameters = \$this->getDefaultParameters();\n";
|
||||
}
|
||||
|
||||
$code .= <<<EOF
|
||||
|
||||
\$this->services =
|
||||
\$this->scopedServices =
|
||||
\$this->scopeStacks = array();
|
||||
|
|
@ -851,6 +884,26 @@ EOF;
|
|||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the constructor for a frozen container.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function addFrozenCompile()
|
||||
{
|
||||
return <<<EOF
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped frozen container.');
|
||||
}
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the methodMap property definition
|
||||
*
|
||||
|
|
@ -910,8 +963,6 @@ EOF;
|
|||
return '';
|
||||
}
|
||||
|
||||
$parameters = $this->exportParameters($this->container->getParameterBag()->all());
|
||||
|
||||
$code = '';
|
||||
if ($this->container->isFrozen()) {
|
||||
$code .= <<<EOF
|
||||
|
|
@ -923,11 +974,11 @@ EOF;
|
|||
{
|
||||
\$name = strtolower(\$name);
|
||||
|
||||
if (!(isset(\$this->parameters[\$name]) || array_key_exists(\$name, \$this->parameters))) {
|
||||
if (!(isset(self::\$parameters[\$name]) || array_key_exists(\$name, self::\$parameters))) {
|
||||
throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', \$name));
|
||||
}
|
||||
|
||||
return \$this->parameters[\$name];
|
||||
return self::\$parameters[\$name];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -937,7 +988,7 @@ EOF;
|
|||
{
|
||||
\$name = strtolower(\$name);
|
||||
|
||||
return isset(\$this->parameters[\$name]) || array_key_exists(\$name, \$this->parameters);
|
||||
return isset(self::\$parameters[\$name]) || array_key_exists(\$name, self::\$parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -954,27 +1005,14 @@ EOF;
|
|||
public function getParameterBag()
|
||||
{
|
||||
if (null === \$this->parameterBag) {
|
||||
\$this->parameterBag = new FrozenParameterBag(\$this->parameters);
|
||||
\$this->parameterBag = new FrozenParameterBag(self::\$parameters);
|
||||
}
|
||||
|
||||
return \$this->parameterBag;
|
||||
}
|
||||
EOF;
|
||||
}
|
||||
|
||||
$code .= <<<EOF
|
||||
|
||||
/**
|
||||
* Gets the default parameters.
|
||||
*
|
||||
* @return array An array of the default parameters
|
||||
*/
|
||||
protected function getDefaultParameters()
|
||||
{
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
|
@ -1095,7 +1133,8 @@ EOF;
|
|||
$this->getDefinitionsFromArguments($definition->getArguments()),
|
||||
$this->getDefinitionsFromArguments($definition->getMethodCalls()),
|
||||
$this->getDefinitionsFromArguments($definition->getProperties()),
|
||||
$this->getDefinitionsFromArguments(array($definition->getConfigurator()))
|
||||
$this->getDefinitionsFromArguments(array($definition->getConfigurator())),
|
||||
$this->getDefinitionsFromArguments(array($definition->getFactory()))
|
||||
);
|
||||
|
||||
$this->inlinedDefinitions->offsetSet($definition, $definitions);
|
||||
|
|
@ -1173,7 +1212,7 @@ EOF;
|
|||
/**
|
||||
* Dumps values.
|
||||
*
|
||||
* @param array $value
|
||||
* @param mixed $value
|
||||
* @param bool $interpolate
|
||||
*
|
||||
* @return string
|
||||
|
|
@ -1210,6 +1249,30 @@ EOF;
|
|||
throw new RuntimeException('Cannot dump definitions which have a variable class name.');
|
||||
}
|
||||
|
||||
if (null !== $value->getFactory()) {
|
||||
$factory = $value->getFactory();
|
||||
|
||||
if (is_string($factory)) {
|
||||
return sprintf('\\%s(%s)', $factory, implode(', ', $arguments));
|
||||
}
|
||||
|
||||
if (is_array($factory)) {
|
||||
if (is_string($factory[0])) {
|
||||
return sprintf('\\%s::%s(%s)', $factory[0], $factory[1], implode(', ', $arguments));
|
||||
}
|
||||
|
||||
if ($factory[0] instanceof Definition) {
|
||||
return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($factory[0]), $factory[1], count($arguments) > 0 ? ', '.implode(', ', $arguments) : '');
|
||||
}
|
||||
|
||||
if ($factory[0] instanceof Reference) {
|
||||
return sprintf('%s->%s(%s)', $this->dumpValue($factory[0]), $factory[1], implode(', ', $arguments));
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException('Cannot dump definition because of invalid factory');
|
||||
}
|
||||
|
||||
if (null !== $value->getFactoryMethod()) {
|
||||
if (null !== $value->getFactoryClass()) {
|
||||
return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($value->getFactoryClass()), $value->getFactoryMethod(), count($arguments) > 0 ? ', '.implode(', ', $arguments) : '');
|
||||
|
|
@ -1283,6 +1346,11 @@ EOF;
|
|||
return sprintf("\$this->getParameter('%s')", strtolower($name));
|
||||
}
|
||||
|
||||
public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
|
||||
{
|
||||
$this->expressionLanguageProviders[] = $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a service call
|
||||
*
|
||||
|
|
@ -1372,7 +1440,7 @@ EOF;
|
|||
if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
|
||||
throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
|
||||
}
|
||||
$this->expressionLanguage = new ExpressionLanguage();
|
||||
$this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
|
||||
}
|
||||
|
||||
return $this->expressionLanguage;
|
||||
|
|
|
|||
|
|
@ -176,6 +176,17 @@ class XmlDumper extends Dumper
|
|||
|
||||
$this->addMethodCalls($definition->getMethodCalls(), $service);
|
||||
|
||||
if ($callable = $definition->getFactory()) {
|
||||
$factory = $this->document->createElement('factory');
|
||||
if (is_array($callable)) {
|
||||
$factory->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]);
|
||||
$factory->setAttribute('method', $callable[1]);
|
||||
} else {
|
||||
$factory->setAttribute('function', $callable);
|
||||
}
|
||||
$service->appendChild($factory);
|
||||
}
|
||||
|
||||
if ($callable = $definition->getConfigurator()) {
|
||||
$configurator = $this->document->createElement('configurator');
|
||||
if (is_array($callable)) {
|
||||
|
|
|
|||
|
|
@ -147,16 +147,12 @@ class YamlDumper extends Dumper
|
|||
}
|
||||
}
|
||||
|
||||
if ($callable = $definition->getConfigurator()) {
|
||||
if (is_array($callable)) {
|
||||
if ($callable[0] instanceof Reference) {
|
||||
$callable = array($this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]);
|
||||
} else {
|
||||
$callable = array($callable[0], $callable[1]);
|
||||
}
|
||||
if ($callable = $definition->getFactory()) {
|
||||
$code .= sprintf(" factory: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0));
|
||||
}
|
||||
|
||||
$code .= sprintf(" configurator: %s\n", $this->dumper->dump($callable, 0));
|
||||
if ($callable = $definition->getConfigurator()) {
|
||||
$code .= sprintf(" configurator: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0));
|
||||
}
|
||||
|
||||
return $code;
|
||||
|
|
@ -222,6 +218,26 @@ class YamlDumper extends Dumper
|
|||
return $this->dumper->dump(array('parameters' => $parameters), 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps callable to YAML format
|
||||
*
|
||||
* @param callable $callable
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
private function dumpCallable($callable)
|
||||
{
|
||||
if (is_array($callable)) {
|
||||
if ($callable[0] instanceof Reference) {
|
||||
$callable = array($this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]);
|
||||
} else {
|
||||
$callable = array($callable[0], $callable[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the value to YAML format
|
||||
*
|
||||
|
|
|
|||
|
|
@ -12,31 +12,22 @@
|
|||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
|
||||
use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface;
|
||||
|
||||
/**
|
||||
* Adds some function to the default ExpressionLanguage.
|
||||
*
|
||||
* To get a service, use service('request').
|
||||
* To get a parameter, use parameter('kernel.debug').
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @see ExpressionLanguageProvider
|
||||
*/
|
||||
class ExpressionLanguage extends BaseExpressionLanguage
|
||||
{
|
||||
protected function registerFunctions()
|
||||
public function __construct(ParserCacheInterface $cache = null, array $providers = array())
|
||||
{
|
||||
parent::registerFunctions();
|
||||
// prepend the default provider to let users overide it easily
|
||||
array_unshift($providers, new ExpressionLanguageProvider());
|
||||
|
||||
$this->register('service', function ($arg) {
|
||||
return sprintf('$this->get(%s)', $arg);
|
||||
}, function (array $variables, $value) {
|
||||
return $variables['container']->get($value);
|
||||
});
|
||||
|
||||
$this->register('parameter', function ($arg) {
|
||||
return sprintf('$this->getParameter(%s)', $arg);
|
||||
}, function (array $variables, $value) {
|
||||
return $variables['container']->getParameter($value);
|
||||
});
|
||||
parent::__construct($cache, $providers);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
||||
|
||||
/**
|
||||
* Define some ExpressionLanguage functions.
|
||||
*
|
||||
* To get a service, use service('request').
|
||||
* To get a parameter, use parameter('kernel.debug').
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
|
||||
{
|
||||
public function getFunctions()
|
||||
{
|
||||
return array(
|
||||
new ExpressionFunction('service', function ($arg) {
|
||||
return sprintf('$this->get(%s)', $arg);
|
||||
}, function (array $variables, $value) {
|
||||
return $variables['container']->get($value);
|
||||
}),
|
||||
|
||||
new ExpressionFunction('parameter', function ($arg) {
|
||||
return sprintf('$this->getParameter(%s)', $arg);
|
||||
}, function (array $variables, $value) {
|
||||
return $variables['container']->getParameter($value);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -36,23 +36,15 @@ class ClosureLoader extends Loader
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads a Closure.
|
||||
*
|
||||
* @param \Closure $closure The resource
|
||||
* @param string $type The resource type
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($closure, $type = null)
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
call_user_func($closure, $this->container);
|
||||
call_user_func($resource, $this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,22 +22,17 @@ use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
|||
class IniFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Loads a resource.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @throws InvalidArgumentException When ini file is not valid
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
$path = $this->locator->locate($resource);
|
||||
|
||||
$this->container->addResource(new FileResource($path));
|
||||
|
||||
$result = parse_ini_file($path, true);
|
||||
if (false === $result || array() === $result) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $file));
|
||||
throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $resource));
|
||||
}
|
||||
|
||||
if (isset($result['parameters']) && is_array($result['parameters'])) {
|
||||
|
|
@ -48,12 +43,7 @@ class IniFileLoader extends FileLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,18 +24,15 @@ use Symfony\Component\Config\Resource\FileResource;
|
|||
class PhpFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Loads a PHP file.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
// the container and loader variables are exposed to the included file below
|
||||
$container = $this->container;
|
||||
$loader = $this;
|
||||
|
||||
$path = $this->locator->locate($file);
|
||||
$path = $this->locator->locate($resource);
|
||||
$this->setCurrentDir(dirname($path));
|
||||
$this->container->addResource(new FileResource($path));
|
||||
|
||||
|
|
@ -43,12 +40,7 @@ class PhpFileLoader extends FileLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,14 +32,11 @@ class XmlFileLoader extends FileLoader
|
|||
const NS = 'http://symfony.com/schema/dic/services';
|
||||
|
||||
/**
|
||||
* Loads an XML file.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
$path = $this->locator->locate($resource);
|
||||
|
||||
$xml = $this->parseFileToDOM($path);
|
||||
|
||||
|
|
@ -62,12 +59,7 @@ class XmlFileLoader extends FileLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
|
|
@ -167,6 +159,21 @@ class XmlFileLoader extends FileLoader
|
|||
$definition->setArguments($this->getArgumentsAsPhp($service, 'argument'));
|
||||
$definition->setProperties($this->getArgumentsAsPhp($service, 'property'));
|
||||
|
||||
if ($factories = $this->getChildren($service, 'factory')) {
|
||||
$factory = $factories[0];
|
||||
if ($function = $factory->getAttribute('function')) {
|
||||
$definition->setFactory($function);
|
||||
} else {
|
||||
if ($childService = $factory->getAttribute('service')) {
|
||||
$class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false);
|
||||
} else {
|
||||
$class = $factory->getAttribute('class');
|
||||
}
|
||||
|
||||
$definition->setFactory(array($class, $factory->getAttribute('method')));
|
||||
}
|
||||
}
|
||||
|
||||
if ($configurators = $this->getChildren($service, 'configurator')) {
|
||||
$configurator = $configurators[0];
|
||||
if ($function = $configurator->getAttribute('function')) {
|
||||
|
|
|
|||
|
|
@ -33,14 +33,11 @@ class YamlFileLoader extends FileLoader
|
|||
private $yamlParser;
|
||||
|
||||
/**
|
||||
* Loads a Yaml file.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
$path = $this->locator->locate($resource);
|
||||
|
||||
$content = $this->loadFile($path);
|
||||
|
||||
|
|
@ -57,7 +54,7 @@ class YamlFileLoader extends FileLoader
|
|||
// parameters
|
||||
if (isset($content['parameters'])) {
|
||||
if (!is_array($content['parameters'])) {
|
||||
throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $file));
|
||||
throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $resource));
|
||||
}
|
||||
|
||||
foreach ($content['parameters'] as $key => $value) {
|
||||
|
|
@ -69,16 +66,11 @@ class YamlFileLoader extends FileLoader
|
|||
$this->loadFromExtensions($content);
|
||||
|
||||
// services
|
||||
$this->parseDefinitions($content, $file);
|
||||
$this->parseDefinitions($content, $resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
|
|
@ -194,6 +186,19 @@ class YamlFileLoader extends FileLoader
|
|||
$definition->setAbstract($service['abstract']);
|
||||
}
|
||||
|
||||
if (isset($service['factory'])) {
|
||||
if (is_string($service['factory'])) {
|
||||
if (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') === false) {
|
||||
$parts = explode(':', $service['factory']);
|
||||
$definition->setFactory(array($this->resolveServices('@'.$parts[0]), $parts[1]));
|
||||
} else {
|
||||
$definition->setFactory($service['factory']);
|
||||
}
|
||||
} else {
|
||||
$definition->setFactory(array($this->resolveServices($service['factory'][0]), $service['factory'][1]));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($service['factory_class'])) {
|
||||
$definition->setFactoryClass($service['factory_class']);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
<xsd:attribute name="ignore-errors" type="boolean" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="configurator">
|
||||
<xsd:complexType name="callable">
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="service" type="xsd:string" />
|
||||
<xsd:attribute name="class" type="xsd:string" />
|
||||
|
|
@ -76,7 +76,8 @@
|
|||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="file" type="xsd:string" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="configurator" type="configurator" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="configurator" type="callable" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="factory" type="callable" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="call" type="call" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Injection Container.
|
|||
|
||||
Here is a simple example that shows how to register services and parameters:
|
||||
|
||||
```php
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
|
|
@ -17,9 +18,11 @@ Here is a simple example that shows how to register services and parameters:
|
|||
$sc->setParameter('foo.class', 'Foo');
|
||||
|
||||
$sc->get('foo');
|
||||
```
|
||||
|
||||
Method Calls (Setter Injection):
|
||||
|
||||
```php
|
||||
$sc = new ContainerBuilder();
|
||||
|
||||
$sc
|
||||
|
|
@ -29,22 +32,24 @@ Method Calls (Setter Injection):
|
|||
$sc->setParameter('bar.class', 'Bar');
|
||||
|
||||
$sc->get('bar');
|
||||
```
|
||||
|
||||
Factory Class:
|
||||
|
||||
If your service is retrieved by calling a static method:
|
||||
|
||||
```php
|
||||
$sc = new ContainerBuilder();
|
||||
|
||||
$sc
|
||||
->register('bar', '%bar.class%')
|
||||
->setFactoryClass('%bar.class%')
|
||||
->setFactoryMethod('getInstance')
|
||||
->setFactory(array('%bar.class%', 'getInstance'))
|
||||
->addArgument('Aarrg!!!')
|
||||
;
|
||||
$sc->setParameter('bar.class', 'Bar');
|
||||
|
||||
$sc->get('bar');
|
||||
```
|
||||
|
||||
File Include:
|
||||
|
||||
|
|
@ -52,6 +57,7 @@ For some services, especially those that are difficult or impossible to
|
|||
autoload, you may need the container to include a file before
|
||||
instantiating your class.
|
||||
|
||||
```php
|
||||
$sc = new ContainerBuilder();
|
||||
|
||||
$sc
|
||||
|
|
@ -62,6 +68,7 @@ instantiating your class.
|
|||
$sc->setParameter('bar.class', 'Bar');
|
||||
|
||||
$sc->get('bar');
|
||||
```
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
|
|
|||
|
|
@ -50,6 +50,17 @@ class CheckDefinitionValidityPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
*/
|
||||
public function testProcessDetectsBothFactorySyntaxesUsed()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('a')->setFactory(array('a', 'b'))->setFactoryClass('a');
|
||||
|
||||
$this->process($container);
|
||||
}
|
||||
|
||||
public function testProcess()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
|
|
|||
|
|
@ -48,6 +48,17 @@ class ResolveReferencesToAliasesPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals('foo', (string) $arguments[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
|
||||
*/
|
||||
public function testAliasCircularReference()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->setAlias('bar', 'foo');
|
||||
$container->setAlias('foo', 'bar');
|
||||
$this->process($container);
|
||||
}
|
||||
|
||||
protected function process(ContainerBuilder $container)
|
||||
{
|
||||
$pass = new ResolveReferencesToAliasesPass();
|
||||
|
|
|
|||
|
|
@ -341,6 +341,23 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertInstanceOf('BazClass', $builder->get('baz_service'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService
|
||||
*/
|
||||
public function testCreateServiceFactory()
|
||||
{
|
||||
$builder = new ContainerBuilder();
|
||||
$builder->register('foo', 'Bar\FooClass')->setFactory('Bar\FooClass::getInstance');
|
||||
$builder->register('qux', 'Bar\FooClass')->setFactory(array('Bar\FooClass', 'getInstance'));
|
||||
$builder->register('bar', 'Bar\FooClass')->setFactory(array(new Definition('Bar\FooClass'), 'getInstance'));
|
||||
$builder->register('baz', 'Bar\FooClass')->setFactory(array(new Reference('bar'), 'getInstance'));
|
||||
|
||||
$this->assertTrue($builder->get('foo')->called, '->createService() calls the factory method to create the service instance');
|
||||
$this->assertTrue($builder->get('qux')->called, '->createService() calls the factory method to create the service instance');
|
||||
$this->assertTrue($builder->get('bar')->called, '->createService() uses anonymous service as factory');
|
||||
$this->assertTrue($builder->get('baz')->called, '->createService() uses another service as factory');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -55,13 +55,35 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForTestUnderscore
|
||||
*/
|
||||
public function testUnderscore($id, $expected)
|
||||
{
|
||||
$this->assertEquals($expected, Container::underscore($id), sprintf('Container::underscore("%s")', $id));
|
||||
}
|
||||
|
||||
public function dataForTestUnderscore()
|
||||
{
|
||||
return array(
|
||||
array('FooBar', 'foo_bar'),
|
||||
array('Foo_Bar', 'foo.bar'),
|
||||
array('Foo_BarBaz', 'foo.bar_baz'),
|
||||
array('FooBar_BazQux', 'foo_bar.baz_qux'),
|
||||
array('_Foo', '.foo'),
|
||||
array('Foo_', 'foo.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\Container::compile
|
||||
*/
|
||||
public function testCompile()
|
||||
{
|
||||
$sc = new Container(new ParameterBag(array('foo' => 'bar')));
|
||||
$this->assertFalse($sc->getParameterBag()->isResolved(), '->compile() resolves the parameter bag');
|
||||
$sc->compile();
|
||||
$this->assertTrue($sc->getParameterBag()->isResolved(), '->compile() resolves the parameter bag');
|
||||
$this->assertInstanceOf('Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag', $sc->getParameterBag(), '->compile() changes the parameter bag to a FrozenParameterBag instance');
|
||||
$this->assertEquals(array('foo' => 'bar'), $sc->getParameterBag()->all(), '->compile() copies the current parameters to the new parameter bag');
|
||||
}
|
||||
|
|
@ -123,7 +145,8 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals(array('service_container', 'foo', 'bar'), $sc->getServiceIds(), '->getServiceIds() returns all defined service ids');
|
||||
|
||||
$sc = new ProjectServiceContainer();
|
||||
$this->assertEquals(array('scoped', 'scoped_foo', 'inactive', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'service_container'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by getXXXService() methods');
|
||||
$sc->set('foo', $obj = new \stdClass());
|
||||
$this->assertEquals(array('scoped', 'scoped_foo', 'scoped_synchronized_foo', 'inactive', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'service_container', 'foo'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by getXXXService() methods, followed by service ids defined by set()');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -143,7 +166,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
$sc = new Container();
|
||||
$sc->set('foo', null);
|
||||
$this->assertFalse($sc->has('foo'));
|
||||
$this->assertFalse($sc->has('foo'), '->set() with null service resets the service');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -152,7 +175,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
public function testSetDoesNotAllowPrototypeScope()
|
||||
{
|
||||
$c = new Container();
|
||||
$c->set('foo', new \stdClass(), 'prototype');
|
||||
$c->set('foo', new \stdClass(), Container::SCOPE_PROTOTYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -172,9 +195,18 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$c->enterScope('foo');
|
||||
$c->set('foo', $foo = new \stdClass(), 'foo');
|
||||
|
||||
$services = $this->getField($c, 'scopedServices');
|
||||
$this->assertTrue(isset($services['foo']['foo']));
|
||||
$this->assertSame($foo, $services['foo']['foo']);
|
||||
$scoped = $this->getField($c, 'scopedServices');
|
||||
$this->assertTrue(isset($scoped['foo']['foo']), '->set() sets a scoped service');
|
||||
$this->assertSame($foo, $scoped['foo']['foo'], '->set() sets a scoped service');
|
||||
}
|
||||
|
||||
public function testSetAlsoCallsSynchronizeService()
|
||||
{
|
||||
$c = new ProjectServiceContainer();
|
||||
$c->addScope(new Scope('foo'));
|
||||
$c->enterScope('foo');
|
||||
$c->set('scoped_synchronized_foo', $bar = new \stdClass(), 'foo');
|
||||
$this->assertTrue($c->synchronized, '->set() calls synchronize*Service() if it is defined for the service');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -185,6 +217,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$sc = new ProjectServiceContainer();
|
||||
$sc->set('foo', $foo = new \stdClass());
|
||||
$this->assertEquals($foo, $sc->get('foo'), '->get() returns the service for the given id');
|
||||
$this->assertEquals($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase');
|
||||
$this->assertEquals($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id');
|
||||
$this->assertEquals($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined');
|
||||
$this->assertEquals($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined');
|
||||
|
|
@ -199,7 +232,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws a ServiceNotFoundException exception if the service is empty');
|
||||
}
|
||||
$this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE));
|
||||
$this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service is empty');
|
||||
}
|
||||
|
||||
public function testGetThrowServiceNotFoundException()
|
||||
|
|
@ -316,16 +349,15 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$a = new \stdClass();
|
||||
$container->set('a', $a, 'bar');
|
||||
|
||||
$services = $this->getField($container, 'scopedServices');
|
||||
$this->assertTrue(isset($services['bar']['a']));
|
||||
$this->assertSame($a, $services['bar']['a']);
|
||||
|
||||
$scoped = $this->getField($container, 'scopedServices');
|
||||
$this->assertTrue(isset($scoped['bar']['a']));
|
||||
$this->assertSame($a, $scoped['bar']['a']);
|
||||
$this->assertTrue($container->has('a'));
|
||||
|
||||
$container->leaveScope('foo');
|
||||
|
||||
$services = $this->getField($container, 'scopedServices');
|
||||
$this->assertFalse(isset($services['bar']));
|
||||
|
||||
$scoped = $this->getField($container, 'scopedServices');
|
||||
$this->assertFalse(isset($scoped['bar']));
|
||||
$this->assertFalse($container->isScopeActive('foo'));
|
||||
$this->assertFalse($container->has('a'));
|
||||
}
|
||||
|
|
@ -347,19 +379,83 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$a = new \stdClass();
|
||||
$container->set('a', $a, 'foo');
|
||||
|
||||
$services = $this->getField($container, 'scopedServices');
|
||||
$this->assertTrue(isset($services['foo']['a']));
|
||||
$this->assertSame($a, $services['foo']['a']);
|
||||
|
||||
$scoped = $this->getField($container, 'scopedServices');
|
||||
$this->assertTrue(isset($scoped['foo']['a']));
|
||||
$this->assertSame($a, $scoped['foo']['a']);
|
||||
$this->assertTrue($container->has('a'));
|
||||
|
||||
$container->enterScope('foo');
|
||||
|
||||
$services = $this->getField($container, 'scopedServices');
|
||||
$this->assertFalse(isset($services['a']));
|
||||
|
||||
$scoped = $this->getField($container, 'scopedServices');
|
||||
$this->assertFalse(isset($scoped['a']));
|
||||
$this->assertTrue($container->isScopeActive('foo'));
|
||||
$this->assertFalse($container->isScopeActive('bar'));
|
||||
$this->assertFalse($container->has('a'));
|
||||
|
||||
$container->enterScope('bar');
|
||||
|
||||
$this->assertTrue($container->isScopeActive('bar'));
|
||||
|
||||
$container->leaveScope('foo');
|
||||
|
||||
$this->assertTrue($container->isScopeActive('foo'));
|
||||
$this->assertFalse($container->isScopeActive('bar'));
|
||||
$this->assertTrue($container->has('a'));
|
||||
}
|
||||
|
||||
public function testEnterChildScopeRecursively()
|
||||
{
|
||||
$container = new Container();
|
||||
$container->addScope(new Scope('foo'));
|
||||
$container->addScope(new Scope('bar', 'foo'));
|
||||
|
||||
$container->enterScope('foo');
|
||||
$container->enterScope('bar');
|
||||
|
||||
$this->assertTrue($container->isScopeActive('bar'));
|
||||
$this->assertFalse($container->has('a'));
|
||||
|
||||
$a = new \stdClass();
|
||||
$container->set('a', $a, 'bar');
|
||||
|
||||
$scoped = $this->getField($container, 'scopedServices');
|
||||
$this->assertTrue(isset($scoped['bar']['a']));
|
||||
$this->assertSame($a, $scoped['bar']['a']);
|
||||
$this->assertTrue($container->has('a'));
|
||||
|
||||
$container->enterScope('bar');
|
||||
|
||||
$scoped = $this->getField($container, 'scopedServices');
|
||||
$this->assertFalse(isset($scoped['a']));
|
||||
$this->assertTrue($container->isScopeActive('foo'));
|
||||
$this->assertTrue($container->isScopeActive('bar'));
|
||||
$this->assertFalse($container->has('a'));
|
||||
|
||||
$container->leaveScope('bar');
|
||||
|
||||
$this->assertTrue($container->isScopeActive('foo'));
|
||||
$this->assertTrue($container->isScopeActive('bar'));
|
||||
$this->assertTrue($container->has('a'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testEnterScopeNotAdded()
|
||||
{
|
||||
$container = new Container();
|
||||
$container->enterScope('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testEnterScopeDoesNotAllowInactiveParentScope()
|
||||
{
|
||||
$container = new Container();
|
||||
$container->addScope(new Scope('foo'));
|
||||
$container->addScope(new Scope('bar', 'foo'));
|
||||
$container->enterScope('bar');
|
||||
}
|
||||
|
||||
public function testLeaveScopeNotActive()
|
||||
|
|
@ -422,6 +518,11 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
$this->assertSame(array('foo' => 'container', 'bar' => 'foo'), $this->getField($c, 'scopes'));
|
||||
$this->assertSame(array('foo' => array('bar'), 'bar' => array()), $this->getField($c, 'scopeChildren'));
|
||||
|
||||
$c->addScope(new Scope('baz', 'bar'));
|
||||
|
||||
$this->assertSame(array('foo' => 'container', 'bar' => 'foo', 'baz' => 'bar'), $this->getField($c, 'scopes'));
|
||||
$this->assertSame(array('foo' => array('bar', 'baz'), 'bar' => array('baz'), 'baz' => array()), $this->getField($c, 'scopeChildren'));
|
||||
}
|
||||
|
||||
public function testHasScope()
|
||||
|
|
@ -433,6 +534,45 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertTrue($c->hasScope('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage Something went terribly wrong!
|
||||
*/
|
||||
public function testGetThrowsException()
|
||||
{
|
||||
$c = new ProjectServiceContainer();
|
||||
|
||||
try {
|
||||
$c->get('throw_exception');
|
||||
} catch (\Exception $e) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
// Retry, to make sure that get*Service() will be called.
|
||||
$c->get('throw_exception');
|
||||
}
|
||||
|
||||
public function testGetThrowsExceptionOnServiceConfiguration()
|
||||
{
|
||||
$c = new ProjectServiceContainer();
|
||||
|
||||
try {
|
||||
$c->get('throws_exception_on_service_configuration');
|
||||
} catch (\Exception $e) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
$this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
|
||||
|
||||
// Retry, to make sure that get*Service() will be called.
|
||||
try {
|
||||
$c->get('throws_exception_on_service_configuration');
|
||||
} catch (\Exception $e) {
|
||||
// Do nothing.
|
||||
}
|
||||
$this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
|
||||
}
|
||||
|
||||
public function testIsScopeActive()
|
||||
{
|
||||
$c = new Container();
|
||||
|
|
@ -449,46 +589,6 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertFalse($c->isScopeActive('foo'));
|
||||
}
|
||||
|
||||
public function testGetThrowsException()
|
||||
{
|
||||
$c = new ProjectServiceContainer();
|
||||
|
||||
try {
|
||||
$c->get('throw_exception');
|
||||
$this->fail();
|
||||
} catch (\Exception $e) {
|
||||
$this->assertEquals('Something went terribly wrong!', $e->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
$c->get('throw_exception');
|
||||
$this->fail();
|
||||
} catch (\Exception $e) {
|
||||
$this->assertEquals('Something went terribly wrong!', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetThrowsExceptionOnServiceConfiguration()
|
||||
{
|
||||
$c = new ProjectServiceContainer();
|
||||
|
||||
try {
|
||||
$c->get('throws_exception_on_service_configuration');
|
||||
$this->fail('The container can not contain invalid service!');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertEquals('Something was terribly wrong while trying to configure the service!', $e->getMessage());
|
||||
}
|
||||
$this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
|
||||
|
||||
try {
|
||||
$c->get('throws_exception_on_service_configuration');
|
||||
$this->fail('The container can not contain invalid service!');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertEquals('Something was terribly wrong while trying to configure the service!', $e->getMessage());
|
||||
}
|
||||
$this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
|
||||
}
|
||||
|
||||
public function getInvalidParentScopes()
|
||||
{
|
||||
return array(
|
||||
|
|
@ -525,6 +625,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
class ProjectServiceContainer extends Container
|
||||
{
|
||||
public $__bar, $__foo_bar, $__foo_baz;
|
||||
public $synchronized;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -533,12 +634,13 @@ class ProjectServiceContainer extends Container
|
|||
$this->__bar = new \stdClass();
|
||||
$this->__foo_bar = new \stdClass();
|
||||
$this->__foo_baz = new \stdClass();
|
||||
$this->synchronized = false;
|
||||
$this->aliases = array('alias' => 'bar');
|
||||
}
|
||||
|
||||
protected function getScopedService()
|
||||
{
|
||||
if (!isset($this->scopedServices['foo'])) {
|
||||
if (!$this->isScopeActive('foo')) {
|
||||
throw new \RuntimeException('Invalid call');
|
||||
}
|
||||
|
||||
|
|
@ -547,13 +649,27 @@ class ProjectServiceContainer extends Container
|
|||
|
||||
protected function getScopedFooService()
|
||||
{
|
||||
if (!isset($this->scopedServices['foo'])) {
|
||||
if (!$this->isScopeActive('foo')) {
|
||||
throw new \RuntimeException('invalid call');
|
||||
}
|
||||
|
||||
return $this->services['scoped_foo'] = $this->scopedServices['foo']['scoped_foo'] = new \stdClass();
|
||||
}
|
||||
|
||||
protected function getScopedSynchronizedFooService()
|
||||
{
|
||||
if (!$this->isScopeActive('foo')) {
|
||||
throw new \RuntimeException('invalid call');
|
||||
}
|
||||
|
||||
return $this->services['scoped_bar'] = $this->scopedServices['foo']['scoped_bar'] = new \stdClass();
|
||||
}
|
||||
|
||||
protected function synchronizeScopedSynchronizedFooService()
|
||||
{
|
||||
$this->synchronized = true;
|
||||
}
|
||||
|
||||
protected function getInactiveService()
|
||||
{
|
||||
throw new InactiveScopeException('request', 'request');
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class DefinitionDecoratorTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
return array(
|
||||
array('class', 'class'),
|
||||
array('factory', 'factory'),
|
||||
array('factoryClass', 'factory_class'),
|
||||
array('factoryMethod', 'factory_method'),
|
||||
array('factoryService', 'factory_service'),
|
||||
|
|
|
|||
|
|
@ -27,6 +27,21 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals(array('foo'), $def->getArguments(), '__construct() takes an optional array of arguments as its second argument');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\Definition::setFactory
|
||||
* @covers Symfony\Component\DependencyInjection\Definition::getFactory
|
||||
*/
|
||||
public function testSetGetFactory()
|
||||
{
|
||||
$def = new Definition('stdClass');
|
||||
|
||||
$this->assertSame($def, $def->setFactory('foo'), '->setFactory() implements a fluent interface');
|
||||
$this->assertEquals('foo', $def->getFactory(), '->getFactory() returns the factory');
|
||||
|
||||
$def->setFactory('Foo::bar');
|
||||
$this->assertEquals(array('Foo', 'bar'), $def->getFactory(), '->setFactory() converts string static method call to the array');
|
||||
}
|
||||
|
||||
public function testSetGetFactoryClass()
|
||||
{
|
||||
$def = new Definition('stdClass');
|
||||
|
|
|
|||
|
|
@ -120,6 +120,14 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
}
|
||||
|
||||
public function testServicesWithAnonymousFactories()
|
||||
{
|
||||
$container = include self::$fixturesPath.'/containers/container19.php';
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services19.php', $dumper->dump(), '->dump() dumps services with anonymous factories');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Service id "bar$" cannot be converted to a valid PHP method name.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
require_once __DIR__.'/../includes/classes.php';
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container
|
||||
->register('service_from_anonymous_factory', 'Bar\FooClass')
|
||||
->setFactory(array(new Definition('Bar\FooClass'), 'getInstance'))
|
||||
;
|
||||
|
||||
$anonymousServiceWithFactory = new Definition('Bar\FooClass');
|
||||
$anonymousServiceWithFactory->setFactory('Bar\FooClass::getInstance');
|
||||
$container
|
||||
->register('service_with_method_call_and_factory', 'Bar\FooClass')
|
||||
->addMethodCall('setBar', array($anonymousServiceWithFactory))
|
||||
;
|
||||
|
||||
return $container;
|
||||
|
|
@ -103,5 +103,20 @@ $container
|
|||
->register('decorator_service_with_name', 'stdClass')
|
||||
->setDecoratedService('decorated', 'decorated.pif-pouf')
|
||||
;
|
||||
$container
|
||||
->register('new_factory', 'FactoryClass')
|
||||
->setProperty('foo', 'bar')
|
||||
->setScope('container')
|
||||
->setPublic(false)
|
||||
;
|
||||
$container
|
||||
->register('new_factory_service', 'FooBarBaz')
|
||||
->setProperty('foo', 'bar')
|
||||
->setFactory(array(new Reference('new_factory'), 'getInstance'))
|
||||
;
|
||||
$container
|
||||
->register('service_from_static_method', 'Bar\FooClass')
|
||||
->setFactory(array('Bar\FooClass', 'getInstance'))
|
||||
;
|
||||
|
||||
return $container;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ digraph sc {
|
|||
node_decorated [label="decorated\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_decorator_service [label="decorator_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_decorator_service_with_name [label="decorator_service_with_name\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_new_factory [label="new_factory\nFactoryClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_new_factory_service [label="new_factory_service\nFooBarBaz\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_service_from_static_method [label="service_from_static_method\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
|
||||
node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"];
|
||||
node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"];
|
||||
|
|
|
|||
|
|
@ -16,11 +16,15 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
|||
*/
|
||||
class ProjectServiceContainer extends Container
|
||||
{
|
||||
private static $parameters = array(
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
parent::__construct(new ParameterBag(self::$parameters));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,15 +16,16 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
|||
*/
|
||||
class ProjectServiceContainer extends Container
|
||||
{
|
||||
private $parameters;
|
||||
private static $parameters = array(
|
||||
'empty_value' => '',
|
||||
'some_string' => '-',
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->parameters = $this->getDefaultParameters();
|
||||
|
||||
$this->services =
|
||||
$this->scopedServices =
|
||||
$this->scopeStacks = array();
|
||||
|
|
@ -40,6 +41,14 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped frozen container.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'test' service.
|
||||
*
|
||||
|
|
@ -60,11 +69,11 @@ class ProjectServiceContainer extends Container
|
|||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters))) {
|
||||
if (!(isset(self::$parameters[$name]) || array_key_exists($name, self::$parameters))) {
|
||||
throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
|
||||
}
|
||||
|
||||
return $this->parameters[$name];
|
||||
return self::$parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,7 +83,7 @@ class ProjectServiceContainer extends Container
|
|||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
return isset(self::$parameters[$name]) || array_key_exists($name, self::$parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -91,21 +100,9 @@ class ProjectServiceContainer extends Container
|
|||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
$this->parameterBag = new FrozenParameterBag($this->parameters);
|
||||
$this->parameterBag = new FrozenParameterBag(self::$parameters);
|
||||
}
|
||||
|
||||
return $this->parameterBag;
|
||||
}
|
||||
/**
|
||||
* Gets the default parameters.
|
||||
*
|
||||
* @return array An array of the default parameters
|
||||
*/
|
||||
protected function getDefaultParameters()
|
||||
{
|
||||
return array(
|
||||
'empty_value' => '',
|
||||
'some_string' => '-',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
|
||||
/**
|
||||
* ProjectServiceContainer
|
||||
*
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Dependency Injection Component.
|
||||
*/
|
||||
class ProjectServiceContainer extends Container
|
||||
{
|
||||
private static $parameters = array(
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new ParameterBag(self::$parameters));
|
||||
$this->methodMap = array(
|
||||
'service_from_anonymous_factory' => 'getServiceFromAnonymousFactoryService',
|
||||
'service_with_method_call_and_factory' => 'getServiceWithMethodCallAndFactoryService',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'service_from_anonymous_factory' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return \Bar\FooClass A Bar\FooClass instance.
|
||||
*/
|
||||
protected function getServiceFromAnonymousFactoryService()
|
||||
{
|
||||
return $this->services['service_from_anonymous_factory'] = call_user_func(array(new \Bar\FooClass(), 'getInstance'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'service_with_method_call_and_factory' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return \Bar\FooClass A Bar\FooClass instance.
|
||||
*/
|
||||
protected function getServiceWithMethodCallAndFactoryService()
|
||||
{
|
||||
$this->services['service_with_method_call_and_factory'] = $instance = new \Bar\FooClass();
|
||||
|
||||
$instance->setBar(\Bar\FooClass::getInstance());
|
||||
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,22 +16,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
|||
*/
|
||||
class ProjectServiceContainer extends Container
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new ParameterBag($this->getDefaultParameters()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default parameters.
|
||||
*
|
||||
* @return array An array of the default parameters
|
||||
*/
|
||||
protected function getDefaultParameters()
|
||||
{
|
||||
return array(
|
||||
private static $parameters = array(
|
||||
'foo' => '%baz%',
|
||||
'baz' => 'bar',
|
||||
'bar' => 'foo is %%foo bar',
|
||||
|
|
@ -47,5 +32,12 @@ class ProjectServiceContainer extends Container
|
|||
7 => 'null',
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new ParameterBag(self::$parameters));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,18 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
|||
*/
|
||||
class ProjectServiceContainer extends Container
|
||||
{
|
||||
private static $parameters = array(
|
||||
'baz_class' => 'BazClass',
|
||||
'foo_class' => 'Bar\\FooClass',
|
||||
'foo' => 'bar',
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new ParameterBag($this->getDefaultParameters()));
|
||||
parent::__construct(new ParameterBag(self::$parameters));
|
||||
$this->methodMap = array(
|
||||
'bar' => 'getBarService',
|
||||
'baz' => 'getBazService',
|
||||
|
|
@ -38,7 +44,10 @@ class ProjectServiceContainer extends Container
|
|||
'foo_with_inline' => 'getFooWithInlineService',
|
||||
'inlined' => 'getInlinedService',
|
||||
'method_call1' => 'getMethodCall1Service',
|
||||
'new_factory' => 'getNewFactoryService',
|
||||
'new_factory_service' => 'getNewFactoryServiceService',
|
||||
'request' => 'getRequestService',
|
||||
'service_from_static_method' => 'getServiceFromStaticMethodService',
|
||||
);
|
||||
$this->aliases = array(
|
||||
'alias_for_alias' => 'foo',
|
||||
|
|
@ -265,6 +274,23 @@ class ProjectServiceContainer extends Container
|
|||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'new_factory_service' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return \FooBarBaz A FooBarBaz instance.
|
||||
*/
|
||||
protected function getNewFactoryServiceService()
|
||||
{
|
||||
$this->services['new_factory_service'] = $instance = $this->get('new_factory')->getInstance();
|
||||
|
||||
$instance->foo = 'bar';
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'request' service.
|
||||
*
|
||||
|
|
@ -278,6 +304,19 @@ class ProjectServiceContainer extends Container
|
|||
throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'service_from_static_method' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return \Bar\FooClass A Bar\FooClass instance.
|
||||
*/
|
||||
protected function getServiceFromStaticMethodService()
|
||||
{
|
||||
return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the 'request' service.
|
||||
*/
|
||||
|
|
@ -332,16 +371,23 @@ class ProjectServiceContainer extends Container
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the default parameters.
|
||||
* Gets the 'new_factory' service.
|
||||
*
|
||||
* @return array An array of the default parameters
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* This service is private.
|
||||
* If you want to be able to request this service from the container directly,
|
||||
* make it public, otherwise you might end up with broken code.
|
||||
*
|
||||
* @return \FactoryClass A FactoryClass instance.
|
||||
*/
|
||||
protected function getDefaultParameters()
|
||||
protected function getNewFactoryService()
|
||||
{
|
||||
return array(
|
||||
'baz_class' => 'BazClass',
|
||||
'foo_class' => 'Bar\\FooClass',
|
||||
'foo' => 'bar',
|
||||
);
|
||||
$this->services['new_factory'] = $instance = new \FactoryClass();
|
||||
|
||||
$instance->foo = 'bar';
|
||||
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,15 +16,17 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
|||
*/
|
||||
class ProjectServiceContainer extends Container
|
||||
{
|
||||
private $parameters;
|
||||
private static $parameters = array(
|
||||
'baz_class' => 'BazClass',
|
||||
'foo_class' => 'Bar\\FooClass',
|
||||
'foo' => 'bar',
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->parameters = $this->getDefaultParameters();
|
||||
|
||||
$this->services =
|
||||
$this->scopedServices =
|
||||
$this->scopeStacks = array();
|
||||
|
|
@ -46,7 +48,9 @@ class ProjectServiceContainer extends Container
|
|||
'foo_bar' => 'getFooBarService',
|
||||
'foo_with_inline' => 'getFooWithInlineService',
|
||||
'method_call1' => 'getMethodCall1Service',
|
||||
'new_factory_service' => 'getNewFactoryServiceService',
|
||||
'request' => 'getRequestService',
|
||||
'service_from_static_method' => 'getServiceFromStaticMethodService',
|
||||
);
|
||||
$this->aliases = array(
|
||||
'alias_for_alias' => 'foo',
|
||||
|
|
@ -55,6 +59,14 @@ class ProjectServiceContainer extends Container
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped frozen container.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'bar' service.
|
||||
*
|
||||
|
|
@ -261,6 +273,26 @@ class ProjectServiceContainer extends Container
|
|||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'new_factory_service' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return \FooBarBaz A FooBarBaz instance.
|
||||
*/
|
||||
protected function getNewFactoryServiceService()
|
||||
{
|
||||
$a = new \FactoryClass();
|
||||
$a->foo = 'bar';
|
||||
|
||||
$this->services['new_factory_service'] = $instance = $a->getInstance();
|
||||
|
||||
$instance->foo = 'bar';
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'request' service.
|
||||
*
|
||||
|
|
@ -274,6 +306,19 @@ class ProjectServiceContainer extends Container
|
|||
throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'service_from_static_method' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return \Bar\FooClass A Bar\FooClass instance.
|
||||
*/
|
||||
protected function getServiceFromStaticMethodService()
|
||||
{
|
||||
return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the 'request' service.
|
||||
*/
|
||||
|
|
@ -291,11 +336,11 @@ class ProjectServiceContainer extends Container
|
|||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters))) {
|
||||
if (!(isset(self::$parameters[$name]) || array_key_exists($name, self::$parameters))) {
|
||||
throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
|
||||
}
|
||||
|
||||
return $this->parameters[$name];
|
||||
return self::$parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -305,7 +350,7 @@ class ProjectServiceContainer extends Container
|
|||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
return isset(self::$parameters[$name]) || array_key_exists($name, self::$parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -322,22 +367,9 @@ class ProjectServiceContainer extends Container
|
|||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
$this->parameterBag = new FrozenParameterBag($this->parameters);
|
||||
$this->parameterBag = new FrozenParameterBag(self::$parameters);
|
||||
}
|
||||
|
||||
return $this->parameterBag;
|
||||
}
|
||||
/**
|
||||
* Gets the default parameters.
|
||||
*
|
||||
* @return array An array of the default parameters
|
||||
*/
|
||||
protected function getDefaultParameters()
|
||||
{
|
||||
return array(
|
||||
'baz_class' => 'BazClass',
|
||||
'foo_class' => 'Bar\\FooClass',
|
||||
'foo' => 'bar',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,5 +52,14 @@
|
|||
<service id="request" class="Request" synthetic="true" synchronized="true" lazy="true"/>
|
||||
<service id="decorator_service" decorates="decorated" />
|
||||
<service id="decorator_service_with_name" decorates="decorated" decoration-inner-name="decorated.pif-pouf"/>
|
||||
<service id="new_factory1" class="FooBarClass">
|
||||
<factory function="factory" />
|
||||
</service>
|
||||
<service id="new_factory2" class="FooBarClass">
|
||||
<factory service="baz" method="getClass" />
|
||||
</service>
|
||||
<service id="new_factory3" class="FooBarClass">
|
||||
<factory class="BazClass" method="getInstance" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue