diff --git a/.gitattributes b/.gitattributes index 16d8d2934..ef2513dc9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,3 +8,4 @@ /phpcs.xml export-ignore /phpunit.xml.dist export-ignore /test/ export-ignore +/phpstan.neon.dist export-ignore diff --git a/.gitignore b/.gitignore index 245087af8..ba75cfde2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /coveralls-upload.json /docs/html/ /phpunit.xml +/phpstan.neon /vendor/ /zf-mkdoc-theme.tgz /zf-mkdoc-theme/ diff --git a/.travis.yml b/.travis.yml index 3c5f852b5..6078afe2c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ env: global: - COMPOSER_ARGS="--no-interaction" - COVERAGE_DEPS="php-coveralls/php-coveralls" + - PHPSTAN_DEPS="phpstan/phpstan:^0.10.3" matrix: include: @@ -41,6 +42,7 @@ matrix: - DEPS=locked - CS_CHECK=true - TEST_COVERAGE=true + - PHPSTAN_TEST=true - php: 7.1 env: - DEPS=latest @@ -63,11 +65,13 @@ install: - if [[ $DEPS == 'latest' ]]; then travis_retry composer update $COMPOSER_ARGS ; fi - if [[ $DEPS == 'lowest' ]]; then travis_retry composer update --prefer-lowest --prefer-stable $COMPOSER_ARGS ; fi - if [[ $TEST_COVERAGE == 'true' ]]; then travis_retry composer require --dev $COMPOSER_ARGS $COVERAGE_DEPS ; fi + - if [[ $PHPSTAN_TEST == 'true' ]]; then travis_retry composer require --dev $COMPOSER_ARGS $PHPSTAN_DEPS ; fi - stty cols 120 && composer show script: - if [[ $TEST_COVERAGE == 'true' ]]; then composer test-coverage ; else composer test ; fi - if [[ $CS_CHECK == 'true' ]]; then composer cs-check ; fi + - if [[ $PHPSTAN_TEST == 'true' ]]; then ./vendor/bin/phpstan analyse --no-progress . ; fi after_script: - if [[ $TEST_COVERAGE == 'true' ]]; then vendor/bin/php-coveralls -v ; fi diff --git a/composer.json b/composer.json index e34462775..44ef632fb 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "zendframework", "mvc" ], + "version": "3.2-dev", "support": { "docs": "https://docs.zendframework.com/zend-mvc/", "issues": "https://github.com/zendframework/zend-mvc/issues", diff --git a/composer.lock b/composer.lock index 0087b6629..0183416bd 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4dca15262833c4fd34ad940c5472e161", + "content-hash": "b14c28913c90f5f00cd5276a57bf6729", "packages": [ { "name": "container-interop/container-interop", @@ -88,16 +88,16 @@ }, { "name": "zendframework/zend-config", - "version": "3.1.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-config.git", - "reference": "a12e4a592bf66d9629b84960e268f3752e53abe4" + "reference": "6796f5dcba52c84ef2501d7313618989b5ef3023" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-config/zipball/a12e4a592bf66d9629b84960e268f3752e53abe4", - "reference": "a12e4a592bf66d9629b84960e268f3752e53abe4", + "url": "https://api.github.com/repos/zendframework/zend-config/zipball/6796f5dcba52c84ef2501d7313618989b5ef3023", + "reference": "6796f5dcba52c84ef2501d7313618989b5ef3023", "shasum": "" }, "require": { @@ -110,23 +110,23 @@ "container-interop/container-interop": "<1.2.0" }, "require-dev": { - "malukenho/docheader": "^0.1.5", - "phpunit/phpunit": "^5.7 || ^6.0", + "malukenho/docheader": "^0.1.6", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-filter": "^2.7.1", - "zendframework/zend-i18n": "^2.7.3", - "zendframework/zend-servicemanager": "^2.7.8 || ^3.2.1" + "zendframework/zend-filter": "^2.7.2", + "zendframework/zend-i18n": "^2.7.4", + "zendframework/zend-servicemanager": "^2.7.8 || ^3.3" }, "suggest": { - "zendframework/zend-filter": "^2.7.1; install if you want to use the Filter processor", - "zendframework/zend-i18n": "^2.7.3; install if you want to use the Translator processor", - "zendframework/zend-servicemanager": "^2.7.8 || ^3.2.1; if you need an extensible plugin manager for use with the Config Factory" + "zendframework/zend-filter": "^2.7.2; install if you want to use the Filter processor", + "zendframework/zend-i18n": "^2.7.4; install if you want to use the Translator processor", + "zendframework/zend-servicemanager": "^2.7.8 || ^3.3; if you need an extensible plugin manager for use with the Config Factory" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev", - "dev-develop": "3.2-dev" + "dev-master": "3.2.x-dev", + "dev-develop": "3.3.x-dev" } }, "autoload": { @@ -139,39 +139,39 @@ "BSD-3-Clause" ], "description": "provides a nested object property based user interface for accessing this configuration data within application code", - "homepage": "https://github.com/zendframework/zend-config", "keywords": [ + "ZendFramework", "config", - "zf2" + "zf" ], - "time": "2017-02-22T14:31:10+00:00" + "time": "2018-04-24T19:26:44+00:00" }, { "name": "zendframework/zend-escaper", - "version": "2.5.2", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-escaper.git", - "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e" + "reference": "31d8aafae982f9568287cb4dce987e6aff8fd074" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/2dcd14b61a72d8b8e27d579c6344e12c26141d4e", - "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e", + "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/31d8aafae982f9568287cb4dce987e6aff8fd074", + "reference": "31d8aafae982f9568287cb4dce987e6aff8fd074", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^5.6 || ^7.0" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" } }, "autoload": { @@ -183,25 +183,26 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-escaper", + "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", "keywords": [ + "ZendFramework", "escaper", - "zf2" + "zf" ], - "time": "2016-06-30T19:48:38+00:00" + "time": "2018-04-25T15:48:53+00:00" }, { "name": "zendframework/zend-eventmanager", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-eventmanager.git", - "reference": "9d72db10ceb6e42fb92350c0cb54460da61bd79c" + "reference": "a5e2583a211f73604691586b8406ff7296a946dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/9d72db10ceb6e42fb92350c0cb54460da61bd79c", - "reference": "9d72db10ceb6e42fb92350c0cb54460da61bd79c", + "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/a5e2583a211f73604691586b8406ff7296a946dd", + "reference": "a5e2583a211f73604691586b8406ff7296a946dd", "shasum": "" }, "require": { @@ -210,7 +211,7 @@ "require-dev": { "athletic/athletic": "^0.1", "container-interop/container-interop": "^1.1.0", - "phpunit/phpunit": "^6.0.7 || ^5.7.14", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-stdlib": "^2.7.3 || ^3.0" }, @@ -242,20 +243,20 @@ "events", "zf2" ], - "time": "2017-07-11T19:17:22+00:00" + "time": "2018-04-25T15:33:34+00:00" }, { "name": "zendframework/zend-http", - "version": "2.7.0", + "version": "2.8.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-http.git", - "reference": "78aa510c0ea64bfb2aa234f50c4f232c9531acfa" + "reference": "2c8aed3d25522618573194e7cc51351f8cd4a45b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-http/zipball/78aa510c0ea64bfb2aa234f50c4f232c9531acfa", - "reference": "78aa510c0ea64bfb2aa234f50c4f232c9531acfa", + "url": "https://api.github.com/repos/zendframework/zend-http/zipball/2c8aed3d25522618573194e7cc51351f8cd4a45b", + "reference": "2c8aed3d25522618573194e7cc51351f8cd4a45b", "shasum": "" }, "require": { @@ -266,15 +267,18 @@ "zendframework/zend-validator": "^2.10.1" }, "require-dev": { - "phpunit/phpunit": "^6.4.1 || ^5.7.15", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.3", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-config": "^3.1 || ^2.6" }, + "suggest": { + "paragonie/certainty": "For automated management of cacert.pem" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" + "dev-master": "2.8.x-dev", + "dev-develop": "2.9.x-dev" } }, "autoload": { @@ -286,8 +290,7 @@ "license": [ "BSD-3-Clause" ], - "description": "provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests", - "homepage": "https://github.com/zendframework/zend-http", + "description": "Provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests", "keywords": [ "ZendFramework", "http", @@ -295,34 +298,34 @@ "zend", "zf" ], - "time": "2017-10-13T12:06:24+00:00" + "time": "2018-08-13T18:47:03+00:00" }, { "name": "zendframework/zend-loader", - "version": "2.5.1", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-loader.git", - "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c" + "reference": "78f11749ea340f6ca316bca5958eef80b38f9b6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/c5fd2f071bde071f4363def7dea8dec7393e135c", - "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c", + "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/78f11749ea340f6ca316bca5958eef80b38f9b6c", + "reference": "78f11749ea340f6ca316bca5958eef80b38f9b6c", "shasum": "" }, "require": { - "php": ">=5.3.23" + "php": "^5.6 || ^7.0" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.4", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" } }, "autoload": { @@ -334,32 +337,33 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-loader", + "description": "Autoloading and plugin loading strategies", "keywords": [ + "ZendFramework", "loader", - "zf2" + "zf" ], - "time": "2015-06-03T14:05:47+00:00" + "time": "2018-04-30T15:20:54+00:00" }, { "name": "zendframework/zend-modulemanager", - "version": "2.8.1", + "version": "2.8.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-modulemanager.git", - "reference": "710c13353b1ff0975777dbeb39bbf1c85e3353a3" + "reference": "394df6e12248ac430a312d4693f793ee7120baa6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-modulemanager/zipball/710c13353b1ff0975777dbeb39bbf1c85e3353a3", - "reference": "710c13353b1ff0975777dbeb39bbf1c85e3353a3", + "url": "https://api.github.com/repos/zendframework/zend-modulemanager/zipball/394df6e12248ac430a312d4693f793ee7120baa6", + "reference": "394df6e12248ac430a312d4693f793ee7120baa6", "shasum": "" }, "require": { "php": "^5.6 || ^7.0", "zendframework/zend-config": "^3.1 || ^2.6", "zendframework/zend-eventmanager": "^3.2 || ^2.6.3", - "zendframework/zend-stdlib": "^3.0 || ^2.7" + "zendframework/zend-stdlib": "^3.1 || ^2.7" }, "require-dev": { "phpunit/phpunit": "^6.0.8 || ^5.7.15", @@ -367,7 +371,7 @@ "zendframework/zend-console": "^2.6", "zendframework/zend-di": "^2.6", "zendframework/zend-loader": "^2.5", - "zendframework/zend-mvc": "^2.7", + "zendframework/zend-mvc": "^3.0 || ^2.7", "zendframework/zend-servicemanager": "^3.0.3 || ^2.7.5" }, "suggest": { @@ -379,8 +383,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev", - "dev-develop": "2.9-dev" + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" } }, "autoload": { @@ -392,51 +396,52 @@ "license": [ "BSD-3-Clause" ], + "description": "Modular application system for zend-mvc applications", "homepage": "https://github.com/zendframework/zend-modulemanager", "keywords": [ + "ZendFramework", "modulemanager", - "zf2" + "zf" ], - "time": "2017-11-01T18:30:41+00:00" + "time": "2017-12-02T06:11:18+00:00" }, { "name": "zendframework/zend-router", - "version": "3.0.2", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-router.git", - "reference": "03763610632a9022aff22a0e8f340852e68392a1" + "reference": "a80a7427afb8f736b9aeeb341a78dae855849291" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-router/zipball/03763610632a9022aff22a0e8f340852e68392a1", - "reference": "03763610632a9022aff22a0e8f340852e68392a1", + "url": "https://api.github.com/repos/zendframework/zend-router/zipball/a80a7427afb8f736b9aeeb341a78dae855849291", + "reference": "a80a7427afb8f736b9aeeb341a78dae855849291", "shasum": "" }, "require": { - "container-interop/container-interop": "^1.1", - "php": "^5.5 || ^7.0", - "zendframework/zend-http": "^2.5", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-stdlib": "^2.7.5 || ^3.0" + "container-interop/container-interop": "^1.2", + "php": "^5.6 || ^7.0", + "zendframework/zend-http": "^2.8.1", + "zendframework/zend-servicemanager": "^2.7.8 || ^3.3", + "zendframework/zend-stdlib": "^2.7.7 || ^3.1" }, "conflict": { "zendframework/zend-mvc": "<3.0.0" }, "require-dev": { - "phpunit/phpunit": "^4.5", - "sebastian/version": "^1.0.4", - "squizlabs/php_codesniffer": "^2.3", - "zendframework/zend-i18n": "^2.6" + "phpunit/phpunit": "^5.7.22 || ^6.4.1", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-i18n": "^2.7.4" }, "suggest": { - "zendframework/zend-i18n": "^2.6, if defining translatable HTTP path segments" + "zendframework/zend-i18n": "^2.7.4, if defining translatable HTTP path segments" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev", - "dev-develop": "3.1-dev" + "dev-master": "3.2.x-dev", + "dev-develop": "3.3.x-dev" }, "zf": { "component": "Zend\\Router", @@ -452,26 +457,28 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-router", + "description": "Flexible routing system for HTTP and console applications", "keywords": [ + "ZendFramework", "mvc", "routing", - "zf2" + "zend", + "zf" ], - "time": "2016-05-31T20:47:48+00:00" + "time": "2018-08-01T22:24:35+00:00" }, { "name": "zendframework/zend-servicemanager", - "version": "3.3.0", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-servicemanager.git", - "reference": "c3036efb81f71bfa36cc9962ee5d4474f36581d0" + "reference": "9f35a104b8d4d3b32da5f4a3b6efc0dd62e5af42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/c3036efb81f71bfa36cc9962ee5d4474f36581d0", - "reference": "c3036efb81f71bfa36cc9962ee5d4474f36581d0", + "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/9f35a104b8d4d3b32da5f4a3b6efc0dd62e5af42", + "reference": "9f35a104b8d4d3b32da5f4a3b6efc0dd62e5af42", "shasum": "" }, "require": { @@ -485,10 +492,10 @@ "psr/container-implementation": "^1.0" }, "require-dev": { - "mikey179/vfsstream": "^1.6", + "mikey179/vfsstream": "^1.6.5", "ocramius/proxy-manager": "^1.0 || ^2.0", - "phpbench/phpbench": "^0.10.0", - "phpunit/phpunit": "^5.7 || ^6.0.6", + "phpbench/phpbench": "^0.13.0", + "phpunit/phpunit": "^5.7.25 || ^6.4.4", "zendframework/zend-coding-standard": "~1.0.0" }, "suggest": { @@ -503,7 +510,7 @@ "extra": { "branch-alias": { "dev-master": "3.3-dev", - "dev-develop": "3.4-dev" + "dev-develop": "4.0-dev" } }, "autoload": { @@ -515,41 +522,46 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-servicemanager", + "description": "Factory-Driven Dependency Injection Container", "keywords": [ + "PSR-11", + "ZendFramework", + "dependency-injection", + "di", + "dic", "service-manager", "servicemanager", "zf" ], - "time": "2017-03-01T22:08:02+00:00" + "time": "2018-01-29T16:48:37+00:00" }, { "name": "zendframework/zend-stdlib", - "version": "3.1.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78" + "reference": "66536006722aff9e62d1b331025089b7ec71c065" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/debedcfc373a293f9250cc9aa03cf121428c8e78", - "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/66536006722aff9e62d1b331025089b7ec71c065", + "reference": "66536006722aff9e62d1b331025089b7ec71c065", "shasum": "" }, "require": { "php": "^5.6 || ^7.0" }, "require-dev": { - "athletic/athletic": "~0.1", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "^2.6.2" + "phpbench/phpbench": "^0.13", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev", - "dev-develop": "3.2-dev" + "dev-master": "3.2.x-dev", + "dev-develop": "3.3.x-dev" } }, "autoload": { @@ -561,41 +573,42 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-stdlib", + "description": "SPL extensions, array utilities, error handlers, and more", "keywords": [ + "ZendFramework", "stdlib", - "zf2" + "zf" ], - "time": "2016-09-13T14:38:50+00:00" + "time": "2018-08-28T21:34:05+00:00" }, { "name": "zendframework/zend-uri", - "version": "2.5.2", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-uri.git", - "reference": "0bf717a239432b1a1675ae314f7c4acd742749ed" + "reference": "3b6463645c6766f78ce537c70cb4fdabee1e725f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-uri/zipball/0bf717a239432b1a1675ae314f7c4acd742749ed", - "reference": "0bf717a239432b1a1675ae314f7c4acd742749ed", + "url": "https://api.github.com/repos/zendframework/zend-uri/zipball/3b6463645c6766f78ce537c70cb4fdabee1e725f", + "reference": "3b6463645c6766f78ce537c70cb4fdabee1e725f", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", + "php": "^5.6 || ^7.0", "zendframework/zend-escaper": "^2.5", - "zendframework/zend-validator": "^2.5" + "zendframework/zend-validator": "^2.10" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.4", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" } }, "autoload": { @@ -607,26 +620,26 @@ "license": [ "BSD-3-Clause" ], - "description": "a component that aids in manipulating and validating » Uniform Resource Identifiers (URIs)", - "homepage": "https://github.com/zendframework/zend-uri", + "description": "A component that aids in manipulating and validating » Uniform Resource Identifiers (URIs)", "keywords": [ + "ZendFramework", "uri", - "zf2" + "zf" ], - "time": "2016-02-17T22:38:51+00:00" + "time": "2018-04-30T13:40:08+00:00" }, { "name": "zendframework/zend-validator", - "version": "2.10.1", + "version": "2.10.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-validator.git", - "reference": "010084ddbd33299bf51ea6f0e07f8f4e8bd832a8" + "reference": "38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/010084ddbd33299bf51ea6f0e07f8f4e8bd832a8", - "reference": "010084ddbd33299bf51ea6f0e07f8f4e8bd832a8", + "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9", + "reference": "38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9", "shasum": "" }, "require": { @@ -661,8 +674,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.10-dev", - "dev-develop": "2.11-dev" + "dev-master": "2.10.x-dev", + "dev-develop": "2.11.x-dev" }, "zf": { "component": "Zend\\Validator", @@ -684,20 +697,20 @@ "validator", "zf2" ], - "time": "2017-08-22T14:19:23+00:00" + "time": "2018-02-01T17:05:33+00:00" }, { "name": "zendframework/zend-view", - "version": "2.9.0", + "version": "2.10.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-view.git", - "reference": "3b6342c381c4437a03fc81d0064c0bb8924914d3" + "reference": "4478cc5dd960e2339d88b363ef99fa278700e80e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-view/zipball/3b6342c381c4437a03fc81d0064c0bb8924914d3", - "reference": "3b6342c381c4437a03fc81d0064c0bb8924914d3", + "url": "https://api.github.com/repos/zendframework/zend-view/zipball/4478cc5dd960e2339d88b363ef99fa278700e80e", + "reference": "4478cc5dd960e2339d88b363ef99fa278700e80e", "shasum": "" }, "require": { @@ -728,7 +741,7 @@ "zendframework/zend-router": "^3.0.1", "zendframework/zend-serializer": "^2.6.1", "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-session": "^2.6.2", + "zendframework/zend-session": "^2.8.1", "zendframework/zend-uri": "^2.5" }, "suggest": { @@ -752,8 +765,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.9-dev", - "dev-develop": "3.0-dev" + "dev-master": "2.10.x-dev", + "dev-develop": "2.11.x-dev" } }, "autoload": { @@ -771,38 +784,38 @@ "view", "zf2" ], - "time": "2017-03-21T15:05:56+00:00" + "time": "2018-01-17T22:21:50+00:00" } ], "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.1.0", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=5.3,<8.0-DEV" }, "require-dev": { "athletic/athletic": "~0.1.8", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { @@ -827,7 +840,7 @@ "constructor", "instantiate" ], - "time": "2017-07-22T11:58:36+00:00" + "time": "2015-06-14T21:17:01+00:00" }, { "name": "http-interop/http-middleware", @@ -927,108 +940,6 @@ ], "time": "2017-10-19T19:58:43+00:00" }, - { - "name": "phar-io/manifest", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" - }, - { - "name": "phar-io/version", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" - }, { "name": "phpdocumentor/reflection-common", "version": "1.0.1", @@ -1085,21 +996,21 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.1.1", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2" + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2d3d238c433cf69caeb4842e97a3223a116f94b2", - "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", "shasum": "" }, "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0@dev", + "php": "^5.6 || ^7.0", + "phpdocumentor/reflection-common": "^1.0.0", "phpdocumentor/type-resolver": "^0.4.0", "webmozart/assert": "^1.0" }, @@ -1126,7 +1037,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-08-30T18:51:59+00:00" + "time": "2017-11-10T14:09:06+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -1177,33 +1088,33 @@ }, { "name": "phpspec/prophecy", - "version": "v1.7.2", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6" + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", - "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8 || ^5.6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7.x-dev" + "dev-master": "1.8.x-dev" } }, "autoload": { @@ -1236,45 +1147,44 @@ "spy", "stub" ], - "time": "2017-09-04T11:05:03+00:00" + "time": "2018-08-05T17:53:17+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "5.2.3", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d" + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d", - "reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.2 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "^1.0 || ^2.0" }, "require-dev": { - "ext-xdebug": "^2.5", - "phpunit/phpunit": "^6.0" + "ext-xdebug": "^2.1.4", + "phpunit/phpunit": "^5.7" }, "suggest": { - "ext-xdebug": "^2.5.5" + "ext-xdebug": "^2.5.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.2.x-dev" + "dev-master": "4.0.x-dev" } }, "autoload": { @@ -1300,20 +1210,20 @@ "testing", "xunit" ], - "time": "2017-11-03T13:47:33+00:00" + "time": "2017-04-02T07:44:40+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.2", + "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", "shasum": "" }, "require": { @@ -1347,7 +1257,7 @@ "filesystem", "iterator" ], - "time": "2016-10-03T07:40:28+00:00" + "time": "2017-11-27T13:52:08+00:00" }, { "name": "phpunit/php-text-template", @@ -1441,29 +1351,29 @@ }, { "name": "phpunit/php-token-stream", - "version": "2.0.1", + "version": "1.4.12", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0" + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9a02332089ac48e704c70f6cefed30c224e3c0b0", - "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": "^7.0" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "^6.2.4" + "phpunit/phpunit": "~4.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -1486,20 +1396,20 @@ "keywords": [ "tokenizer" ], - "time": "2017-08-20T05:47:52+00:00" + "time": "2017-12-04T08:55:13+00:00" }, { "name": "phpunit/phpunit", - "version": "6.4.4", + "version": "5.7.27", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "562f7dc75d46510a4ed5d16189ae57fbe45a9932" + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/562f7dc75d46510a4ed5d16189ae57fbe45a9932", - "reference": "562f7dc75d46510a4ed5d16189ae57fbe45a9932", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", "shasum": "" }, "require": { @@ -1508,35 +1418,33 @@ "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.2.2", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^4.0.3", - "sebastian/comparator": "^2.0.2", - "sebastian/diff": "^2.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0.1" + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.4", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "^1.2.4", + "sebastian/diff": "^1.4.3", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.1", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "^1.0.6|^2.0.1", + "symfony/yaml": "~2.1|~3.0|~4.0" }, "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" + "phpdocumentor/reflection-docblock": "3.0.2" }, "require-dev": { "ext-pdo": "*" }, "suggest": { "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" + "phpunit/php-invoker": "~1.1" }, "bin": [ "phpunit" @@ -1544,7 +1452,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.4.x-dev" + "dev-master": "5.7.x-dev" } }, "autoload": { @@ -1570,33 +1478,33 @@ "testing", "xunit" ], - "time": "2017-11-08T11:26:09+00:00" + "time": "2018-02-01T05:50:59+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "4.0.4", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "2f789b59ab89669015ad984afa350c4ec577ade0" + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/2f789b59ab89669015ad984afa350c4ec577ade0", - "reference": "2f789b59ab89669015ad984afa350c4ec577ade0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.0" + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" }, "conflict": { - "phpunit/phpunit": "<6.0" + "phpunit/phpunit": "<5.4.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^5.4" }, "suggest": { "ext-soap": "*" @@ -1604,7 +1512,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "3.2.x-dev" } }, "autoload": { @@ -1629,7 +1537,7 @@ "mock", "xunit" ], - "time": "2017-08-03T14:08:16+00:00" + "time": "2017-06-30T09:13:00+00:00" }, { "name": "psr/http-message", @@ -1728,30 +1636,30 @@ }, { "name": "sebastian/comparator", - "version": "2.1.0", + "version": "1.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1174d9018191e93cb9d719edec01257fc05f8158" + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1174d9018191e93cb9d719edec01257fc05f8158", - "reference": "1174d9018191e93cb9d719edec01257fc05f8158", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/diff": "^2.0", - "sebastian/exporter": "^3.1" + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" }, "require-dev": { - "phpunit/phpunit": "^6.4" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -1782,38 +1690,38 @@ } ], "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", + "homepage": "http://www.github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], - "time": "2017-11-03T07:16:52+00:00" + "time": "2017-01-29T09:50:25+00:00" }, { "name": "sebastian/diff", - "version": "2.0.1", + "version": "1.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^6.2" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -1840,32 +1748,32 @@ "keywords": [ "diff" ], - "time": "2017-08-03T08:09:46+00:00" + "time": "2017-05-22T07:24:03+00:00" }, { "name": "sebastian/environment", - "version": "3.1.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^6.1" + "phpunit/phpunit": "^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1890,34 +1798,34 @@ "environment", "hhvm" ], - "time": "2017-07-01T08:51:00+00:00" + "time": "2016-11-26T07:53:53+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" + "php": ">=5.3.3", + "sebastian/recursion-context": "~2.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1957,27 +1865,27 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2016-11-19T08:54:04+00:00" }, { "name": "sebastian/global-state", - "version": "2.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "~4.2" }, "suggest": { "ext-uopz": "*" @@ -1985,7 +1893,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "1.0-dev" } }, "autoload": { @@ -2008,34 +1916,33 @@ "keywords": [ "global state" ], - "time": "2017-04-27T15:39:26+00:00" + "time": "2015-10-12T03:26:01+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.3", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "~5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -2055,77 +1962,32 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "time": "2017-02-18T15:18:39+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -2153,7 +2015,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "time": "2016-11-19T07:33:16+00:00" }, { "name": "sebastian/resource-operations", @@ -2319,44 +2181,121 @@ "time": "2017-05-22T02:43:20+00:00" }, { - "name": "theseer/tokenizer", - "version": "1.1.0", + "name": "symfony/polyfill-ctype", + "version": "v1.9.0", "source": { "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.0" + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "640b6c27fed4066d64b64d5903a86043f4a4de7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/640b6c27fed4066d64b64d5903a86043f4a4de7f", + "reference": "640b6c27fed4066d64b64d5903a86043f4a4de7f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2018-10-02T16:33:53+00:00" }, { "name": "webimpress/composer-extra-dependency", @@ -2448,20 +2387,21 @@ "psr-15", "webimpress" ], + "abandoned": "psr/http-server-middleware", "time": "2017-10-17T17:31:10+00:00" }, { "name": "webmozart/assert", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", "shasum": "" }, "require": { @@ -2498,7 +2438,7 @@ "check", "validate" ], - "time": "2016-11-23T20:04:58+00:00" + "time": "2018-01-29T19:49:41+00:00" }, { "name": "zendframework/zend-coding-standard", @@ -2531,16 +2471,16 @@ }, { "name": "zendframework/zend-diactoros", - "version": "1.6.1", + "version": "1.8.6", "source": { "type": "git", "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "c8664b92a6d5bc229e48b0923486c097e45a7877" + "reference": "20da13beba0dde8fb648be3cc19765732790f46e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/c8664b92a6d5bc229e48b0923486c097e45a7877", - "reference": "c8664b92a6d5bc229e48b0923486c097e45a7877", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/20da13beba0dde8fb648be3cc19765732790f46e", + "reference": "20da13beba0dde8fb648be3cc19765732790f46e", "shasum": "" }, "require": { @@ -2553,17 +2493,29 @@ "require-dev": { "ext-dom": "*", "ext-libxml": "*", - "phpunit/phpunit": "^5.7.16 || ^6.0.8", + "php-http/psr7-integration-tests": "dev-master", + "phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7", "zendframework/zend-coding-standard": "~1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev", - "dev-develop": "1.7-dev" + "dev-master": "1.8.x-dev", + "dev-develop": "1.9.x-dev", + "dev-release-2.0": "2.0.x-dev" } }, "autoload": { + "files": [ + "src/functions/create_uploaded_file.php", + "src/functions/marshal_headers_from_sapi.php", + "src/functions/marshal_method_from_sapi.php", + "src/functions/marshal_protocol_version_from_sapi.php", + "src/functions/marshal_uri_from_sapi.php", + "src/functions/normalize_server.php", + "src/functions/normalize_uploaded_files.php", + "src/functions/parse_cookie_header.php" + ], "psr-4": { "Zend\\Diactoros\\": "src/" } @@ -2579,29 +2531,29 @@ "psr", "psr-7" ], - "time": "2017-10-12T15:24:51+00:00" + "time": "2018-09-05T19:29:37+00:00" }, { "name": "zendframework/zend-json", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-json.git", - "reference": "f42a1588e75c2a3e338cd94c37906231e616daab" + "reference": "4dd940e8e6f32f1d36ea6b0677ea57c540c7c19c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-json/zipball/f42a1588e75c2a3e338cd94c37906231e616daab", - "reference": "f42a1588e75c2a3e338cd94c37906231e616daab", + "url": "https://api.github.com/repos/zendframework/zend-json/zipball/4dd940e8e6f32f1d36ea6b0677ea57c540c7c19c", + "reference": "4dd940e8e6f32f1d36ea6b0677ea57c540c7c19c", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "^2.3", - "zendframework/zend-stdlib": "^2.7 || ^3.0" + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-stdlib": "^2.7.7 || ^3.1" }, "suggest": { "zendframework/zend-json-server": "For implementing JSON-RPC servers", @@ -2610,8 +2562,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev", - "dev-develop": "3.1-dev" + "dev-master": "3.1.x-dev", + "dev-develop": "3.2.x-dev" } }, "autoload": { @@ -2624,42 +2576,42 @@ "BSD-3-Clause" ], "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP", - "homepage": "https://github.com/zendframework/zend-json", "keywords": [ + "ZendFramework", "json", - "zf2" + "zf" ], - "time": "2016-04-01T02:34:00+00:00" + "time": "2018-01-04T17:51:34+00:00" }, { "name": "zendframework/zend-psr7bridge", - "version": "1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-psr7bridge.git", - "reference": "935721336ded76fd5ba90ba7637c7d85b4d0cf68" + "reference": "9b46ee86e9360f5fcd61a962381d68bcad7cc881" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-psr7bridge/zipball/935721336ded76fd5ba90ba7637c7d85b4d0cf68", - "reference": "935721336ded76fd5ba90ba7637c7d85b4d0cf68", + "url": "https://api.github.com/repos/zendframework/zend-psr7bridge/zipball/9b46ee86e9360f5fcd61a962381d68bcad7cc881", + "reference": "9b46ee86e9360f5fcd61a962381d68bcad7cc881", "shasum": "" }, "require": { "php": "^5.6 || ^7.0", "psr/http-message": "^1.0", - "zendframework/zend-diactoros": "^1.1", - "zendframework/zend-http": "^2.6" + "zendframework/zend-diactoros": "^1.7 || ^2.0", + "zendframework/zend-http": "^2.7" }, "require-dev": { - "phpunit/phpunit": "^5.7.15 || ^6.0.8", + "phpunit/phpunit": "^5.7.15 || ^6.5.6", "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev", - "dev-develop": "1.1-dev" + "dev-master": "1.1.x-dev", + "dev-develop": "1.2.x-dev" } }, "autoload": { @@ -2671,40 +2623,40 @@ "license": [ "BSD-3-Clause" ], - "description": "PSR-7 <-> Zend\\Http bridge", - "homepage": "https://github.com/zendframework/zend-psr7bridge", + "description": "PSR-7 <-> zend-http message conversions", "keywords": [ "ZendFramework", "http", "psr", "psr-7", - "zend" + "zend", + "zf" ], - "time": "2017-08-02T15:52:02+00:00" + "time": "2018-09-27T21:12:00+00:00" }, { "name": "zendframework/zend-stratigility", - "version": "2.1.2", + "version": "2.2.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-stratigility.git", - "reference": "7dfec8dee92dad0d01e68365015f2848c250fe9f" + "reference": "840e41d1984e8845c5539c769fedc5e7bb00a4d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stratigility/zipball/7dfec8dee92dad0d01e68365015f2848c250fe9f", - "reference": "7dfec8dee92dad0d01e68365015f2848c250fe9f", + "url": "https://api.github.com/repos/zendframework/zend-stratigility/zipball/840e41d1984e8845c5539c769fedc5e7bb00a4d5", + "reference": "840e41d1984e8845c5539c769fedc5e7bb00a4d5", "shasum": "" }, "require": { "php": "^5.6 || ^7.0", "psr/http-message": "^1.0", - "webimpress/http-middleware-compatibility": "^0.1.3", + "webimpress/http-middleware-compatibility": "^0.1.4", "zendframework/zend-escaper": "^2.3" }, "require-dev": { "malukenho/docheader": "^0.1.5", - "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "phpunit/phpunit": "^5.7.22 || ^6.4.1", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-diactoros": "^1.0" }, @@ -2714,11 +2666,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.0-dev", - "dev-develop": "2.2.0-dev" + "dev-master": "2.2.x-dev", + "dev-develop": "3.0.x-dev" } }, "autoload": { + "files": [ + "src/functions/double-pass-middleware.php", + "src/functions/middleware.php", + "src/functions/path.php" + ], "psr-4": { "Zend\\Stratigility\\": "src/" } @@ -2730,11 +2687,13 @@ "description": "Middleware for PHP", "homepage": "https://github.com/zendframework/zend-stratigility", "keywords": [ + "ZendFramework", "http", "middleware", - "psr-7" + "psr-7", + "zf" ], - "time": "2017-10-12T13:14:14+00:00" + "time": "2018-04-16T18:22:03+00:00" } ], "aliases": [], diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 000000000..60a6e0d07 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,17 @@ +parameters: + level: 7 + + fileExtensions: + - php + + excludes_analyse: + - %currentWorkingDirectory%/docs/* + - %currentWorkingDirectory%/test/* + - %currentWorkingDirectory%/vendor/* + + ignoreErrors: + - '#Function zend_monitor_custom_event_ex not found#' + - '#PHPDoc tag @throws with type Zend\\ModuleManager\\Listener\\ServiceListenerInterface is not subtype of Throwable#' + - '#Access to an undefined property Zend\\Http\\Header\\Accept\\FieldValuePart\\AbstractFieldValuePart::\$params#' + - "#Casting to [a-z]+ something that's already [a-z]+#" + diff --git a/src/Controller/AbstractActionController.php b/src/Controller/AbstractActionController.php index 54277ab31..0da35ff3d 100644 --- a/src/Controller/AbstractActionController.php +++ b/src/Controller/AbstractActionController.php @@ -42,6 +42,11 @@ public function notFoundAction() { $event = $this->getEvent(); $routeMatch = $event->getRouteMatch(); + + if (null === $routeMatch) { + throw new Exception\RuntimeException('Event does not have a RouteMatch'); + } + $routeMatch->setParam('action', 'not-found'); $helper = $this->plugin('createHttpNotFoundModel'); diff --git a/src/Controller/AbstractController.php b/src/Controller/AbstractController.php index da634c5c6..eb733370a 100644 --- a/src/Controller/AbstractController.php +++ b/src/Controller/AbstractController.php @@ -40,27 +40,27 @@ abstract class AbstractController implements InjectApplicationEventInterface { /** - * @var PluginManager + * @var null|PluginManager */ protected $plugins; /** - * @var Request + * @var null|Request */ protected $request; /** - * @var Response + * @var null|Response */ protected $response; /** - * @var Event + * @var null|MvcEvent */ protected $event; /** - * @var EventManagerInterface + * @var null|EventManagerInterface */ protected $events; @@ -149,7 +149,9 @@ public function setEventManager(EventManagerInterface $events) $className = get_class($this); $nsPos = strpos($className, '\\') ?: 0; - $events->setIdentifiers(array_merge( + + /** @var string[] $identifiers */ + $identifiers = array_merge( [ __CLASS__, $className, @@ -157,7 +159,9 @@ public function setEventManager(EventManagerInterface $events) ], array_values(class_implements($className)), (array) $this->eventIdentifier - )); + ); + + $events->setIdentifiers($identifiers); $this->events = $events; $this->attachDefaultListeners(); @@ -178,7 +182,10 @@ public function getEventManager() $this->setEventManager(new EventManager()); } - return $this->events; + /** @var EventManagerInterface $events */ + $events = $this->events; + + return $events; } /** @@ -213,7 +220,10 @@ public function getEvent() $this->setEvent(new MvcEvent()); } - return $this->event; + /** @var MvcEvent $event */ + $event = $this->event; + + return $event; } /** @@ -227,8 +237,11 @@ public function getPluginManager() $this->setPluginManager(new PluginManager(new ServiceManager())); } - $this->plugins->setController($this); - return $this->plugins; + /** @var PluginManager $plugins */ + $plugins = $this->plugins; + $plugins->setController($this); + + return $plugins; } /** diff --git a/src/Controller/AbstractRestfulController.php b/src/Controller/AbstractRestfulController.php index cff21f6db..ffb956581 100644 --- a/src/Controller/AbstractRestfulController.php +++ b/src/Controller/AbstractRestfulController.php @@ -6,10 +6,13 @@ */ namespace Zend\Mvc\Controller; +use Zend\Http\Headers; use Zend\Http\Request as HttpRequest; +use Zend\Http\Response as HttpResponse; use Zend\Json\Json; use Zend\Mvc\Exception; use Zend\Mvc\MvcEvent; +use Zend\Router\RouteMatch; use Zend\Stdlib\RequestInterface as Request; use Zend\Stdlib\ResponseInterface as Response; @@ -90,6 +93,20 @@ public function getIdentifierName() return $this->identifierName; } + /** + * @return HttpResponse + */ + private function getHttpResponse() + { + $response = $this->getResponse(); + + if (! $response instanceof HttpResponse) { + throw Exception\UnexpectedValueException::unexpectedType(HttpResponse::class, $response); + } + + return $response; + } + /** * Create a new resource * @@ -98,7 +115,7 @@ public function getIdentifierName() */ public function create($data) { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -113,7 +130,7 @@ public function create($data) */ public function delete($id) { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -130,7 +147,7 @@ public function delete($id) */ public function deleteList($data) { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -145,7 +162,7 @@ public function deleteList($data) */ public function get($id) { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -159,7 +176,7 @@ public function get($id) */ public function getList() { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -177,7 +194,7 @@ public function getList() */ public function head($id = null) { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -197,7 +214,7 @@ public function head($id = null) */ public function options() { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -210,13 +227,13 @@ public function options() * Not marked as abstract, as that would introduce a BC break * (introduced in 2.1.0); instead, raises an exception if not implemented. * - * @param $id - * @param $data + * @param mixed $id + * @param mixed $data * @return array */ public function patch($id, $data) { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -234,7 +251,7 @@ public function patch($id, $data) */ public function replaceList($data) { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -252,7 +269,7 @@ public function replaceList($data) */ public function patchList($data) { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -268,7 +285,7 @@ public function patchList($data) */ public function update($id, $data) { - $this->response->setStatusCode(405); + $this->getHttpResponse()->setStatusCode(405); return [ 'content' => 'Method Not Allowed' @@ -282,7 +299,7 @@ public function update($id, $data) */ public function notFoundAction() { - $this->response->setStatusCode(404); + $this->getHttpResponse()->setStatusCode(404); return [ 'content' => 'Page not found' @@ -331,6 +348,15 @@ public function onDispatch(MvcEvent $e) } $request = $e->getRequest(); + $response = $e->getResponse(); + + if (! $request instanceof HttpRequest) { + throw Exception\UnexpectedValueException::unexpectedType(HttpRequest::class, $request); + } + + if (! $response instanceof HttpResponse) { + throw Exception\UnexpectedValueException::unexpectedType(HttpResponse::class, $response); + } // Was an "action" requested? $action = $routeMatch->getParam('action', false); @@ -352,7 +378,7 @@ public function onDispatch(MvcEvent $e) case (isset($this->customHttpMethodsMap[$method])): $callable = $this->customHttpMethodsMap[$method]; $action = $method; - $return = call_user_func($callable, $e); + $return = $callable($e); break; // DELETE case 'delete': @@ -388,15 +414,15 @@ public function onDispatch(MvcEvent $e) } $action = 'head'; $headResult = $this->head($id); - $response = ($headResult instanceof Response) ? clone $headResult : $e->getResponse(); - $response->setContent(''); - $return = $response; + $resultResponse = ($headResult instanceof Response) ? clone $headResult : $response; + $resultResponse->setContent(''); + $return = $resultResponse; break; // OPTIONS case 'options': $action = 'options'; $this->options(); - $return = $e->getResponse(); + $return = $response; break; // PATCH case 'patch': @@ -416,7 +442,6 @@ public function onDispatch(MvcEvent $e) $action = 'patchList'; $return = $this->patchList($data); } catch (Exception\RuntimeException $ex) { - $response = $e->getResponse(); $response->setStatusCode(405); return $response; } @@ -442,7 +467,6 @@ public function onDispatch(MvcEvent $e) break; // All others... default: - $response = $e->getResponse(); $response->setStatusCode(405); return $response; } @@ -462,6 +486,10 @@ public function onDispatch(MvcEvent $e) */ public function processPostData(Request $request) { + if (! $request instanceof HttpRequest) { + throw Exception\InvalidArgumentException::unexpectedType(HttpRequest::class, $request); + } + if ($this->requestHasContentType($request, self::CONTENT_TYPE_JSON)) { return $this->create($this->jsonDecode($request->getContent())); } @@ -473,13 +501,19 @@ public function processPostData(Request $request) * Check if request has certain content type * * @param Request $request - * @param string|null $contentType + * @param string $contentType * @return bool */ public function requestHasContentType(Request $request, $contentType = '') { - /** @var $headerContentType \Zend\Http\Header\ContentType */ - $headerContentType = $request->getHeaders()->get('content-type'); + if (! $request instanceof HttpRequest) { + throw Exception\InvalidArgumentException::unexpectedType(HttpRequest::class, $request); + } + + /** @var Headers $headers */ + $headers = $request->getHeaders(); + /** @var \Zend\Http\Header\ContentType|null $headerContentType */ + $headerContentType = $headers->get('content-type'); if (! $headerContentType) { return false; } @@ -487,6 +521,7 @@ public function requestHasContentType(Request $request, $contentType = '') $requestedContentType = $headerContentType->getFieldValue(); if (false !== strpos($requestedContentType, ';')) { $headerData = explode(';', $requestedContentType); + /** @var string $requestedContentType */ $requestedContentType = array_shift($headerData); } $requestedContentType = trim($requestedContentType); @@ -546,12 +581,20 @@ public function addHttpMethodHandler($method, /* Callable */ $handler) * Attempts to see if an identifier was passed in either the URI or the * query string, returning it if found. Otherwise, returns a boolean false. * - * @param \Zend\Router\RouteMatch $routeMatch - * @param Request $request + * @param RouteMatch $routeMatch + * @param HttpRequest $request * @return false|mixed */ protected function getIdentifier($routeMatch, $request) { + if (! $routeMatch instanceof RouteMatch) { + throw Exception\InvalidArgumentException::unexpectedType(RouteMatch::class, $routeMatch); + } + + if (! $request instanceof HttpRequest) { + throw Exception\InvalidArgumentException::unexpectedType(HttpRequest::class, $request); + } + $identifier = $this->getIdentifierName(); $id = $routeMatch->getParam($identifier, false); if ($id !== false) { @@ -611,7 +654,7 @@ protected function processBodyContent($request) * * Marked protected to allow usage from extending classes. * - * @param string + * @param string $string * @return mixed * @throws Exception\DomainException if no JSON decoding functionality is * available. diff --git a/src/Controller/ControllerManager.php b/src/Controller/ControllerManager.php index 20e721655..3f0338d45 100644 --- a/src/Controller/ControllerManager.php +++ b/src/Controller/ControllerManager.php @@ -9,6 +9,7 @@ use Interop\Container\ContainerInterface; use Zend\EventManager\EventManagerAwareInterface; +use Zend\EventManager\EventManagerInterface; use Zend\EventManager\SharedEventManagerInterface; use Zend\ServiceManager\AbstractPluginManager; use Zend\ServiceManager\ConfigInterface; @@ -42,7 +43,7 @@ class ControllerManager extends AbstractPluginManager * Injects an initializer for injecting controllers with an * event manager and plugin manager. * - * @param ConfigInterface|ContainerInterface $container + * @param ConfigInterface|ContainerInterface $configOrContainerInstance * @param array $config */ public function __construct($configOrContainerInstance, array $config = []) @@ -87,6 +88,7 @@ public function injectEventManager(ContainerInterface $container, $controller) return; } + /** @var EventManagerInterface|null $events */ $events = $controller->getEventManager(); if (! $events || ! $events->getSharedManager() instanceof SharedEventManagerInterface) { $controller->setEventManager($container->get('EventManager')); diff --git a/src/Controller/LazyControllerAbstractFactory.php b/src/Controller/LazyControllerAbstractFactory.php index 0cd0f23d8..12e22495e 100644 --- a/src/Controller/LazyControllerAbstractFactory.php +++ b/src/Controller/LazyControllerAbstractFactory.php @@ -83,16 +83,16 @@ class LazyControllerAbstractFactory implements AbstractFactoryInterface * @var string[] */ protected $aliases = [ - ConsoleAdapterInterface::class => 'ConsoleAdapter', - FilterPluginManager::class => 'FilterManager', - HydratorPluginManager::class => 'HydratorManager', - InputFilterPluginManager::class => 'InputFilterManager', - LogFilterManager::class => 'LogFilterManager', - LogFormatterManager::class => 'LogFormatterManager', - LogProcessorManager::class => 'LogProcessorManager', - LogWriterManager::class => 'LogWriterManager', - SerializerAdapterManager::class => 'SerializerAdapterManager', - ValidatorPluginManager::class => 'ValidatorManager', + 'Zend\Console\Adapter\AdapterInterface' => 'ConsoleAdapter', + 'Zend\Filter\FilterPluginManager' => 'FilterManager', + 'Zend\Hydrator\HydratorPluginManager' => 'HydratorManager', + 'Zend\InputFilter\InputFilterPluginManager' => 'InputFilterManager', + 'Zend\Log\FilterPluginManager' => 'LogFilterManager', + 'Zend\Log\FormatterPluginManager' => 'LogFormatterManager', + 'Zend\Log\ProcessorPluginManager' => 'LogProcessorManager', + 'Zend\Log\WriterPluginManager' => 'LogWriterManager', + 'Zend\Serializer\AdapterPluginManager' => 'SerializerAdapterManager', + 'Zend\Validator\ValidatorPluginManager' => 'ValidatorManager', ]; /** @@ -104,7 +104,9 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o { $reflectionClass = new ReflectionClass($requestedName); - if (null === ($constructor = $reflectionClass->getConstructor())) { + $constructor = $constructor = $reflectionClass->getConstructor(); + + if (null === $constructor) { return new $requestedName(); } @@ -163,11 +165,13 @@ private function resolveParameter(ContainerInterface $container, $requestedName) return []; } - if (! $parameter->getClass()) { - return; + $parameterClass = $parameter->getClass(); + + if (! $parameterClass) { + return null; } - $type = $parameter->getClass()->getName(); + $type = $parameterClass->getName(); $type = isset($this->aliases[$type]) ? $this->aliases[$type] : $type; if (! $container->has($type)) { diff --git a/src/Controller/MiddlewareController.php b/src/Controller/MiddlewareController.php index aee5e269d..d5621a365 100644 --- a/src/Controller/MiddlewareController.php +++ b/src/Controller/MiddlewareController.php @@ -95,7 +95,7 @@ private function loadRequest() throw new RuntimeException(sprintf( 'Expected request to be a %s, %s given', Request::class, - get_class($request) + \is_object($request) ? \get_class($request) : \gettype($request) )); } diff --git a/src/Controller/Plugin/AcceptableViewModelSelector.php b/src/Controller/Plugin/AcceptableViewModelSelector.php index 7a7a5efe7..8463a4405 100644 --- a/src/Controller/Plugin/AcceptableViewModelSelector.php +++ b/src/Controller/Plugin/AcceptableViewModelSelector.php @@ -8,12 +8,16 @@ namespace Zend\Mvc\Controller\Plugin; use Zend\Http\Header\Accept\FieldValuePart\AbstractFieldValuePart; +use Zend\Http\Header\Accept\FieldValuePart\AcceptFieldValuePart; +use Zend\Http\Headers; use Zend\Http\Request; +use Zend\Mvc\Exception\UnexpectedValueException; use Zend\Mvc\InjectApplicationEventInterface; use Zend\Mvc\MvcEvent; use Zend\Mvc\Exception\DomainException; use Zend\Mvc\Exception\InvalidArgumentException; use Zend\View\Model\ModelInterface; +use Zend\View\Model\ViewModel; /** * Controller Plugin to assist in selecting an appropriate View Model type based on the @@ -29,20 +33,20 @@ class AcceptableViewModelSelector extends AbstractPlugin /** * - * @var \Zend\Mvc\MvcEvent + * @var null|\Zend\Mvc\MvcEvent */ protected $event; /** * - * @var \Zend\Http\Request + * @var null|\Zend\Http\Request */ protected $request; /** * Default array to match against. * - * @var Array + * @var array|null */ protected $defaultMatchAgainst; @@ -50,7 +54,7 @@ class AcceptableViewModelSelector extends AbstractPlugin * * @var string Default ViewModel */ - protected $defaultViewModelName = 'Zend\View\Model\ViewModel'; + protected $defaultViewModelName = ViewModel::class; /** * Detects an appropriate viewmodel for request. @@ -86,14 +90,20 @@ public function getViewModel( $name = $this->getViewModelName($matchAgainst, $returnDefault, $resultReference); if (! $name) { - return; + return null; } if (! class_exists($name)) { throw new InvalidArgumentException('The supplied View Model could not be found'); } - return new $name(); + $viewModel = new $name(); + + if (! $viewModel instanceof ModelInterface) { + throw InvalidArgumentException::unexpectedType(ModelInterface::class, $viewModel); + } + + return $viewModel; } /** @@ -102,7 +112,7 @@ public function getViewModel( * @param array $matchAgainst (optional) The Array to match against * @param bool $returnDefault (optional) If no match is available. Return default instead * @param AbstractFieldValuePart|null $resultReference (optional) The object that was matched. - * @return ModelInterface|null Returns null if $returnDefault = false and no match could be made + * @return string|null Returns null if $returnDefault = false and no match could be made */ public function getViewModelName( array $matchAgainst = null, @@ -124,21 +134,26 @@ public function getViewModelName( * Detects an appropriate viewmodel name for request. * * @param array $matchAgainst (optional) The Array to match against - * @return AbstractFieldValuePart|null The object that was matched + * @return AcceptFieldValuePart|null The object that was matched */ public function match(array $matchAgainst = null) { $request = $this->getRequest(); + /** @var Headers $headers */ $headers = $request->getHeaders(); - if ((! $matchAgainst && ! $this->defaultMatchAgainst) || ! $headers->has('accept')) { - return; + if (! $headers->has('accept')) { + return null; } if (! $matchAgainst) { $matchAgainst = $this->defaultMatchAgainst; } + if (! $matchAgainst) { + return null; + } + $matchAgainstString = ''; foreach ($matchAgainst as $modelName => $modelStrings) { foreach ((array) $modelStrings as $modelString) { @@ -146,13 +161,15 @@ public function match(array $matchAgainst = null) } } - /** @var $accept \Zend\Http\Header\Accept */ + /** @var \Zend\Http\Header\Accept $accept */ $accept = $headers->get('Accept'); - if (($res = $accept->match($matchAgainstString)) === false) { - return; + /** @var AcceptFieldValuePart|false $match */ + $match = $accept->match($matchAgainstString); + if ($match === false) { + return null; } - return $res; + return $match; } /** @@ -200,14 +217,14 @@ public function getDefaultMatchAgainst() /** * Inject the viewmodel name into the accept header string * - * @param string $modelAcceptString + * @param string|array $modelAcceptString * @param string $modelName * @return string */ protected function injectViewModelName($modelAcceptString, $modelName) { $modelName = str_replace('\\', '|', $modelName); - $modelAcceptString = (is_array($modelAcceptString)) + $modelAcceptString = is_array($modelAcceptString) ? $modelAcceptString[key($modelAcceptString)] : $modelAcceptString; return $modelAcceptString . '; ' . self::INJECT_VIEWMODEL_NAME . '="' . $modelName . '", '; @@ -220,7 +237,11 @@ protected function injectViewModelName($modelAcceptString, $modelName) */ protected function extractViewModelName(AbstractFieldValuePart $res) { - $modelName = $res->getMatchedAgainst()->params[self::INJECT_VIEWMODEL_NAME]; + $matchedAgainst = $res->getMatchedAgainst(); + if (null === $matchedAgainst) { + throw new UnexpectedValueException('Unable to find matchedAgainst value'); + } + $modelName = $matchedAgainst->params[self::INJECT_VIEWMODEL_NAME]; return str_replace('|', '\\', $modelName); } diff --git a/src/Controller/Plugin/Forward.php b/src/Controller/Plugin/Forward.php index 32f2d8273..c44beef73 100644 --- a/src/Controller/Plugin/Forward.php +++ b/src/Controller/Plugin/Forward.php @@ -7,13 +7,15 @@ namespace Zend\Mvc\Controller\Plugin; +use Zend\EventManager\EventInterface; use Zend\EventManager\SharedEventManagerInterface as SharedEvents; use Zend\Mvc\Controller\ControllerManager; use Zend\Mvc\Exception; use Zend\Mvc\InjectApplicationEventInterface; use Zend\Mvc\MvcEvent; use Zend\Router\RouteMatch; -use Zend\Stdlib\CallbackHandler; +use Zend\Stdlib\DispatchableInterface; +use Zend\Mvc\View\Http\InjectViewModelListener; class Forward extends AbstractPlugin { @@ -23,7 +25,7 @@ class Forward extends AbstractPlugin protected $controllers; /** - * @var MvcEvent + * @var null|MvcEvent */ protected $event; @@ -40,7 +42,7 @@ class Forward extends AbstractPlugin /** * @var array[]|null */ - protected $listenersToDetach = null; + protected $listenersToDetach; /** * @param ControllerManager $controllers @@ -82,9 +84,9 @@ public function getListenersToDetach() // from getting attached to the ViewModel twice when a calling action // returns the output generated by a forwarded action. $this->listenersToDetach = [[ - 'id' => 'Zend\Stdlib\DispatchableInterface', + 'id' => DispatchableInterface::class, 'event' => MvcEvent::EVENT_DISPATCH, - 'class' => 'Zend\Mvc\View\Http\InjectViewModelListener', + 'class' => InjectViewModelListener::class, ]]; } return $this->listenersToDetach; @@ -115,7 +117,7 @@ public function setListenersToDetach($listeners) */ public function dispatch($name, array $params = null) { - $event = clone($this->getEvent()); + $event = clone $this->getEvent(); $controller = $this->controllers->get($name); if ($controller instanceof InjectApplicationEventInterface) { @@ -125,7 +127,13 @@ public function dispatch($name, array $params = null) // Allow passing parameters to seed the RouteMatch with & copy matched route name if ($params !== null) { $routeMatch = new RouteMatch($params); - $routeMatch->setMatchedRouteName($event->getRouteMatch()->getMatchedRouteName()); + $eventRouteMatch = $event->getRouteMatch(); + + if (null === $eventRouteMatch) { + throw new Exception\RuntimeException('No route match on event'); + } + + $routeMatch->setMatchedRouteName($eventRouteMatch->getMatchedRouteName()); $event->setRouteMatch($routeMatch); } @@ -137,7 +145,19 @@ public function dispatch($name, array $params = null) $this->numNestedForwards++; // Detach listeners that may cause problems during dispatch: - $sharedEvents = $event->getApplication()->getEventManager()->getSharedManager(); + $application = $event->getApplication(); + + if (null === $application) { + throw new Exception\UnexpectedValueException('No Application in event'); + } + + $appEventManager = $application->getEventManager(); + $sharedEvents = $appEventManager->getSharedManager(); + + if (null === $sharedEvents) { + throw new Exception\RuntimeException('No SharedEventManager set on application EventManager'); + } + $listeners = $this->detachProblemListeners($sharedEvents); $return = $controller->dispatch($event->getRequest(), $event->getResponse()); @@ -174,8 +194,16 @@ protected function detachProblemListeners(SharedEvents $sharedEvents) // Loop through the class blacklist, detaching problem events and remembering their CallbackHandlers // for future reference: $results = []; + /** + * @var string $id + * @var array $eventArray + */ foreach ($formattedProblems as $id => $eventArray) { $results[$id] = []; + /** + * @var string $eventName + * @var string[] $classArray + */ foreach ($eventArray as $eventName => $classArray) { $results[$id][$eventName] = []; $events = $this->getSharedListenersById($id, $eventName, $sharedEvents); @@ -243,10 +271,11 @@ protected function getEvent() if (! $controller instanceof InjectApplicationEventInterface) { throw new Exception\DomainException(sprintf( 'Forward plugin requires a controller that implements InjectApplicationEventInterface; received %s', - (is_object($controller) ? get_class($controller) : var_export($controller, 1)) + (is_object($controller) ? get_class($controller) : var_export($controller, true)) )); } + /** @var EventInterface|null $event */ $event = $controller->getEvent(); if (! $event instanceof MvcEvent) { $params = []; @@ -281,8 +310,8 @@ private function getSharedListenersById($id, $event, SharedEvents $sharedEvents) * * Varies detachment based on zend-eventmanager version. * - * @param string|int $id - * @param callable|CallbackHandler $listener + * @param string $id + * @param callable $listener * @param SharedEvents $sharedEvents * @return void */ diff --git a/src/Controller/Plugin/Layout.php b/src/Controller/Plugin/Layout.php index 89e41588e..f190957ca 100644 --- a/src/Controller/Plugin/Layout.php +++ b/src/Controller/Plugin/Layout.php @@ -15,7 +15,7 @@ class Layout extends AbstractPlugin { /** - * @var MvcEvent + * @var null|MvcEvent */ protected $event; diff --git a/src/Controller/Plugin/Params.php b/src/Controller/Plugin/Params.php index eeed5456b..fd0c57572 100644 --- a/src/Controller/Plugin/Params.php +++ b/src/Controller/Plugin/Params.php @@ -7,11 +7,24 @@ namespace Zend\Mvc\Controller\Plugin; +use Zend\Mvc\Controller\AbstractController; use Zend\Mvc\Exception\RuntimeException; use Zend\Mvc\InjectApplicationEventInterface; +use Zend\Mvc\MvcEvent; class Params extends AbstractPlugin { + private function getPluginController() + { + $controller = $this->getController(); + + if (! $controller instanceof AbstractController) { + throw new RuntimeException('Controller is not an instance of ' . AbstractController::class); + } + + return $controller; + } + /** * Grabs a param from route match by default. * @@ -37,10 +50,10 @@ public function __invoke($param = null, $default = null) public function fromFiles($name = null, $default = null) { if ($name === null) { - return $this->getController()->getRequest()->getFiles($name, $default)->toArray(); + return $this->getPluginController()->getRequest()->getFiles($name, $default)->toArray(); } - return $this->getController()->getRequest()->getFiles($name, $default); + return $this->getPluginController()->getRequest()->getFiles($name, $default); } /** @@ -53,10 +66,10 @@ public function fromFiles($name = null, $default = null) public function fromHeader($header = null, $default = null) { if ($header === null) { - return $this->getController()->getRequest()->getHeaders($header, $default)->toArray(); + return $this->getPluginController()->getRequest()->getHeaders($header, $default)->toArray(); } - return $this->getController()->getRequest()->getHeaders($header, $default); + return $this->getPluginController()->getRequest()->getHeaders($header, $default); } /** @@ -69,10 +82,10 @@ public function fromHeader($header = null, $default = null) public function fromPost($param = null, $default = null) { if ($param === null) { - return $this->getController()->getRequest()->getPost($param, $default)->toArray(); + return $this->getPluginController()->getRequest()->getPost($param, $default)->toArray(); } - return $this->getController()->getRequest()->getPost($param, $default); + return $this->getPluginController()->getRequest()->getPost($param, $default); } /** @@ -85,10 +98,10 @@ public function fromPost($param = null, $default = null) public function fromQuery($param = null, $default = null) { if ($param === null) { - return $this->getController()->getRequest()->getQuery($param, $default)->toArray(); + return $this->getPluginController()->getRequest()->getQuery($param, $default)->toArray(); } - return $this->getController()->getRequest()->getQuery($param, $default); + return $this->getPluginController()->getRequest()->getQuery($param, $default); } /** @@ -101,7 +114,7 @@ public function fromQuery($param = null, $default = null) */ public function fromRoute($param = null, $default = null) { - $controller = $this->getController(); + $controller = $this->getPluginController(); if (! $controller instanceof InjectApplicationEventInterface) { throw new RuntimeException( @@ -109,10 +122,22 @@ public function fromRoute($param = null, $default = null) ); } + $event = $controller->getEvent(); + + if (! $event instanceof MvcEvent) { + throw new RuntimeException('Controller event is not an instance of ' . MvcEvent::class); + } + + $routeMatch = $event->getRouteMatch(); + + if (null === $routeMatch) { + throw new RuntimeException('Controller event has no RouteMatch'); + } + if ($param === null) { - return $controller->getEvent()->getRouteMatch()->getParams(); + return $routeMatch->getParams(); } - return $controller->getEvent()->getRouteMatch()->getParam($param, $default); + return $routeMatch->getParam($param, $default); } } diff --git a/src/Controller/Plugin/Redirect.php b/src/Controller/Plugin/Redirect.php index df9b650d4..71930dbad 100644 --- a/src/Controller/Plugin/Redirect.php +++ b/src/Controller/Plugin/Redirect.php @@ -25,7 +25,7 @@ class Redirect extends AbstractPlugin * * @param string $route RouteInterface name * @param array $params Parameters to use in url generation, if any - * @param array $options RouteInterface-specific options to use in url generation, if any + * @param array|bool $options RouteInterface-specific options to use in url generation, if any * @param bool $reuseMatchedParams Whether to reuse matched parameters * @return Response * @throws Exception\DomainException if composed controller does not implement InjectApplicationEventInterface, or @@ -40,6 +40,7 @@ public function toRoute($route = null, $params = [], $options = [], $reuseMatche ); } + /** @var Url $urlPlugin */ $urlPlugin = $controller->plugin('url'); if (is_scalar($options)) { diff --git a/src/Controller/Plugin/Url.php b/src/Controller/Plugin/Url.php index 7a050a175..36fb653a7 100644 --- a/src/Controller/Plugin/Url.php +++ b/src/Controller/Plugin/Url.php @@ -65,8 +65,11 @@ public function fromRoute($route = null, $params = [], $options = [], $reuseMatc ); } - if (3 == func_num_args() && is_bool($options)) { + if (3 === func_num_args() && is_bool($options)) { $reuseMatchedParams = $options; + } + + if (false === is_array($options)) { $options = []; } diff --git a/src/Controller/PluginManager.php b/src/Controller/PluginManager.php index 5a9295903..047d80e9a 100644 --- a/src/Controller/PluginManager.php +++ b/src/Controller/PluginManager.php @@ -7,6 +7,7 @@ namespace Zend\Mvc\Controller; +use Zend\Mvc\Controller\Plugin\PluginInterface; use Zend\ServiceManager\AbstractPluginManager; use Zend\ServiceManager\Exception\InvalidServiceException; use Zend\ServiceManager\Factory\InvokableFactory; @@ -137,7 +138,7 @@ public function injectController($plugin) } $controller = $this->getController(); - if (! $controller instanceof DispatchableInterface) { + if (! $controller instanceof DispatchableInterface || ! $plugin instanceof PluginInterface) { return; } diff --git a/src/DispatchListener.php b/src/DispatchListener.php index ed7c7fe68..518666df6 100644 --- a/src/DispatchListener.php +++ b/src/DispatchListener.php @@ -10,6 +10,7 @@ use ArrayObject; use Zend\EventManager\AbstractListenerAggregate; use Zend\EventManager\EventManagerInterface; +use Zend\Mvc\Exception\RuntimeException; use Zend\Router\RouteMatch; use Zend\ServiceManager\Exception\InvalidServiceException; use Zend\Stdlib\ArrayUtils; @@ -75,7 +76,7 @@ public function attach(EventManagerInterface $events, $priority = 1) public function onDispatch(MvcEvent $e) { if (null !== $e->getResult()) { - return; + return null; } $routeMatch = $e->getRouteMatch(); @@ -83,14 +84,16 @@ public function onDispatch(MvcEvent $e) ? $routeMatch->getParam('controller', 'not-found') : 'not-found'; $application = $e->getApplication(); - $events = $application->getEventManager(); $controllerManager = $this->controllerManager; + if (! $application instanceof Application) { + throw new RuntimeException('Application is not an instance of ' . Application::class); + } // Query abstract controllers, too! if (! $controllerManager->has($controllerName)) { $return = $this->marshalControllerNotFoundEvent( - $application::ERROR_CONTROLLER_NOT_FOUND, + Application::ERROR_CONTROLLER_NOT_FOUND, $controllerName, $e, $application @@ -102,7 +105,7 @@ public function onDispatch(MvcEvent $e) $controller = $controllerManager->get($controllerName); } catch (Exception\InvalidControllerException $exception) { $return = $this->marshalControllerNotFoundEvent( - $application::ERROR_CONTROLLER_INVALID, + Application::ERROR_CONTROLLER_INVALID, $controllerName, $e, $application, @@ -111,7 +114,7 @@ public function onDispatch(MvcEvent $e) return $this->complete($return, $e); } catch (InvalidServiceException $exception) { $return = $this->marshalControllerNotFoundEvent( - $application::ERROR_CONTROLLER_INVALID, + Application::ERROR_CONTROLLER_INVALID, $controllerName, $e, $application, @@ -133,6 +136,7 @@ public function onDispatch(MvcEvent $e) $request = $e->getRequest(); $response = $application->getResponse(); $caughtException = null; + $return = null; try { $return = $controller->dispatch($request, $response); @@ -163,6 +167,10 @@ public function onDispatch(MvcEvent $e) */ public function reportMonitorEvent(MvcEvent $e) { + if (! \function_exists('zend_monitor_custom_event_ex')) { + return; + } + $error = $e->getError(); $exception = $e->getParam('exception'); // @TODO clean up once PHP 7 requirement is enforced @@ -244,7 +252,7 @@ protected function marshalBadControllerEvent( $exception ) { $event->setName(MvcEvent::EVENT_DISPATCH_ERROR); - $event->setError($application::ERROR_EXCEPTION); + $event->setError(Application::ERROR_EXCEPTION); $event->setController($controllerName); $event->setParam('exception', $exception); diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index fd7c910cd..f9eef9f4e 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -9,4 +9,18 @@ class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface { + /** + * @param string $expected + * @param mixed $actual + * + * @return InvalidArgumentException + */ + public static function unexpectedType($expected, $actual) + { + return new static(sprintf( + 'Expected %s. %s given', + $expected, + \is_object($actual) ? \get_class($actual) : \gettype($actual) + )); + } } diff --git a/src/Exception/UnexpectedValueException.php b/src/Exception/UnexpectedValueException.php new file mode 100644 index 000000000..7e3dbe54e --- /dev/null +++ b/src/Exception/UnexpectedValueException.php @@ -0,0 +1,26 @@ +getResponse(); if (! $request instanceof HttpRequest || ! $response instanceof HttpResponse) { - return; + return null; } $method = $request->getMethod(); if (in_array($method, $this->getAllowedMethods())) { - return; + return null; } $response->setStatusCode(405); diff --git a/src/MiddlewareListener.php b/src/MiddlewareListener.php index 618325451..3ff5e4c59 100644 --- a/src/MiddlewareListener.php +++ b/src/MiddlewareListener.php @@ -11,15 +11,14 @@ use Interop\Http\ServerMiddleware\MiddlewareInterface; use Psr\Http\Message\ResponseInterface as PsrResponseInterface; use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\ServerRequestInterface as PsrServerRequestInterface; use Zend\EventManager\AbstractListenerAggregate; use Zend\EventManager\EventManagerInterface; +use Zend\Http\Response; use Zend\Mvc\Exception\InvalidMiddlewareException; -use Zend\Mvc\Exception\ReachedFinalHandlerException; use Zend\Mvc\Controller\MiddlewareController; +use Zend\Mvc\Exception\RuntimeException; +use Zend\Mvc\Exception\UnexpectedValueException; use Zend\Psr7Bridge\Psr7Response; -use Zend\Router\RouteMatch; -use Zend\Stratigility\Delegate\CallableDelegateDecorator; use Zend\Stratigility\MiddlewarePipe; class MiddlewareListener extends AbstractListenerAggregate @@ -27,7 +26,8 @@ class MiddlewareListener extends AbstractListenerAggregate /** * Attach listeners to an event manager * - * @param EventManagerInterface $events + * @param EventManagerInterface $events + * @param int $priority * @return void */ public function attach(EventManagerInterface $events, $priority = 1) @@ -44,20 +44,38 @@ public function attach(EventManagerInterface $events, $priority = 1) public function onDispatch(MvcEvent $event) { if (null !== $event->getResult()) { - return; + return null; } $routeMatch = $event->getRouteMatch(); + + if (null === $routeMatch) { + throw new RuntimeException('No RouteMatch in event'); + } + $middleware = $routeMatch->getParam('middleware', false); if (false === $middleware) { - return; + return null; } $request = $event->getRequest(); $application = $event->getApplication(); + + if (null === $request) { + throw new UnexpectedValueException('No Request in event'); + } + + if (! $application instanceof Application) { + throw UnexpectedValueException::unexpectedType(Application::class, $application); + } + $response = $application->getResponse(); $serviceManager = $application->getServiceManager(); + if (! $response instanceof Response) { + throw UnexpectedValueException::unexpectedType(Response::class, $response); + } + $psr7ResponsePrototype = Psr7Response::fromZend($response); try { @@ -68,7 +86,7 @@ public function onDispatch(MvcEvent $event) ); } catch (InvalidMiddlewareException $invalidMiddlewareException) { $return = $this->marshalInvalidMiddleware( - $application::ERROR_MIDDLEWARE_CANNOT_DISPATCH, + Application::ERROR_MIDDLEWARE_CANNOT_DISPATCH, $invalidMiddlewareException->toMiddlewareName(), $event, $application, @@ -79,6 +97,8 @@ public function onDispatch(MvcEvent $event) } $caughtException = null; + $return = null; + try { $return = (new MiddlewareController( $pipe, @@ -94,7 +114,7 @@ public function onDispatch(MvcEvent $event) if ($caughtException !== null) { $event->setName(MvcEvent::EVENT_DISPATCH_ERROR); - $event->setError($application::ERROR_EXCEPTION); + $event->setError(Application::ERROR_EXCEPTION); $event->setParam('exception', $caughtException); $events = $application->getEventManager(); diff --git a/src/ModuleRouteListener.php b/src/ModuleRouteListener.php index 02fc72be9..5848b4da0 100644 --- a/src/ModuleRouteListener.php +++ b/src/ModuleRouteListener.php @@ -36,7 +36,6 @@ public function attach(EventManagerInterface $events, $priority = 1) * the matched controller parameter. * * @param MvcEvent $e - * @return null */ public function onRoute(MvcEvent $e) { diff --git a/src/MvcEvent.php b/src/MvcEvent.php index f9918377c..3a9fb05ea 100644 --- a/src/MvcEvent.php +++ b/src/MvcEvent.php @@ -29,15 +29,18 @@ class MvcEvent extends Event const EVENT_ROUTE = 'route'; /**#@-*/ + /** + * @var null|ApplicationInterface + */ protected $application; /** - * @var Request + * @var null|Request */ protected $request; /** - * @var Response + * @var null|Response */ protected $response; @@ -47,7 +50,7 @@ class MvcEvent extends Event protected $result; /** - * @var RouteStackInterface + * @var null|RouteStackInterface */ protected $router; @@ -57,7 +60,7 @@ class MvcEvent extends Event protected $routeMatch; /** - * @var Model + * @var null|Model */ protected $viewModel; @@ -77,7 +80,7 @@ public function setApplication(ApplicationInterface $application) /** * Get application instance * - * @return ApplicationInterface + * @return null|ApplicationInterface */ public function getApplication() { @@ -87,7 +90,7 @@ public function getApplication() /** * Get router * - * @return RouteStackInterface + * @return null|RouteStackInterface */ public function getRouter() { @@ -133,7 +136,7 @@ public function setRouteMatch(RouteMatch $matches) /** * Get request * - * @return Request + * @return null|Request */ public function getRequest() { @@ -156,7 +159,7 @@ public function setRequest(Request $request) /** * Get response * - * @return Response + * @return null|Response */ public function getResponse() { @@ -191,7 +194,7 @@ public function setViewModel(Model $viewModel) /** * Get the view model * - * @return Model + * @return null|Model */ public function getViewModel() { @@ -259,7 +262,7 @@ public function getError() /** * Get the currently registered controller name * - * @return string + * @return null|string */ public function getController() { @@ -281,7 +284,7 @@ public function setController($name) /** * Get controller class * - * @return string + * @return null|string */ public function getControllerClass() { diff --git a/src/ResponseSender/AbstractResponseSender.php b/src/ResponseSender/AbstractResponseSender.php index ed719d5d0..44dd95bb1 100644 --- a/src/ResponseSender/AbstractResponseSender.php +++ b/src/ResponseSender/AbstractResponseSender.php @@ -7,7 +7,12 @@ namespace Zend\Mvc\ResponseSender; +use Zend\Http\Header\HeaderInterface; use Zend\Http\Header\MultipleHeaderInterface; +use Zend\Http\Headers; +use Zend\Http\Response; +use Zend\Mvc\Exception\RuntimeException; +use Zend\Mvc\Exception\UnexpectedValueException; abstract class AbstractResponseSender implements ResponseSenderInterface { @@ -25,11 +30,18 @@ public function sendHeaders(SendResponseEvent $event) $response = $event->getResponse(); - foreach ($response->getHeaders() as $header) { + if (! $response instanceof Response) { + throw UnexpectedValueException::unexpectedType(Response::class, $response); + } + + /** @var Headers|HeaderInterface[] $headers */ + $headers = $response->getHeaders(); + foreach ($headers as $header) { if ($header instanceof MultipleHeaderInterface) { header($header->toString(), false); continue; } + header($header->toString()); } diff --git a/src/ResponseSender/HttpResponseSender.php b/src/ResponseSender/HttpResponseSender.php index 1131cab3f..3257182f1 100644 --- a/src/ResponseSender/HttpResponseSender.php +++ b/src/ResponseSender/HttpResponseSender.php @@ -41,8 +41,8 @@ public function __invoke(SendResponseEvent $event) return $this; } - $this->sendHeaders($event) - ->sendContent($event); + $this->sendHeaders($event); + $this->sendContent($event); $event->stopPropagation(true); return $this; } diff --git a/src/ResponseSender/PhpEnvironmentResponseSender.php b/src/ResponseSender/PhpEnvironmentResponseSender.php index 5309e11f0..77ff0460f 100644 --- a/src/ResponseSender/PhpEnvironmentResponseSender.php +++ b/src/ResponseSender/PhpEnvironmentResponseSender.php @@ -24,8 +24,8 @@ public function __invoke(SendResponseEvent $event) return $this; } - $this->sendHeaders($event) - ->sendContent($event); + $this->sendHeaders($event); + $this->sendContent($event); $event->stopPropagation(true); return $this; } diff --git a/src/ResponseSender/SimpleStreamResponseSender.php b/src/ResponseSender/SimpleStreamResponseSender.php index 3d1be8f75..f3f9a0195 100644 --- a/src/ResponseSender/SimpleStreamResponseSender.php +++ b/src/ResponseSender/SimpleStreamResponseSender.php @@ -8,6 +8,8 @@ namespace Zend\Mvc\ResponseSender; use Zend\Http\Response\Stream; +use Zend\Mvc\Exception\RuntimeException; +use Zend\Mvc\Exception\UnexpectedValueException; class SimpleStreamResponseSender extends AbstractResponseSender { @@ -22,10 +24,18 @@ public function sendStream(SendResponseEvent $event) if ($event->contentSent()) { return $this; } + $response = $event->getResponse(); + + if (! $response instanceof Stream) { + throw UnexpectedValueException::unexpectedType(Stream::class, $response); + } + $stream = $response->getStream(); fpassthru($stream); $event->setContentSent(); + + return $this; } /** diff --git a/src/RouteListener.php b/src/RouteListener.php index 4fd1fc37f..3c32782fe 100644 --- a/src/RouteListener.php +++ b/src/RouteListener.php @@ -9,6 +9,7 @@ use Zend\EventManager\AbstractListenerAggregate; use Zend\EventManager\EventManagerInterface; +use Zend\Mvc\Exception\UnexpectedValueException; use Zend\Router\RouteMatch; class RouteListener extends AbstractListenerAggregate @@ -34,12 +35,21 @@ public function attach(EventManagerInterface $events, $priority = 1) * Seeds the event with the route match on completion. * * @param MvcEvent $event - * @return null|RouteMatch + * @return null|RouteMatch|array|object */ public function onRoute(MvcEvent $event) { $request = $event->getRequest(); $router = $event->getRouter(); + + if (null === $request) { + throw new UnexpectedValueException('No Request in event'); + } + + if (null === $router) { + throw new UnexpectedValueException('No Router in event'); + } + $routeMatch = $router->match($request); if ($routeMatch instanceof RouteMatch) { @@ -50,6 +60,7 @@ public function onRoute(MvcEvent $event) $event->setName(MvcEvent::EVENT_DISPATCH_ERROR); $event->setError(Application::ERROR_ROUTER_NO_MATCH); + /** @var Application $target */ $target = $event->getTarget(); $results = $target->getEventManager()->triggerEvent($event); if (! empty($results)) { diff --git a/src/SendResponseListener.php b/src/SendResponseListener.php index 1b939ef6e..373951d95 100644 --- a/src/SendResponseListener.php +++ b/src/SendResponseListener.php @@ -109,7 +109,7 @@ public function getEvent() * Set the send response event * * @param SendResponseEvent $e - * @return SendResponseEvent + * @return SendResponseListener */ public function setEvent(SendResponseEvent $e) { @@ -126,8 +126,6 @@ public function setEvent(SendResponseEvent $e) * You can attach your response sender before or after every default response sender implementation. * All default response sender implementation have negative priority. * You are able to attach listeners without giving a priority and your response sender would be first to try. - * - * @return SendResponseListener */ protected function attachDefaultListeners() { diff --git a/src/Service/ApplicationFactory.php b/src/Service/ApplicationFactory.php index 2871cc334..8fce9851d 100644 --- a/src/Service/ApplicationFactory.php +++ b/src/Service/ApplicationFactory.php @@ -9,7 +9,9 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\Application; +use Zend\Mvc\Exception\InvalidArgumentException; use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\ServiceManager; class ApplicationFactory implements FactoryInterface { @@ -26,6 +28,10 @@ class ApplicationFactory implements FactoryInterface */ public function __invoke(ContainerInterface $container, $name, array $options = null) { + if (! $container instanceof ServiceManager) { + throw InvalidArgumentException::unexpectedType(ServiceManager::class, $container); + } + return new Application( $container, $container->get('EventManager'), diff --git a/src/Service/ControllerManagerFactory.php b/src/Service/ControllerManagerFactory.php index a1dd50812..59330d9b2 100644 --- a/src/Service/ControllerManagerFactory.php +++ b/src/Service/ControllerManagerFactory.php @@ -24,7 +24,7 @@ class ControllerManagerFactory implements FactoryInterface * if the controller implements a setPluginManager() method. * * @param ContainerInterface $container - * @param string $Name + * @param string $name * @param null|array $options * @return ControllerManager */ diff --git a/src/Service/HttpDefaultRenderingStrategyFactory.php b/src/Service/HttpDefaultRenderingStrategyFactory.php index 21a47daae..d580202ab 100644 --- a/src/Service/HttpDefaultRenderingStrategyFactory.php +++ b/src/Service/HttpDefaultRenderingStrategyFactory.php @@ -7,6 +7,7 @@ namespace Zend\Mvc\Service; +use ArrayAccess; use Interop\Container\ContainerInterface; use Zend\Mvc\View\Http\DefaultRenderingStrategy; use Zend\ServiceManager\Factory\FactoryInterface; @@ -38,9 +39,9 @@ public function __invoke(ContainerInterface $container, $name, array $options = * Uses layout template from configuration; if none available, defaults to "layout/layout". * * @param DefaultRenderingStrategy $strategy - * @param array $config + * @param array|ArrayAccess $config */ - private function injectLayoutTemplate(DefaultRenderingStrategy $strategy, array $config) + private function injectLayoutTemplate(DefaultRenderingStrategy $strategy, $config) { $layout = isset($config['layout']) ? $config['layout'] : 'layout/layout'; $strategy->setLayoutTemplate($layout); diff --git a/src/Service/HttpExceptionStrategyFactory.php b/src/Service/HttpExceptionStrategyFactory.php index 6798f5a0a..5dbaa53a2 100644 --- a/src/Service/HttpExceptionStrategyFactory.php +++ b/src/Service/HttpExceptionStrategyFactory.php @@ -7,6 +7,7 @@ namespace Zend\Mvc\Service; +use ArrayAccess; use Interop\Container\ContainerInterface; use Zend\Mvc\View\Http\ExceptionStrategy; use Zend\ServiceManager\Factory\FactoryInterface; @@ -36,9 +37,9 @@ public function __invoke(ContainerInterface $container, $name, array $options = * Inject strategy with configured display_exceptions flag. * * @param ExceptionStrategy $strategy - * @param array $config + * @param array|ArrayAccess $config */ - private function injectDisplayExceptions(ExceptionStrategy $strategy, array $config) + private function injectDisplayExceptions(ExceptionStrategy $strategy, $config) { $flag = isset($config['display_exceptions']) ? $config['display_exceptions'] : false; $strategy->setDisplayExceptions($flag); @@ -48,9 +49,9 @@ private function injectDisplayExceptions(ExceptionStrategy $strategy, array $con * Inject strategy with configured exception_template * * @param ExceptionStrategy $strategy - * @param array $config + * @param array|ArrayAccess $config */ - private function injectExceptionTemplate(ExceptionStrategy $strategy, array $config) + private function injectExceptionTemplate(ExceptionStrategy $strategy, $config) { $template = isset($config['exception_template']) ? $config['exception_template'] : 'error'; $strategy->setExceptionTemplate($template); diff --git a/src/Service/HttpRouteNotFoundStrategyFactory.php b/src/Service/HttpRouteNotFoundStrategyFactory.php index a426d1aea..6a75da5b6 100644 --- a/src/Service/HttpRouteNotFoundStrategyFactory.php +++ b/src/Service/HttpRouteNotFoundStrategyFactory.php @@ -7,6 +7,7 @@ namespace Zend\Mvc\Service; +use ArrayAccess; use Interop\Container\ContainerInterface; use Zend\Mvc\View\Http\RouteNotFoundStrategy; use Zend\ServiceManager\Factory\FactoryInterface; @@ -37,9 +38,9 @@ public function __invoke(ContainerInterface $container, $name, array $options = * Inject strategy with configured display_exceptions flag. * * @param RouteNotFoundStrategy $strategy - * @param array $config + * @param array|ArrayAccess $config */ - private function injectDisplayExceptions(RouteNotFoundStrategy $strategy, array $config) + private function injectDisplayExceptions(RouteNotFoundStrategy $strategy, $config) { $flag = isset($config['display_exceptions']) ? $config['display_exceptions'] : false; $strategy->setDisplayExceptions($flag); @@ -49,9 +50,9 @@ private function injectDisplayExceptions(RouteNotFoundStrategy $strategy, array * Inject strategy with configured display_not_found_reason flag. * * @param RouteNotFoundStrategy $strategy - * @param array $config + * @param array|ArrayAccess $config */ - private function injectDisplayNotFoundReason(RouteNotFoundStrategy $strategy, array $config) + private function injectDisplayNotFoundReason(RouteNotFoundStrategy $strategy, $config) { $flag = isset($config['display_not_found_reason']) ? $config['display_not_found_reason'] : false; $strategy->setDisplayNotFoundReason($flag); @@ -61,9 +62,9 @@ private function injectDisplayNotFoundReason(RouteNotFoundStrategy $strategy, ar * Inject strategy with configured not_found_template. * * @param RouteNotFoundStrategy $strategy - * @param array $config + * @param array|ArrayAccess $config */ - private function injectNotFoundTemplate(RouteNotFoundStrategy $strategy, array $config) + private function injectNotFoundTemplate(RouteNotFoundStrategy $strategy, $config) { $template = isset($config['not_found_template']) ? $config['not_found_template'] : '404'; $strategy->setNotFoundTemplate($template); diff --git a/src/Service/HttpViewManagerConfigTrait.php b/src/Service/HttpViewManagerConfigTrait.php index 6c6efa62d..3cc2fa58a 100644 --- a/src/Service/HttpViewManagerConfigTrait.php +++ b/src/Service/HttpViewManagerConfigTrait.php @@ -16,17 +16,17 @@ trait HttpViewManagerConfigTrait * Retrieve view_manager configuration, if present. * * @param ContainerInterface $container - * @return array + * @return array|ArrayAccess */ private function getConfig(ContainerInterface $container) { $config = $container->has('config') ? $container->get('config') : []; - if (isset($config['view_manager']) - && (is_array($config['view_manager']) - || $config['view_manager'] instanceof ArrayAccess - ) - ) { + if (! isset($config['view_manager'])) { + return []; + } + + if (\is_array($config['view_manager']) || $config['view_manager'] instanceof ArrayAccess) { return $config['view_manager']; } diff --git a/src/Service/PaginatorPluginManagerFactory.php b/src/Service/PaginatorPluginManagerFactory.php index eac7de893..7c469c01c 100644 --- a/src/Service/PaginatorPluginManagerFactory.php +++ b/src/Service/PaginatorPluginManagerFactory.php @@ -7,9 +7,7 @@ namespace Zend\Mvc\Service; -use Zend\Paginator\AdapterPluginManager as PaginatorPluginManager; - class PaginatorPluginManagerFactory extends AbstractPluginManagerFactory { - const PLUGIN_MANAGER_CLASS = PaginatorPluginManager::class; + const PLUGIN_MANAGER_CLASS = 'Zend\Paginator\AdapterPluginManager'; } diff --git a/src/Service/ServiceListenerFactory.php b/src/Service/ServiceListenerFactory.php index 4416fb6e8..67b9e8a7a 100644 --- a/src/Service/ServiceListenerFactory.php +++ b/src/Service/ServiceListenerFactory.php @@ -14,7 +14,8 @@ use Zend\ServiceManager\Exception\ServiceNotCreatedException; use Zend\ServiceManager\Factory\FactoryInterface; use Zend\ServiceManager\Factory\InvokableFactory; -use Zend\ServiceManager\ServiceLocatorInterface; +use Zend\ServiceManager\ServiceManager; +use Zend\Mvc\Exception; class ServiceListenerFactory implements FactoryInterface { @@ -112,7 +113,9 @@ class ServiceListenerFactory implements FactoryInterface * - interface: the name of the interface that modules can implement as string * - method: the name of the method that modules have to implement as string * - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface $container + * @param string $requestedName + * @param array|null $options * @return ServiceListenerInterface * @throws ServiceNotCreatedException for invalid ServiceListener service * @throws ServiceNotCreatedException For invalid configurations. @@ -121,9 +124,16 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o { $configuration = $container->get('ApplicationConfig'); - $serviceListener = $container->has('ServiceListenerInterface') - ? $container->get('ServiceListenerInterface') - : new ServiceListener($container); + if ($container->has('ServiceListenerInterface')) { + $serviceListener = $container->get('ServiceListenerInterface'); + } elseif ($container instanceof ServiceManager) { + $serviceListener = new ServiceListener($container); + } else { + throw new Exception\InvalidArgumentException( + 'No service listener found in container.' + . 'Unable to create a new one because $container should be an instance of ' . ServiceManager::class + ); + } if (! $serviceListener instanceof ServiceListenerInterface) { throw new ServiceNotCreatedException( diff --git a/src/Service/ViewHelperManagerFactory.php b/src/Service/ViewHelperManagerFactory.php index 371885b19..5c9aa512a 100644 --- a/src/Service/ViewHelperManagerFactory.php +++ b/src/Service/ViewHelperManagerFactory.php @@ -31,13 +31,16 @@ class ViewHelperManagerFactory extends AbstractPluginManagerFactory * Create and return the view helper manager * * @param ContainerInterface $container - * @return HelperPluginManager + * @param string $requestedName + * @param array|null $options * @throws ServiceNotCreatedException + * @return HelperPluginManager */ public function __invoke(ContainerInterface $container, $requestedName, array $options = null) { $options = $options ?: []; $options['factories'] = isset($options['factories']) ? $options['factories'] : []; + /** @var HelperPluginManager $plugins */ $plugins = parent::__invoke($container, $requestedName, $options); // Override plugin factories diff --git a/src/View/Http/DefaultRenderingStrategy.php b/src/View/Http/DefaultRenderingStrategy.php index 5031966c8..cfd9922a0 100644 --- a/src/View/Http/DefaultRenderingStrategy.php +++ b/src/View/Http/DefaultRenderingStrategy.php @@ -10,6 +10,7 @@ use Zend\EventManager\AbstractListenerAggregate; use Zend\EventManager\EventManagerInterface; use Zend\Mvc\Application; +use Zend\Mvc\Exception\UnexpectedValueException; use Zend\Mvc\MvcEvent; use Zend\Stdlib\ResponseInterface as Response; use Zend\View\Model\ModelInterface as ViewModel; @@ -33,7 +34,6 @@ class DefaultRenderingStrategy extends AbstractListenerAggregate * Set view * * @param View $view - * @return DefaultRenderingStrategy */ public function __construct(View $view) { @@ -90,7 +90,15 @@ public function render(MvcEvent $e) $response = $e->getResponse(); $viewModel = $e->getViewModel(); if (! $viewModel instanceof ViewModel) { - return; + return null; + } + + if (null === $request) { + throw new UnexpectedValueException('No Request in event'); + } + + if (null === $response) { + throw new UnexpectedValueException('No Response in event'); } $view = $this->view; @@ -107,20 +115,25 @@ public function render(MvcEvent $e) $caughtException = $ex; } - if ($caughtException !== null) { - if ($e->getName() === MvcEvent::EVENT_RENDER_ERROR) { - throw $caughtException; - } + if (null === $caughtException) { + return $response; + } + + if ($e->getName() === MvcEvent::EVENT_RENDER_ERROR) { + throw $caughtException; + } - $application = $e->getApplication(); - $events = $application->getEventManager(); + $application = $e->getApplication(); - $e->setError(Application::ERROR_EXCEPTION); - $e->setParam('exception', $caughtException); - $e->setName(MvcEvent::EVENT_RENDER_ERROR); - $events->triggerEvent($e); + if (null === $application) { + throw new UnexpectedValueException('No Application in event'); } - return $response; + $events = $application->getEventManager(); + + $e->setError(Application::ERROR_EXCEPTION); + $e->setParam('exception', $caughtException); + $e->setName(MvcEvent::EVENT_RENDER_ERROR); + $events->triggerEvent($e); } } diff --git a/src/View/Http/ExceptionStrategy.php b/src/View/Http/ExceptionStrategy.php index 440358210..d2f55227d 100644 --- a/src/View/Http/ExceptionStrategy.php +++ b/src/View/Http/ExceptionStrategy.php @@ -11,6 +11,7 @@ use Zend\EventManager\EventManagerInterface; use Zend\Http\Response as HttpResponse; use Zend\Mvc\Application; +use Zend\Mvc\Exception\UnexpectedValueException; use Zend\Mvc\MvcEvent; use Zend\Stdlib\ResponseInterface as Response; use Zend\View\Model\ViewModel; @@ -116,27 +117,38 @@ public function prepareExceptionViewModel(MvcEvent $e) case Application::ERROR_EXCEPTION: default: - $model = new ViewModel([ - 'message' => 'An error occurred during execution; please try again later.', - 'exception' => $e->getParam('exception'), - 'display_exceptions' => $this->displayExceptions(), - ]); - $model->setTemplate($this->getExceptionTemplate()); - $e->setResult($model); - - $response = $e->getResponse(); - if (! $response) { - $response = new HttpResponse(); - $response->setStatusCode(500); - $e->setResponse($response); - } else { - $statusCode = $response->getStatusCode(); - if ($statusCode === 200) { - $response->setStatusCode(500); - } - } - - break; + $this->handleExceptionViewModel($e); } } + + private function handleExceptionViewModel(MvcEvent $e) + { + $model = new ViewModel([ + 'message' => 'An error occurred during execution; please try again later.', + 'exception' => $e->getParam('exception'), + 'display_exceptions' => $this->displayExceptions(), + ]); + $model->setTemplate($this->getExceptionTemplate()); + $e->setResult($model); + + $response = $e->getResponse(); + if (! $response) { + $response = new HttpResponse(); + $response->setStatusCode(500); + $e->setResponse($response); + + return; + } + + if ($response instanceof HttpResponse) { + $statusCode = $response->getStatusCode(); + if ($statusCode === 200) { + $response->setStatusCode(500); + } + + return; + } + + throw UnexpectedValueException::unexpectedType(HttpResponse::class, $response); + } } diff --git a/src/View/Http/InjectRoutematchParamsListener.php b/src/View/Http/InjectRoutematchParamsListener.php index adcaf29b9..57be8f141 100644 --- a/src/View/Http/InjectRoutematchParamsListener.php +++ b/src/View/Http/InjectRoutematchParamsListener.php @@ -11,6 +11,7 @@ use Zend\EventManager\EventManagerInterface; use Zend\Http\Request as HttpRequest; use Zend\Mvc\MvcEvent; +use Zend\Mvc\Exception; class InjectRoutematchParamsListener extends AbstractListenerAggregate { @@ -37,7 +38,13 @@ public function attach(EventManagerInterface $events, $priority = 1) */ public function injectParams(MvcEvent $e) { - $routeMatchParams = $e->getRouteMatch()->getParams(); + $routeMatch = $e->getRouteMatch(); + + if (null === $routeMatch) { + throw new Exception\RuntimeException('No RouteMatch in event'); + } + + $routeMatchParams = $routeMatch->getParams(); $request = $e->getRequest(); if (! $request instanceof HttpRequest) { @@ -45,7 +52,7 @@ public function injectParams(MvcEvent $e) return; } - $params = $request->get(); + $params = $request->getQuery(); if ($this->overwrite) { // Overwrite existing parameters, or create new ones if not present. diff --git a/src/View/Http/InjectTemplateListener.php b/src/View/Http/InjectTemplateListener.php index 3b110a787..7cb66283e 100644 --- a/src/View/Http/InjectTemplateListener.php +++ b/src/View/Http/InjectTemplateListener.php @@ -9,6 +9,7 @@ use Zend\EventManager\AbstractListenerAggregate; use Zend\EventManager\EventManagerInterface as Events; +use Zend\Mvc\Exception\RuntimeException; use Zend\Mvc\MvcEvent; use Zend\Stdlib\StringUtils; use Zend\View\Model\ModelInterface as ViewModel; @@ -59,6 +60,11 @@ public function injectTemplate(MvcEvent $e) } $routeMatch = $e->getRouteMatch(); + + if (null === $routeMatch) { + throw new RuntimeException('MvcEvent does not have a RouteMatch'); + } + if ($preferRouteMatchController = $routeMatch->getParam('prefer_route_match_controller', false)) { $this->setPreferRouteMatchController($preferRouteMatchController); } @@ -99,7 +105,7 @@ public function setControllerMap(array $map) * Maps controller to template if controller namespace is whitelisted or mapped * * @param string $controller controller FQCN - * @return string|false template name or false if controller was not matched + * @return string template name or false if controller was not matched */ public function mapController($controller) { @@ -117,7 +123,8 @@ public function mapController($controller) // Map namespace to $replacement if its value is string if (is_string($replacement)) { $mapped = rtrim($replacement, '/') . '/'; - $controller = substr($controller, strlen($namespace) + 1) ?: ''; + $name = substr($controller, strlen($namespace) + 1); + $controller = \is_string($name) ? $name : ''; break; } } @@ -173,7 +180,7 @@ protected function deriveControllerClass($controller) } if ((10 < strlen($controller)) - && ('Controller' == substr($controller, -10)) + && ('Controller' === substr($controller, -10)) ) { $controller = substr($controller, 0, -10); } diff --git a/src/View/Http/InjectViewModelListener.php b/src/View/Http/InjectViewModelListener.php index 6a61a9b32..27fe4c711 100644 --- a/src/View/Http/InjectViewModelListener.php +++ b/src/View/Http/InjectViewModelListener.php @@ -9,6 +9,7 @@ use Zend\EventManager\AbstractListenerAggregate; use Zend\EventManager\EventManagerInterface as Events; +use Zend\Mvc\Exception\UnexpectedValueException; use Zend\Mvc\MvcEvent; use Zend\View\Model\ClearableModelInterface; use Zend\View\Model\ModelInterface as ViewModel; @@ -49,6 +50,10 @@ public function injectViewModel(MvcEvent $e) return; } + if (null === $model) { + throw new UnexpectedValueException('Unable to get ViewModel from MvcEvent'); + } + if ($e->getError() && $model instanceof ClearableModelInterface) { $model->clearChildren(); } diff --git a/src/View/Http/RouteNotFoundStrategy.php b/src/View/Http/RouteNotFoundStrategy.php index 12d397f92..65fcee1fe 100644 --- a/src/View/Http/RouteNotFoundStrategy.php +++ b/src/View/Http/RouteNotFoundStrategy.php @@ -11,6 +11,8 @@ use Zend\EventManager\EventManagerInterface; use Zend\Http\Response as HttpResponse; use Zend\Mvc\Application; +use Zend\Mvc\Exception\RuntimeException; +use Zend\Mvc\Exception\UnexpectedValueException; use Zend\Mvc\MvcEvent; use Zend\Stdlib\ResponseInterface as Response; use Zend\View\Model\ViewModel; @@ -147,6 +149,11 @@ public function detectNotFoundError(MvcEvent $e) $response = new HttpResponse(); $e->setResponse($response); } + + if (! $response instanceof HttpResponse) { + throw UnexpectedValueException::unexpectedType(HttpResponse::class, $response); + } + $response->setStatusCode(404); break; default: @@ -169,6 +176,11 @@ public function prepareNotFoundViewModel(MvcEvent $e) } $response = $e->getResponse(); + + if (! $response instanceof HttpResponse) { + throw UnexpectedValueException::unexpectedType(HttpResponse::class, $response); + } + if ($response->getStatusCode() != 404) { // Only handle 404 responses return; diff --git a/src/View/Http/ViewManager.php b/src/View/Http/ViewManager.php index 67802c5ac..67ec63270 100644 --- a/src/View/Http/ViewManager.php +++ b/src/View/Http/ViewManager.php @@ -13,8 +13,11 @@ use Zend\EventManager\EventManagerInterface; use Zend\EventManager\ListenerAggregateInterface; use Zend\Mvc\MvcEvent; -use Zend\ServiceManager\ServiceManager; +use Zend\ServiceManager\ServiceLocatorInterface; +use Zend\View\Helper\ViewModel; use Zend\View\View; +use Zend\Mvc\Exception; +use Zend\Stdlib\DispatchableInterface; /** * Prepares the view layer @@ -41,7 +44,7 @@ class ViewManager extends AbstractListenerAggregate { /** - * @var object application configuration service + * @var array|ArrayAccess application configuration service */ protected $config; @@ -51,7 +54,7 @@ class ViewManager extends AbstractListenerAggregate protected $event; /** - * @var ServiceManager + * @var ServiceLocatorInterface */ protected $services; @@ -79,12 +82,17 @@ public function attach(EventManagerInterface $events, $priority = 1) /** * Prepares the view layer * - * @param $event + * @param MvcEvent $event * @return void */ public function onBootstrap($event) { $application = $event->getApplication(); + + if (null === $application) { + throw new Exception\UnexpectedValueException('Unable to get Application from MvcEvent'); + } + $services = $application->getServiceManager(); $config = $services->get('config'); $events = $application->getEventManager(); @@ -98,13 +106,17 @@ public function onBootstrap($event) $this->services = $services; $this->event = $event; + /** @var RouteNotFoundStrategy $routeNotFoundStrategy */ $routeNotFoundStrategy = $services->get('HttpRouteNotFoundStrategy'); + /** @var ExceptionStrategy $exceptionStrategy */ $exceptionStrategy = $services->get('HttpExceptionStrategy'); + /** @var DefaultRenderingStrategy $mvcRenderingStrategy */ $mvcRenderingStrategy = $services->get('HttpDefaultRenderingStrategy'); $this->injectViewModelIntoPlugin(); - $injectTemplateListener = $services->get('Zend\Mvc\View\Http\InjectTemplateListener'); + /** @var InjectTemplateListener $injectTemplateListener */ + $injectTemplateListener = $services->get(InjectTemplateListener::class); $createViewModelListener = new CreateViewModelListener(); $injectViewModelListener = new InjectViewModelListener(); @@ -117,32 +129,36 @@ public function onBootstrap($event) $events->attach(MvcEvent::EVENT_RENDER_ERROR, [$injectViewModelListener, 'injectViewModel'], -100); $mvcRenderingStrategy->attach($events); + if (null === $sharedEvents) { + throw new Exception\RuntimeException('No SharedEventManager in application EventManager'); + } + $sharedEvents->attach( - 'Zend\Stdlib\DispatchableInterface', + DispatchableInterface::class, MvcEvent::EVENT_DISPATCH, [$createViewModelListener, 'createViewModelFromArray'], -80 ); $sharedEvents->attach( - 'Zend\Stdlib\DispatchableInterface', + DispatchableInterface::class, MvcEvent::EVENT_DISPATCH, [$routeNotFoundStrategy, 'prepareNotFoundViewModel'], -90 ); $sharedEvents->attach( - 'Zend\Stdlib\DispatchableInterface', + DispatchableInterface::class, MvcEvent::EVENT_DISPATCH, [$createViewModelListener, 'createViewModelFromNull'], -80 ); $sharedEvents->attach( - 'Zend\Stdlib\DispatchableInterface', + DispatchableInterface::class, MvcEvent::EVENT_DISPATCH, [$injectTemplateListener, 'injectTemplate'], -90 ); $sharedEvents->attach( - 'Zend\Stdlib\DispatchableInterface', + DispatchableInterface::class, MvcEvent::EVENT_DISPATCH, [$injectViewModelListener, 'injectViewModel'], -100 @@ -176,10 +192,17 @@ public function getViewModel() } $this->viewModel = $model = $this->event->getViewModel(); - $layoutTemplate = $this->services->get('HttpDefaultRenderingStrategy')->getLayoutTemplate(); + + if (null === $model) { + throw new Exception\UnexpectedValueException('No ViewModel in event'); + } + + /** @var DefaultRenderingStrategy $renderingStrategy */ + $renderingStrategy = $this->services->get('HttpDefaultRenderingStrategy'); + $layoutTemplate = $renderingStrategy->getLayoutTemplate(); $model->setTemplate($layoutTemplate); - return $this->viewModel; + return $model; } /** @@ -265,6 +288,7 @@ private function injectViewModelIntoPlugin() { $model = $this->getViewModel(); $plugins = $this->services->get('ViewHelperManager'); + /** @var ViewModel $plugin */ $plugin = $plugins->get('viewmodel'); $plugin->setRoot($model); } diff --git a/test/Exception/InvalidArgumentExceptionTest.php b/test/Exception/InvalidArgumentExceptionTest.php new file mode 100644 index 000000000..185ddef08 --- /dev/null +++ b/test/Exception/InvalidArgumentExceptionTest.php @@ -0,0 +1,25 @@ +assertSame('Expected foo. ArrayObject given', $exception->getMessage()); + } + + public function testUnexpectedTypeWithScalarType() + { + $exception = InvalidArgumentException::unexpectedType('foo', 5); + + $this->assertSame('Expected foo. integer given', $exception->getMessage()); + } +} diff --git a/test/Exception/UnexpectedValueExceptionTest.php b/test/Exception/UnexpectedValueExceptionTest.php new file mode 100644 index 000000000..e5aa4ceb3 --- /dev/null +++ b/test/Exception/UnexpectedValueExceptionTest.php @@ -0,0 +1,25 @@ +assertSame('Expected foo. ArrayObject given', $exception->getMessage()); + } + + public function testUnexpectedTypeWithScalarType() + { + $exception = UnexpectedValueException::unexpectedType('foo', 5); + + $this->assertSame('Expected foo. integer given', $exception->getMessage()); + } +} diff --git a/test/Service/HttpDefaultRenderingStrategyFactoryTest.php b/test/Service/HttpDefaultRenderingStrategyFactoryTest.php new file mode 100644 index 000000000..08720d162 --- /dev/null +++ b/test/Service/HttpDefaultRenderingStrategyFactoryTest.php @@ -0,0 +1,87 @@ +serviceLocator = $this->prophesize(ContainerInterface::class); + } + + public function testInvoke() + { + $factory = new HttpDefaultRenderingStrategyFactory(); + + $view = $this->prophesize(View::class); + $this->serviceLocator->get(View::class) + ->willReturn($view->reveal()); + + $this->serviceLocator->has('config')->willReturn(true); + $this->serviceLocator->get('config') + ->willReturn([ + 'view_manager' => [ + 'layout' => 'foo', + ], + ]); + + $instance = $factory($this->serviceLocator->reveal(), 'foo'); + + $this->assertInstanceOf(DefaultRenderingStrategy::class, $instance); + $this->assertSame('foo', $instance->getLayoutTemplate()); + } + + public function testInvokeWithArrayAccessConfig() + { + $factory = new HttpDefaultRenderingStrategyFactory(); + + $view = $this->prophesize(View::class); + $this->serviceLocator->get(View::class) + ->willReturn($view->reveal()); + + $this->serviceLocator->has('config')->willReturn(true); + $this->serviceLocator->get('config') + ->shouldBeCalled() + ->willReturn(new \ArrayObject([ + 'view_manager' => [ + 'layout' => 'foo', + ], + ])); + + /** @var DefaultRenderingStrategy $instance */ + $instance = $factory($this->serviceLocator->reveal(), 'foo'); + + $this->assertInstanceOf(DefaultRenderingStrategy::class, $instance); + $this->assertSame('foo', $instance->getLayoutTemplate()); + } + + public function testInvokeWithEmptyObject() + { + $factory = new HttpDefaultRenderingStrategyFactory(); + + $view = $this->prophesize(View::class); + $this->serviceLocator->get(View::class) + ->willReturn($view->reveal()); + + $this->serviceLocator->has('config')->willReturn(true); + $this->serviceLocator->get('config') + ->willReturn([]); + + $instance = $factory($this->serviceLocator->reveal(), 'foo'); + + $this->assertInstanceOf(DefaultRenderingStrategy::class, $instance); + $this->assertSame('layout/layout', $instance->getLayoutTemplate()); + } +}