pax_global_header00006660000000000000000000000064136067640210014517gustar00rootroot0000000000000052 comment=e7f1ff9ad2b26550de31049e44ecc3ff7b0e7695 php-doctrine-common-2.12.0/000077500000000000000000000000001360676402100154635ustar00rootroot00000000000000php-doctrine-common-2.12.0/.doctrine-project.json000066400000000000000000000005411360676402100217070ustar00rootroot00000000000000{ "active": true, "name": "Common", "slug": "common", "docsSlug": "doctrine-common", "versions": [ { "name": "master", "branchName": "master", "slug": "latest" }, { "name": "2.11", "branchName": "2.11", "current": true } ] } php-doctrine-common-2.12.0/.github/000077500000000000000000000000001360676402100170235ustar00rootroot00000000000000php-doctrine-common-2.12.0/.github/FUNDING.yml000066400000000000000000000001651360676402100206420ustar00rootroot00000000000000patreon: phpdoctrine tidelift: packagist/doctrine%2Fcommon custom: https://www.doctrine-project.org/sponsorship.html php-doctrine-common-2.12.0/.gitignore000066400000000000000000000002551360676402100174550ustar00rootroot00000000000000build/ logs/ reports/ dist/ tests/Doctrine/Tests/Common/Proxy/generated/ vendor/ .idea doctrine-common-*.tar doctrine-common-*.tar.gz /phpcs.xml /.phpcs-cache /phpstan.neon php-doctrine-common-2.12.0/.travis.yml000066400000000000000000000017041360676402100175760ustar00rootroot00000000000000dist: trusty sudo: false language: php cache: directories: - $HOME/.composer/cache php: - 7.4 - 7.3 - 7.2 - 7.1 before_install: - mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available" install: - travis_retry composer -n --prefer-source install script: ./vendor/bin/phpunit jobs: include: - stage: Coverage before_script: - mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{.disabled,} - if [[ ! $(php -m | grep -si xdebug) ]]; then echo "xdebug required for coverage"; exit 1; fi script: - ./vendor/bin/phpunit --coverage-clover clover.xml after_script: - wget https://scrutinizer-ci.com/ocular.phar - php ocular.phar code-coverage:upload --format=php-clover clover.xml - stage: Coding standard script: - ./vendor/bin/phpcs - stage: Lint script: vendor/bin/phpstan analyse php-doctrine-common-2.12.0/LICENSE000066400000000000000000000020511360676402100164660ustar00rootroot00000000000000Copyright (c) 2006-2015 Doctrine Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. php-doctrine-common-2.12.0/README.md000066400000000000000000000006631360676402100167470ustar00rootroot00000000000000# Doctrine Common [![Build Status](https://secure.travis-ci.org/doctrine/common.png)](https://travis-ci.org/doctrine/common) The Doctrine Common project is a library that provides extensions to core PHP functionality. ## More resources: * [Website](https://www.doctrine-project.org/) * [Documentation](https://www.doctrine-project.org/projects/doctrine-common/en/latest/) * [Downloads](https://github.com/doctrine/common/releases) php-doctrine-common-2.12.0/UPGRADE_TO_2_1000066400000000000000000000041211360676402100175360ustar00rootroot00000000000000This document details all the possible changes that you should investigate when updating your project from Doctrine Common 2.0.x to 2.1 ## AnnotationReader changes The annotation reader was heavily refactored between 2.0 and 2.1-RC1. In theory the operation of the new reader should be backwards compatible, but it has to be setup differently to work that way: $reader = new \Doctrine\Common\Annotations\AnnotationReader(); $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); // new code necessary starting here $reader->setIgnoreNotImportedAnnotations(true); $reader->setEnableParsePhpImports(false); $reader = new \Doctrine\Common\Annotations\CachedReader( new \Doctrine\Common\Annotations\IndexedReader($reader), new ArrayCache() ); ## Annotation Base class or @Annotation Beginning after 2.1-RC2 you have to either extend ``Doctrine\Common\Annotations\Annotation`` or add @Annotation to your annotations class-level docblock, otherwise the class will simply be ignored. ## Removed methods on AnnotationReader * AnnotationReader::setAutoloadAnnotations() * AnnotationReader::getAutoloadAnnotations() * AnnotationReader::isAutoloadAnnotations() ## AnnotationRegistry Autoloading through the PHP autoloader is removed from the 2.1 AnnotationReader. Instead you have to use the global AnnotationRegistry for loading purposes: \Doctrine\Common\Annotations\AnnotationRegistry::registerFile($fileWithAnnotations); \Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace($namespace, $dirs = null); \Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespaces($namespaces); \Doctrine\Common\Annotations\AnnotationRegistry::registerLoader($callable); The $callable for registering a loader accepts a class as first and only parameter and must try to silently autoload it. On success true has to be returned. The registerAutoloadNamespace function registers a PSR-0 compatible silent autoloader for all classes with the given namespace in the given directories. If null is passed as directory the include path will be used. php-doctrine-common-2.12.0/UPGRADE_TO_2_2000066400000000000000000000045731360676402100175520ustar00rootroot00000000000000This document details all the possible changes that you should investigate when updating your project from Doctrine Common 2.1 to 2.2: ## Annotation Changes - AnnotationReader::setIgnoreNotImportedAnnotations has been removed, you need to add ignore annotation names which are supposed to be ignored via AnnotationReader::addGlobalIgnoredName - AnnotationReader::setAutoloadAnnotations was deprecated by the AnnotationRegistry in 2.1 and has been removed in 2.2 - AnnotationReader::setEnableParsePhpImports was added to ease transition to the new annotation mechanism in 2.1 and is removed in 2.2 - AnnotationReader::isParsePhpImportsEnabled is removed (see above) - AnnotationReader::setDefaultAnnotationNamespace was deprecated in favor of explicit configuration in 2.1 and will be removed in 2.2 (for isolated projects where you have full-control over _all_ available annotations, we offer a dedicated reader class ``SimpleAnnotationReader``) - AnnotationReader::setAnnotationCreationFunction was deprecated in 2.1 and will be removed in 2.2. We only offer two creation mechanisms which cannot be changed anymore to allow the same reader instance to work with all annotations regardless of which library they are coming from. - AnnotationReader::setAnnotationNamespaceAlias was deprecated in 2.1 and will be removed in 2.2 (see setDefaultAnnotationNamespace) - If you use a class as annotation which has not the @Annotation marker in it's class block, we will now throw an exception instead of silently ignoring it. You can however still achieve the previous behavior using the @IgnoreAnnotation, or AnnotationReader::addGlobalIgnoredName (the exception message will contain detailed instructions when you run into this problem). ## Cache Changes - Renamed old AbstractCache to CacheProvider - Dropped the support to the following functions of all cache providers: - CacheProvider::deleteByWildcard - CacheProvider::deleteByRegEx - CacheProvider::deleteByPrefix - CacheProvider::deleteBySuffix - CacheProvider::deleteAll will not remove ALL entries, it will only mark them as invalid - CacheProvider::flushAll will remove ALL entries, namespaced or not - Added support to MemcachedCache - Added support to WincacheCache ## ClassLoader Changes - ClassLoader::fileExistsInIncludePath() no longer exists. Use the native stream_resolve_include_path() PHP functionphp-doctrine-common-2.12.0/build.properties000066400000000000000000000002021360676402100206720ustar00rootroot00000000000000# Version class and file project.version_class = Doctrine\\Common\\Version project.version_file = lib/Doctrine/Common/Version.php php-doctrine-common-2.12.0/build.xml000066400000000000000000000072751360676402100173170ustar00rootroot00000000000000 php-doctrine-common-2.12.0/composer.json000066400000000000000000000035011360676402100202040ustar00rootroot00000000000000{ "name": "doctrine/common", "type": "library", "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, persistence interfaces, proxies, event system and much more.", "keywords": [ "php", "common", "doctrine" ], "homepage": "https://www.doctrine-project.org/projects/common.html", "license": "MIT", "authors": [ {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, {"name": "Roman Borschel", "email": "roman@code-factory.org"}, {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, {"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}, {"name": "Marco Pivetta", "email": "ocramius@gmail.com"} ], "require": { "php": "^7.1", "doctrine/inflector": "^1.0", "doctrine/cache": "^1.0", "doctrine/collections": "^1.0", "doctrine/lexer": "^1.0", "doctrine/annotations": "^1.0", "doctrine/event-manager": "^1.0", "doctrine/reflection": "^1.0", "doctrine/persistence": "^1.1" }, "require-dev": { "phpstan/phpstan": "^0.11", "phpstan/phpstan-phpunit": "^0.11", "phpunit/phpunit": "^7.0", "doctrine/coding-standard": "^1.0", "squizlabs/php_codesniffer": "^3.0", "symfony/phpunit-bridge": "^4.0.5" }, "autoload": { "psr-4": { "Doctrine\\Common\\": "lib/Doctrine/Common" } }, "autoload-dev": { "psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" } }, "extra": { "branch-alias": { "dev-master": "2.11.x-dev" } } } php-doctrine-common-2.12.0/composer.lock000066400000000000000000003525351360676402100202010ustar00rootroot00000000000000{ "_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#installing-dependencies", "This file is @generated automatically" ], "content-hash": "40bcfe4c5277cdfa06868ad21fd26d85", "packages": [ { "name": "doctrine/annotations", "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", "shasum": "" }, "require": { "doctrine/lexer": "1.*", "php": "^7.1" }, "require-dev": { "doctrine/cache": "1.*", "phpunit/phpunit": "^6.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.6.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], "description": "Docblock Annotations Parser", "homepage": "http://www.doctrine-project.org", "keywords": [ "annotations", "docblock", "parser" ], "time": "2017-12-06T07:11:42+00:00" }, { "name": "doctrine/cache", "version": "v1.8.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57", "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57", "shasum": "" }, "require": { "php": "~7.1" }, "conflict": { "doctrine/common": ">2.2,<2.4" }, "require-dev": { "alcaeus/mongo-php-adapter": "^1.1", "doctrine/coding-standard": "^4.0", "mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.0", "predis/predis": "~1.0" }, "suggest": { "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.8.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], "description": "Caching library offering an object-oriented API for many cache backends", "homepage": "https://www.doctrine-project.org", "keywords": [ "cache", "caching" ], "time": "2018-08-21T18:01:43+00:00" }, { "name": "doctrine/collections", "version": "v1.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/collections/zipball/a01ee38fcd999f34d9bfbcee59dbda5105449cbf", "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "doctrine/coding-standard": "~0.1@dev", "phpunit/phpunit": "^5.7" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.3.x-dev" } }, "autoload": { "psr-0": { "Doctrine\\Common\\Collections\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], "description": "Collections Abstraction library", "homepage": "http://www.doctrine-project.org", "keywords": [ "array", "collections", "iterator" ], "time": "2017-07-22T10:37:32+00:00" }, { "name": "doctrine/event-manager", "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3", "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3", "shasum": "" }, "require": { "php": "^7.1" }, "conflict": { "doctrine/common": "<2.9@dev" }, "require-dev": { "doctrine/coding-standard": "^4.0", "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Common\\": "lib/Doctrine/Common" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" }, { "name": "Marco Pivetta", "email": "ocramius@gmail.com" } ], "description": "Doctrine Event Manager component", "homepage": "https://www.doctrine-project.org/projects/event-manager.html", "keywords": [ "event", "eventdispatcher", "eventmanager" ], "time": "2018-06-11T11:59:03+00:00" }, { "name": "doctrine/inflector", "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", "reference": "5527a48b7313d15261292c149e55e26eae771b0a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a", "reference": "5527a48b7313d15261292c149e55e26eae771b0a", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^6.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.3.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], "description": "Common String Manipulations with regard to casing and singular/plural rules.", "homepage": "http://www.doctrine-project.org", "keywords": [ "inflection", "pluralize", "singularize", "string" ], "time": "2018-01-09T20:05:19+00:00" }, { "name": "doctrine/lexer", "version": "v1.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", "shasum": "" }, "require": { "php": ">=5.3.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-0": { "Doctrine\\Common\\Lexer\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", "homepage": "http://www.doctrine-project.org", "keywords": [ "lexer", "parser" ], "time": "2014-09-09T13:34:57+00:00" }, { "name": "doctrine/persistence", "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", "reference": "c0f1c17602afc18b4cbd8e1c8125f264c9cf7d38" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/persistence/zipball/c0f1c17602afc18b4cbd8e1c8125f264c9cf7d38", "reference": "c0f1c17602afc18b4cbd8e1c8125f264c9cf7d38", "shasum": "" }, "require": { "doctrine/annotations": "^1.0", "doctrine/cache": "^1.0", "doctrine/collections": "^1.0", "doctrine/event-manager": "^1.0", "doctrine/reflection": "^1.0", "php": "^7.1" }, "conflict": { "doctrine/common": "<2.10@dev" }, "require-dev": { "doctrine/coding-standard": "^5.0", "phpstan/phpstan": "^0.8", "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Common\\": "lib/Doctrine/Common" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" }, { "name": "Marco Pivetta", "email": "ocramius@gmail.com" } ], "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.", "homepage": "https://doctrine-project.org/projects/persistence.html", "keywords": [ "mapper", "object", "odm", "orm", "persistence" ], "time": "2018-11-21T00:33:13+00:00" }, { "name": "doctrine/reflection", "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/reflection.git", "reference": "02538d3f95e88eb397a5f86274deb2c6175c2ab6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/reflection/zipball/02538d3f95e88eb397a5f86274deb2c6175c2ab6", "reference": "02538d3f95e88eb397a5f86274deb2c6175c2ab6", "shasum": "" }, "require": { "doctrine/annotations": "^1.0", "ext-tokenizer": "*", "php": "^7.1" }, "require-dev": { "doctrine/coding-standard": "^4.0", "doctrine/common": "^2.8", "phpstan/phpstan": "^0.9.2", "phpstan/phpstan-phpunit": "^0.9.4", "phpunit/phpunit": "^7.0", "squizlabs/php_codesniffer": "^3.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Common\\": "lib/Doctrine/Common" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" }, { "name": "Marco Pivetta", "email": "ocramius@gmail.com" } ], "description": "Doctrine Reflection component", "homepage": "https://www.doctrine-project.org/projects/reflection.html", "keywords": [ "reflection" ], "time": "2018-06-14T14:45:07+00:00" } ], "packages-dev": [ { "name": "composer/xdebug-handler", "version": "1.3.2", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", "reference": "d17708133b6c276d6e42ef887a877866b909d892" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/d17708133b6c276d6e42ef887a877866b909d892", "reference": "d17708133b6c276d6e42ef887a877866b909d892", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0", "psr/log": "^1.0" }, "require-dev": { "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" }, "type": "library", "autoload": { "psr-4": { "Composer\\XdebugHandler\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "John Stevenson", "email": "john-stevenson@blueyonder.co.uk" } ], "description": "Restarts a process without xdebug.", "keywords": [ "Xdebug", "performance" ], "time": "2019-01-28T20:25:53+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", "version": "v0.4.4", "source": { "type": "git", "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", "reference": "2e41850d5f7797cbb1af7b030d245b3b24e63a08" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/2e41850d5f7797cbb1af7b030d245b3b24e63a08", "reference": "2e41850d5f7797cbb1af7b030d245b3b24e63a08", "shasum": "" }, "require": { "composer-plugin-api": "^1.0", "php": "^5.3|^7", "squizlabs/php_codesniffer": "*" }, "require-dev": { "composer/composer": "*", "wimg/php-compatibility": "^8.0" }, "suggest": { "dealerdirect/qa-tools": "All the PHP QA tools you'll need" }, "type": "composer-plugin", "extra": { "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, "autoload": { "psr-4": { "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Franck Nijhof", "email": "f.nijhof@dealerdirect.nl", "homepage": "http://workingatdealerdirect.eu", "role": "Developer" } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", "homepage": "http://workingatdealerdirect.eu", "keywords": [ "PHPCodeSniffer", "PHP_CodeSniffer", "code quality", "codesniffer", "composer", "installer", "phpcs", "plugin", "qa", "quality", "standard", "standards", "style guide", "stylecheck", "tests" ], "time": "2017-12-06T16:27:17+00:00" }, { "name": "doctrine/coding-standard", "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/coding-standard.git", "reference": "d0af8acc36d69f315d550eef78a9607bba24a6da" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/coding-standard/zipball/d0af8acc36d69f315d550eef78a9607bba24a6da", "reference": "d0af8acc36d69f315d550eef78a9607bba24a6da", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.4.2", "php": "^7.1", "squizlabs/php_codesniffer": "~3.0" }, "type": "phpcodesniffer-standard", "extra": { "branch-alias": { "dev-master": "0.1-dev" } }, "autoload": { "psr-4": { "Doctrine\\Sniffs\\": "lib/Doctrine/Sniffs" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Steve Müller", "email": "st.mueller@dzh-online.de" } ], "description": "Doctrine Coding Standard", "homepage": "http://www.doctrine-project.org", "keywords": [ "code", "coding", "cs", "doctrine", "sniffer", "standard", "style" ], "time": "2017-08-20T01:30:16+00:00" }, { "name": "doctrine/instantiator", "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", "reference": "a2c590166b2133a4633738648b6b064edae0814a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", "reference": "a2c590166b2133a4633738648b6b064edae0814a", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "doctrine/coding-standard": "^6.0", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.13", "phpstan/phpstan-phpunit": "^0.11", "phpstan/phpstan-shim": "^0.11", "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.2.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", "homepage": "http://ocramius.github.com/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], "time": "2019-03-17T17:37:11+00:00" }, { "name": "jean85/pretty-package-versions", "version": "1.2", "source": { "type": "git", "url": "https://github.com/Jean85/pretty-package-versions.git", "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48", "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48", "shasum": "" }, "require": { "ocramius/package-versions": "^1.2.0", "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "Jean85\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Alessandro Lai", "email": "alessandro.lai85@gmail.com" } ], "description": "A wrapper for ocramius/package-versions to get pretty versions strings", "keywords": [ "composer", "package", "release", "versions" ], "time": "2018-06-13T13:22:40+00:00" }, { "name": "myclabs/deep-copy", "version": "1.9.3", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", "shasum": "" }, "require": { "php": "^7.1" }, "replace": { "myclabs/deep-copy": "self.version" }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", "phpunit/phpunit": "^7.1" }, "type": "library", "autoload": { "psr-4": { "DeepCopy\\": "src/DeepCopy/" }, "files": [ "src/DeepCopy/deep_copy.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Create deep copies (clones) of your objects", "keywords": [ "clone", "copy", "duplicate", "object", "object graph" ], "time": "2019-08-09T12:45:53+00:00" }, { "name": "nette/bootstrap", "version": "v2.4.6", "source": { "type": "git", "url": "https://github.com/nette/bootstrap.git", "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nette/bootstrap/zipball/268816e3f1bb7426c3a4ceec2bd38a036b532543", "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543", "shasum": "" }, "require": { "nette/di": "~2.4.7", "nette/utils": "~2.4", "php": ">=5.6.0" }, "conflict": { "nette/nette": "<2.2" }, "require-dev": { "latte/latte": "~2.2", "nette/application": "~2.3", "nette/caching": "~2.3", "nette/database": "~2.3", "nette/forms": "~2.3", "nette/http": "~2.4.0", "nette/mail": "~2.3", "nette/robot-loader": "^2.4.2 || ^3.0", "nette/safe-stream": "~2.2", "nette/security": "~2.3", "nette/tester": "~2.0", "tracy/tracy": "^2.4.1" }, "suggest": { "nette/robot-loader": "to use Configurator::createRobotLoader()", "tracy/tracy": "to use Configurator::enableTracy()" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.4-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", "GPL-2.0", "GPL-3.0" ], "authors": [ { "name": "David Grudl", "homepage": "https://davidgrudl.com" }, { "name": "Nette Community", "homepage": "https://nette.org/contributors" } ], "description": "? Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", "homepage": "https://nette.org", "keywords": [ "bootstrapping", "configurator", "nette" ], "time": "2018-05-17T12:52:20+00:00" }, { "name": "nette/di", "version": "v2.4.15", "source": { "type": "git", "url": "https://github.com/nette/di.git", "reference": "d0561b8f77e8ef2ed6d83328860e16c81a5a8649" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nette/di/zipball/d0561b8f77e8ef2ed6d83328860e16c81a5a8649", "reference": "d0561b8f77e8ef2ed6d83328860e16c81a5a8649", "shasum": "" }, "require": { "ext-tokenizer": "*", "nette/neon": "^2.3.3 || ~3.0.0", "nette/php-generator": "^2.6.1 || ^3.0.0", "nette/utils": "^2.5.0 || ~3.0.0", "php": ">=5.6.0" }, "conflict": { "nette/bootstrap": "<2.4", "nette/nette": "<2.2" }, "require-dev": { "nette/tester": "^2.0", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.4-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", "GPL-2.0", "GPL-3.0" ], "authors": [ { "name": "David Grudl", "homepage": "https://davidgrudl.com" }, { "name": "Nette Community", "homepage": "https://nette.org/contributors" } ], "description": "? Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.", "homepage": "https://nette.org", "keywords": [ "compiled", "di", "dic", "factory", "ioc", "nette", "static" ], "time": "2019-01-30T13:26:05+00:00" }, { "name": "nette/finder", "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/nette/finder.git", "reference": "6be1b83ea68ac558aff189d640abe242e0306fe2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nette/finder/zipball/6be1b83ea68ac558aff189d640abe242e0306fe2", "reference": "6be1b83ea68ac558aff189d640abe242e0306fe2", "shasum": "" }, "require": { "nette/utils": "^2.4 || ~3.0.0", "php": ">=7.1" }, "conflict": { "nette/nette": "<2.2" }, "require-dev": { "nette/tester": "^2.0", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.5-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", "GPL-2.0", "GPL-3.0" ], "authors": [ { "name": "David Grudl", "homepage": "https://davidgrudl.com" }, { "name": "Nette Community", "homepage": "https://nette.org/contributors" } ], "description": "🔍 Nette Finder: find files and directories with an intuitive API.", "homepage": "https://nette.org", "keywords": [ "filesystem", "glob", "iterator", "nette" ], "time": "2019-02-28T18:13:25+00:00" }, { "name": "nette/neon", "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/nette/neon.git", "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nette/neon/zipball/cbff32059cbdd8720deccf9e9eace6ee516f02eb", "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb", "shasum": "" }, "require": { "ext-iconv": "*", "ext-json": "*", "php": ">=7.0" }, "require-dev": { "nette/tester": "^2.0", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", "GPL-2.0", "GPL-3.0" ], "authors": [ { "name": "David Grudl", "homepage": "https://davidgrudl.com" }, { "name": "Nette Community", "homepage": "https://nette.org/contributors" } ], "description": "🍸 Nette NEON: encodes and decodes NEON file format.", "homepage": "http://ne-on.org", "keywords": [ "export", "import", "neon", "nette", "yaml" ], "time": "2019-02-05T21:30:40+00:00" }, { "name": "nette/php-generator", "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", "reference": "9de4e093a130f7a1bd175198799ebc0efbac6924" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nette/php-generator/zipball/9de4e093a130f7a1bd175198799ebc0efbac6924", "reference": "9de4e093a130f7a1bd175198799ebc0efbac6924", "shasum": "" }, "require": { "nette/utils": "^2.4.2 || ~3.0.0", "php": ">=7.1" }, "conflict": { "nette/nette": "<2.2" }, "require-dev": { "nette/tester": "^2.0", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.2-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", "GPL-2.0", "GPL-3.0" ], "authors": [ { "name": "David Grudl", "homepage": "https://davidgrudl.com" }, { "name": "Nette Community", "homepage": "https://nette.org/contributors" } ], "description": "? Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.3 features.", "homepage": "https://nette.org", "keywords": [ "code", "nette", "php", "scaffolding" ], "time": "2018-11-27T19:00:14+00:00" }, { "name": "nette/robot-loader", "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/nette/robot-loader.git", "reference": "3e8d75d6d976e191bdf46752ca40a286671219d2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nette/robot-loader/zipball/3e8d75d6d976e191bdf46752ca40a286671219d2", "reference": "3e8d75d6d976e191bdf46752ca40a286671219d2", "shasum": "" }, "require": { "ext-tokenizer": "*", "nette/finder": "^2.3 || ^3.0", "nette/utils": "^2.4 || ^3.0", "php": ">=5.6.0" }, "conflict": { "nette/nette": "<2.2" }, "require-dev": { "nette/tester": "^2.0", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", "GPL-2.0", "GPL-3.0" ], "authors": [ { "name": "David Grudl", "homepage": "https://davidgrudl.com" }, { "name": "Nette Community", "homepage": "https://nette.org/contributors" } ], "description": "? Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", "homepage": "https://nette.org", "keywords": [ "autoload", "class", "interface", "nette", "trait" ], "time": "2019-03-01T20:23:02+00:00" }, { "name": "nette/utils", "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/nette/utils.git", "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nette/utils/zipball/17b9f76f2abd0c943adfb556e56f2165460b15ce", "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce", "shasum": "" }, "require": { "php": ">=5.6.0" }, "conflict": { "nette/nette": "<2.2" }, "require-dev": { "nette/tester": "~2.0", "tracy/tracy": "^2.3" }, "suggest": { "ext-gd": "to use Image", "ext-iconv": "to use Strings::webalize() and toAscii()", "ext-intl": "for script transliteration in Strings::webalize() and toAscii()", "ext-json": "to use Nette\\Utils\\Json", "ext-mbstring": "to use Strings::lower() etc...", "ext-xml": "to use Strings::length() etc. when mbstring is not available" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.5-dev" } }, "autoload": { "classmap": [ "src/" ], "files": [ "src/loader.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", "GPL-2.0", "GPL-3.0" ], "authors": [ { "name": "David Grudl", "homepage": "https://davidgrudl.com" }, { "name": "Nette Community", "homepage": "https://nette.org/contributors" } ], "description": "? Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", "homepage": "https://nette.org", "keywords": [ "array", "core", "datetime", "images", "json", "nette", "paginator", "password", "slugify", "string", "unicode", "utf-8", "utility", "validation" ], "time": "2018-09-18T10:22:16+00:00" }, { "name": "nikic/php-parser", "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/5221f49a608808c1e4d436df32884cbc1b821ac0", "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.5 || ^7.0" }, "bin": [ "bin/php-parse" ], "type": "library", "extra": { "branch-alias": { "dev-master": "4.2-dev" } }, "autoload": { "psr-4": { "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Nikita Popov" } ], "description": "A PHP parser written in PHP", "keywords": [ "parser", "php" ], "time": "2019-02-16T20:54:15+00:00" }, { "name": "ocramius/package-versions", "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/Ocramius/PackageVersions.git", "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", "shasum": "" }, "require": { "composer-plugin-api": "^1.0.0", "php": "^7.1.0" }, "require-dev": { "composer/composer": "^1.6.3", "doctrine/coding-standard": "^5.0.1", "ext-zip": "*", "infection/infection": "^0.7.1", "phpunit/phpunit": "^7.0.0" }, "type": "composer-plugin", "extra": { "class": "PackageVersions\\Installer", "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "psr-4": { "PackageVersions\\": "src/PackageVersions" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com" } ], "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", "time": "2019-02-21T12:16:21+00:00" }, { "name": "phar-io/manifest", "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", "phar-io/version": "^2.0", "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": "2018-07-08T19:23:20+00:00" }, { "name": "phar-io/version", "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", "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": "2018-07-08T19:19:57+00:00" }, { "name": "phpdocumentor/reflection-common", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", "shasum": "" }, "require": { "php": ">=5.5" }, "require-dev": { "phpunit/phpunit": "^4.6" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ "src" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Jaap van Otterdijk", "email": "opensource@ijaap.nl" } ], "description": "Common reflection classes used by phpdocumentor to reflect the code structure", "homepage": "http://www.phpdoc.org", "keywords": [ "FQSEN", "phpDocumentor", "phpdoc", "reflection", "static analysis" ], "time": "2017-09-11T18:02:19+00:00" }, { "name": "phpdocumentor/reflection-docblock", "version": "4.3.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", "shasum": "" }, "require": { "php": "^7.0", "phpdocumentor/reflection-common": "^1.0.0", "phpdocumentor/type-resolver": "^0.4.0", "webmozart/assert": "^1.0" }, "require-dev": { "doctrine/instantiator": "~1.0.5", "mockery/mockery": "^1.0", "phpunit/phpunit": "^6.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "time": "2019-04-30T17:48:53+00:00" }, { "name": "phpdocumentor/type-resolver", "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", "shasum": "" }, "require": { "php": "^5.5 || ^7.0", "phpdocumentor/reflection-common": "^1.0" }, "require-dev": { "mockery/mockery": "^0.9.4", "phpunit/phpunit": "^5.2||^4.8.24" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" } ], "time": "2017-07-14T14:27:02+00:00" }, { "name": "phpspec/prophecy", "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76", "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76", "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|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.8.x-dev" } }, "autoload": { "psr-4": { "Prophecy\\": "src/Prophecy" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Konstantin Kudryashov", "email": "ever.zet@gmail.com", "homepage": "http://everzet.com" }, { "name": "Marcello Duarte", "email": "marcello.duarte@gmail.com" } ], "description": "Highly opinionated mocking framework for PHP 5.3+", "homepage": "https://github.com/phpspec/prophecy", "keywords": [ "Double", "Dummy", "fake", "mock", "spy", "stub" ], "time": "2019-06-13T12:50:23+00:00" }, { "name": "phpstan/phpdoc-parser", "version": "0.3.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/2cc49f47c69b023eaf05b48e6529389893b13d74", "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74", "shasum": "" }, "require": { "php": "~7.1" }, "require-dev": { "consistence/coding-standard": "^2.0.0", "jakub-onderka/php-parallel-lint": "^0.9.2", "phing/phing": "^2.16.0", "phpstan/phpstan": "^0.10", "phpunit/phpunit": "^6.3", "slevomat/coding-standard": "^3.3.0", "symfony/process": "^3.4 || ^4.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "0.3-dev" } }, "autoload": { "psr-4": { "PHPStan\\PhpDocParser\\": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "PHPDoc parser with support for nullable, intersection and generic types", "time": "2019-01-14T12:26:23+00:00" }, { "name": "phpstan/phpstan", "version": "0.11.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", "reference": "e4644b4a8fd393c346f1137305fb2f76a7dc20a7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e4644b4a8fd393c346f1137305fb2f76a7dc20a7", "reference": "e4644b4a8fd393c346f1137305fb2f76a7dc20a7", "shasum": "" }, "require": { "composer/xdebug-handler": "^1.3.0", "jean85/pretty-package-versions": "^1.0.3", "nette/bootstrap": "^2.4 || ^3.0", "nette/di": "^2.4.7 || ^3.0", "nette/robot-loader": "^3.0.1", "nette/utils": "^2.4.5 || ^3.0", "nikic/php-parser": "^4.0.2", "php": "~7.1", "phpstan/phpdoc-parser": "^0.3", "symfony/console": "~3.2 || ~4.0", "symfony/finder": "~3.2 || ~4.0" }, "conflict": { "symfony/console": "3.4.16 || 4.1.5" }, "require-dev": { "brianium/paratest": "^2.0", "consistence/coding-standard": "^3.5", "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", "ext-intl": "*", "ext-mysqli": "*", "ext-soap": "*", "ext-zip": "*", "jakub-onderka/php-parallel-lint": "^1.0", "localheinz/composer-normalize": "^1.1.0", "phing/phing": "^2.16.0", "phpstan/phpstan-deprecation-rules": "^0.11", "phpstan/phpstan-php-parser": "^0.11", "phpstan/phpstan-phpunit": "^0.11", "phpstan/phpstan-strict-rules": "^0.11", "phpunit/phpunit": "^7.0", "slevomat/coding-standard": "^4.7.2", "squizlabs/php_codesniffer": "^3.3.2" }, "bin": [ "bin/phpstan" ], "type": "library", "extra": { "branch-alias": { "dev-master": "0.11-dev" } }, "autoload": { "psr-4": { "PHPStan\\": [ "src/", "build/PHPStan" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", "time": "2019-03-10T16:25:30+00:00" }, { "name": "phpstan/phpstan-phpunit", "version": "0.11", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", "reference": "70c22d44b96a21a4952fc13021a5a63cc83f5c81" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/70c22d44b96a21a4952fc13021a5a63cc83f5c81", "reference": "70c22d44b96a21a4952fc13021a5a63cc83f5c81", "shasum": "" }, "require": { "nikic/php-parser": "^4.0", "php": "~7.1", "phpstan/phpdoc-parser": "^0.3", "phpstan/phpstan": "^0.11" }, "conflict": { "phpunit/phpunit": "<7.0" }, "require-dev": { "consistence/coding-standard": "^3.0.1", "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", "jakub-onderka/php-parallel-lint": "^1.0", "phing/phing": "^2.16.0", "phpstan/phpstan-strict-rules": "^0.11", "phpunit/phpunit": "^7.0", "satooshi/php-coveralls": "^1.0", "slevomat/coding-standard": "^4.5.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "0.11-dev" } }, "autoload": { "psr-4": { "PHPStan\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "PHPUnit extensions and rules for PHPStan", "time": "2018-12-22T14:05:04+00:00" }, { "name": "phpunit/php-code-coverage", "version": "6.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", "php": "^7.1", "phpunit/php-file-iterator": "^2.0", "phpunit/php-text-template": "^1.2.1", "phpunit/php-token-stream": "^3.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", "sebastian/environment": "^3.1 || ^4.0", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "suggest": { "ext-xdebug": "^2.6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "6.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ "coverage", "testing", "xunit" ], "time": "2018-10-31T16:06:48+00:00" }, { "name": "phpunit/php-file-iterator", "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", "reference": "050bedf145a257b1ff02746c31894800e5122946" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", "reference": "050bedf145a257b1ff02746c31894800e5122946", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "FilterIterator implementation that filters files based on a list of suffixes.", "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ "filesystem", "iterator" ], "time": "2018-09-13T20:33:42+00:00" }, { "name": "phpunit/php-text-template", "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "shasum": "" }, "require": { "php": ">=5.3.3" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Simple template engine.", "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ "template" ], "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Utility class for timing", "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ "timer" ], "time": "2019-06-07T04:22:29+00:00" }, { "name": "phpunit/php-token-stream", "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", "reference": "e899757bb3df5ff6e95089132f32cd59aac2220a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e899757bb3df5ff6e95089132f32cd59aac2220a", "reference": "e899757bb3df5ff6e95089132f32cd59aac2220a", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Wrapper around PHP's tokenizer extension.", "homepage": "https://github.com/sebastianbergmann/php-token-stream/", "keywords": [ "tokenizer" ], "time": "2019-07-25T05:29:42+00:00" }, { "name": "phpunit/phpunit", "version": "7.5.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", "reference": "d79c053d972856b8b941bb233e39dc521a5093f0" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d79c053d972856b8b941bb233e39dc521a5093f0", "reference": "d79c053d972856b8b941bb233e39dc521a5093f0", "shasum": "" }, "require": { "doctrine/instantiator": "^1.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "myclabs/deep-copy": "^1.7", "phar-io/manifest": "^1.0.2", "phar-io/version": "^2.0", "php": "^7.1", "phpspec/prophecy": "^1.7", "phpunit/php-code-coverage": "^6.0.7", "phpunit/php-file-iterator": "^2.0.1", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^2.1", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", "sebastian/environment": "^4.0", "sebastian/exporter": "^3.1", "sebastian/global-state": "^2.0", "sebastian/object-enumerator": "^3.0.3", "sebastian/resource-operations": "^2.0", "sebastian/version": "^2.0.1" }, "conflict": { "phpunit/phpunit-mock-objects": "*" }, "require-dev": { "ext-pdo": "*" }, "suggest": { "ext-soap": "*", "ext-xdebug": "*", "phpunit/php-invoker": "^2.0" }, "bin": [ "phpunit" ], "type": "library", "extra": { "branch-alias": { "dev-master": "7.5-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "The PHP Unit Testing framework.", "homepage": "https://phpunit.de/", "keywords": [ "phpunit", "testing", "xunit" ], "time": "2019-08-21T07:05:16+00:00" }, { "name": "psr/log", "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", "shasum": "" }, "require": { "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "description": "Common interface for logging libraries", "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], "time": "2018-11-20T15:27:04+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", "shasum": "" }, "require": { "php": "^5.6 || ^7.0" }, "require-dev": { "phpunit/phpunit": "^5.7 || ^6.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": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "time": "2017-03-04T06:30:41+00:00" }, { "name": "sebastian/comparator", "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", "shasum": "" }, "require": { "php": "^7.1", "sebastian/diff": "^3.0", "sebastian/exporter": "^3.1" }, "require-dev": { "phpunit/phpunit": "^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], "time": "2018-07-12T15:12:46+00:00" }, { "name": "sebastian/diff", "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.5 || ^8.0", "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Kore Nordmann", "email": "mail@kore-nordmann.de" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff", "udiff", "unidiff", "unified diff" ], "time": "2019-02-04T06:01:07+00:00" }, { "name": "sebastian/environment", "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404", "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.5" }, "suggest": { "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.2-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides functionality to handle HHVM/PHP environments", "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", "hhvm" ], "time": "2019-05-05T09:05:15+00:00" }, { "name": "sebastian/exporter", "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", "reference": "06a9a5947f47b3029d76118eb5c22802e5869687" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/06a9a5947f47b3029d76118eb5c22802e5869687", "reference": "06a9a5947f47b3029d76118eb5c22802e5869687", "shasum": "" }, "require": { "php": "^7.0", "sebastian/recursion-context": "^3.0" }, "require-dev": { "ext-mbstring": "*", "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.1.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Adam Harvey", "email": "aharvey@php.net" }, { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", "homepage": "http://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "time": "2019-08-11T12:43:14+00:00" }, { "name": "sebastian/global-state", "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "shasum": "" }, "require": { "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "suggest": { "ext-uopz": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Snapshotting of global state", "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "time": "2017-04-27T15:39:26+00:00" }, { "name": "sebastian/object-enumerator", "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", "shasum": "" }, "require": { "php": "^7.0", "sebastian/object-reflector": "^1.1.1", "sebastian/recursion-context": "^3.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "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" }, { "name": "sebastian/recursion-context", "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", "shasum": "" }, "require": { "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Adam Harvey", "email": "aharvey@php.net" } ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "time": "2017-03-03T06:23:57+00:00" }, { "name": "sebastian/resource-operations", "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", "shasum": "" }, "require": { "php": "^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "time": "2018-10-04T04:07:39+00:00" }, { "name": "sebastian/version", "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, "require": { "php": ">=5.6" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, { "name": "squizlabs/php_codesniffer", "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", "reference": "379deb987e26c7cd103a7b387aea178baec96e48" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/379deb987e26c7cd103a7b387aea178baec96e48", "reference": "379deb987e26c7cd103a7b387aea178baec96e48", "shasum": "" }, "require": { "ext-simplexml": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": ">=5.4.0" }, "require-dev": { "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "bin": [ "bin/phpcs", "bin/phpcbf" ], "type": "library", "extra": { "branch-alias": { "dev-master": "3.x-dev" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Greg Sherwood", "role": "lead" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", "homepage": "http://www.squizlabs.com/php-codesniffer", "keywords": [ "phpcs", "standards" ], "time": "2018-12-19T23:57:18+00:00" }, { "name": "symfony/console", "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", "reference": "9dc2299a016497f9ee620be94524e6c0af0280a9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/console/zipball/9dc2299a016497f9ee620be94524e6c0af0280a9", "reference": "9dc2299a016497f9ee620be94524e6c0af0280a9", "shasum": "" }, "require": { "php": "^7.1.3", "symfony/contracts": "^1.0", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { "symfony/dependency-injection": "<3.4", "symfony/process": "<3.3" }, "provide": { "psr/log-implementation": "1.0" }, "require-dev": { "psr/log": "~1.0", "symfony/config": "~3.4|~4.0", "symfony/dependency-injection": "~3.4|~4.0", "symfony/event-dispatcher": "~3.4|~4.0", "symfony/lock": "~3.4|~4.0", "symfony/process": "~3.4|~4.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", "symfony/lock": "", "symfony/process": "" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.2-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Console Component", "homepage": "https://symfony.com", "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/contracts", "version": "v1.0.2", "source": { "type": "git", "url": "https://github.com/symfony/contracts.git", "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", "shasum": "" }, "require": { "php": "^7.1.3" }, "require-dev": { "psr/cache": "^1.0", "psr/container": "^1.0" }, "suggest": { "psr/cache": "When using the Cache contracts", "psr/container": "When using the Service contracts", "symfony/cache-contracts-implementation": "", "symfony/service-contracts-implementation": "", "symfony/translation-contracts-implementation": "" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\": "" }, "exclude-from-classmap": [ "**/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "A set of abstractions extracted out of the Symfony components", "homepage": "https://symfony.com", "keywords": [ "abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards" ], "time": "2018-12-05T08:06:11+00:00" }, { "name": "symfony/finder", "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", "reference": "267b7002c1b70ea80db0833c3afe05f0fbde580a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/finder/zipball/267b7002c1b70ea80db0833c3afe05f0fbde580a", "reference": "267b7002c1b70ea80db0833c3afe05f0fbde580a", "shasum": "" }, "require": { "php": "^7.1.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.2-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Finder\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", "time": "2019-02-23T15:42:05+00:00" }, { "name": "symfony/phpunit-bridge", "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", "reference": "2cc651a38fcb831a405c14fcb76fcb00320e7ee8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/2cc651a38fcb831a405c14fcb76fcb00320e7ee8", "reference": "2cc651a38fcb831a405c14fcb76fcb00320e7ee8", "shasum": "" }, "require": { "php": ">=5.3.3" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, "suggest": { "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" }, "bin": [ "bin/simple-phpunit" ], "type": "symfony-bridge", "extra": { "branch-alias": { "dev-master": "4.2-dev" }, "thanks": { "name": "phpunit/phpunit", "url": "https://github.com/sebastianbergmann/phpunit" } }, "autoload": { "files": [ "bootstrap.php" ], "psr-4": { "Symfony\\Bridge\\PhpUnit\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony PHPUnit Bridge", "homepage": "https://symfony.com", "time": "2019-02-18T06:49:49+00:00" }, { "name": "symfony/polyfill-ctype", "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", "reference": "550ebaac289296ce228a706d0867afc34687e3f4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", "reference": "550ebaac289296ce228a706d0867afc34687e3f4", "shasum": "" }, "require": { "php": ">=5.3.3" }, "suggest": { "ext-ctype": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.12-dev" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Gert de Pagter", "email": "BackEndTea@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for ctype functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "ctype", "polyfill", "portable" ], "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/polyfill-mbstring", "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", "shasum": "" }, "require": { "php": ">=5.3.3" }, "suggest": { "ext-mbstring": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.9-dev" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", "keywords": [ "compatibility", "mbstring", "polyfill", "portable", "shim" ], "time": "2018-09-21T13:07:52+00:00" }, { "name": "theseer/tokenizer", "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": "^7.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "role": "Developer", "email": "arne@blankerts.de" } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "time": "2019-06-13T22:48:21+00:00" }, { "name": "webmozart/assert", "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", "shasum": "" }, "require": { "php": "^5.3.3 || ^7.0", "symfony/polyfill-ctype": "^1.8" }, "require-dev": { "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.3-dev" } }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "Assertions to validate method input/output with nice error messages.", "keywords": [ "assert", "check", "validate" ], "time": "2019-08-24T08:43:50+00:00" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { "php": "^7.1" }, "platform-dev": [] } php-doctrine-common-2.12.0/docs/000077500000000000000000000000001360676402100164135ustar00rootroot00000000000000php-doctrine-common-2.12.0/docs/en/000077500000000000000000000000001360676402100170155ustar00rootroot00000000000000php-doctrine-common-2.12.0/docs/en/index.rst000066400000000000000000000002141360676402100206530ustar00rootroot00000000000000Common Documentation ==================== Welcome to the Doctrine Common Library documentation. .. toctree:: :depth: 2 :glob: * php-doctrine-common-2.12.0/docs/en/reference/000077500000000000000000000000001360676402100207535ustar00rootroot00000000000000php-doctrine-common-2.12.0/docs/en/reference/class-loading.rst000066400000000000000000000224511360676402100242310ustar00rootroot00000000000000Class Loading ============= Class loading is an essential part of any PHP application that makes heavy use of classes and interfaces. Unfortunately, a lot of people and projects spend a lot of time and effort on custom and specialized class loading strategies. It can quickly become a pain to understand what is going on when using multiple libraries and/or frameworks, each with its own way to do class loading. Class loading should be simple and it is an ideal candidate for convention over configuration. Overview -------- The Doctrine Common ClassLoader implements a simple and efficient approach to class loading that is easy to understand and use. The implementation is based on the widely used and accepted convention of mapping namespace and class names to a directory structure. This approach is used for example by Symfony2, the Zend Framework and of course, Doctrine. For example, the following class: .. code-block:: php register(); $dbalLoader->register(); $ormLoader->register(); Do not be afraid of using multiple class loaders. Due to the efficient class loading design you will not incur much overhead from using many class loaders. Take a look at the implementation of ``ClassLoader#loadClass`` to see how simple and efficient the class loading is. The iteration over the installed class loaders happens in C (with the exception of using ``ClassLoader::classExists``). A ClassLoader can be used in the following other variations, however, these are rarely used/needed: - If only the second argument is not supplied, the class loader will be responsible for the namespace prefix given in the first argument and it will rely on the PHP include_path. - If only the first argument is not supplied, the class loader will be responsible for *all* classes and it will try to look up *all* classes starting at the directory given as the second argument. - If both arguments are not supplied, the class loader will be responsible for *all* classes and it will rely on the PHP include_path. File Extension -------------- By default, a ClassLoader uses the ``.php`` file extension for all class files. You can change this behavior, for example to use a ClassLoader to load classes from a library that uses the ".class.php" convention (but it must nevertheless adhere to the directory structure convention!): .. code-block:: php setFileExtension('.class.php'); $customLoader->register(); Namespace Separator ------------------- By default, a ClassLoader uses the ``\`` namespace separator. You can change this behavior, for example to use a ClassLoader to load legacy Zend Framework classes that still use the underscore "_" separator: .. code-block:: php setNamespaceSeparator('_'); $zend1Loader->register(); Failing Silently and class_exists ---------------------------------- A lot of class/autoloaders these days try to fail silently when a class file is not found. For the most part this is necessary in order to support using ``class_exists('ClassName', true)`` which is supposed to return a boolean value but triggers autoloading. This is a bad thing as it basically forces class loaders to fail silently, which in turn requires costly file_exists or fopen calls for each class being loaded, even though in at least 99% of the cases this is not necessary (compare the number of class_exists(..., true) invocations to the total number of classes being loaded in a request). The Doctrine Common ClassLoader does not fail silently, by design. It therefore does not need any costly checks for file existence. A ClassLoader is always responsible for all classes with a certain namespace prefix and if a class is requested to be loaded and can not be found this is considered to be a fatal error. This also means that using class_exists(..., true) to check for class existence when using a Doctrine Common ClassLoader is not possible but this is not a bad thing. What class\_exists(..., true) actually means is two things: 1) Check whether the class is already defined/exists (i.e. class_exists(..., false)) and if not 2) check whether a class file can be loaded for that class. In the Doctrine Common ClassLoader the two responsibilities of loading a class and checking for its existence are separated, which can be observed by the existence of the two methods ``loadClass`` and ``canLoadClass``. Thereby ``loadClass`` does not invoke ``canLoadClass`` internally, by design. However, you are free to use it yourself to check whether a class can be loaded and the following code snippet is thus equivalent to class\_exists(..., true): .. code-block:: php canLoadClass('Foo')) { // ... } The only problem with this is that it is inconvenient as you need to have a reference to the class loaders around (and there are often multiple class loaders in use). Therefore, a simpler alternative exists for the cases in which you really want to ask all installed class loaders whether they can load the class: ``ClassLoader::classExists($className)``: .. code-block:: php ClassLoader is an autoloader for class files that can be * installed on the SPL autoload stack. It is a class loader that either loads only classes * of a specific namespace or all namespaces and it is suitable for working together * with other autoloaders in the SPL autoload stack. * * If no include path is configured through the constructor or {@link setIncludePath}, a ClassLoader * relies on the PHP include_path. * * @author Roman Borschel * @since 2.0 * * @deprecated The ClassLoader is deprecated and will be removed in version 3.0 of doctrine/common. */ class ClassLoader { /** * PHP file extension. * * @var string */ protected $fileExtension = '.php'; /** * Current namespace. * * @var string|null */ protected $namespace; /** * Current include path. * * @var string|null */ protected $includePath; /** * PHP namespace separator. * * @var string */ protected $namespaceSeparator = '\\'; /** * Creates a new ClassLoader that loads classes of the * specified namespace from the specified include path. * * If no include path is given, the ClassLoader relies on the PHP include_path. * If neither a namespace nor an include path is given, the ClassLoader will * be responsible for loading all classes, thereby relying on the PHP include_path. * * @param string|null $ns The namespace of the classes to load. * @param string|null $includePath The base include path to use. */ public function __construct($ns = null, $includePath = null) { $this->namespace = $ns; $this->includePath = $includePath; } /** * Sets the namespace separator used by classes in the namespace of this ClassLoader. * * @param string $sep The separator to use. * * @return void */ public function setNamespaceSeparator($sep) { $this->namespaceSeparator = $sep; } /** * Gets the namespace separator used by classes in the namespace of this ClassLoader. * * @return string */ public function getNamespaceSeparator() { return $this->namespaceSeparator; } /** * Sets the base include path for all class files in the namespace of this ClassLoader. * * @param string|null $includePath * * @return void */ public function setIncludePath($includePath) { $this->includePath = $includePath; } /** * Gets the base include path for all class files in the namespace of this ClassLoader. * * @return string|null */ public function getIncludePath() { return $this->includePath; } /** * Sets the file extension of class files in the namespace of this ClassLoader. * * @param string $fileExtension * * @return void */ public function setFileExtension($fileExtension) { $this->fileExtension = $fileExtension; } /** * Gets the file extension of class files in the namespace of this ClassLoader. * * @return string */ public function getFileExtension() { return $this->fileExtension; } /** * Registers this ClassLoader on the SPL autoload stack. * * @return void */ public function register() { spl_autoload_register([$this, 'loadClass']); } /** * Removes this ClassLoader from the SPL autoload stack. * * @return void */ public function unregister() { spl_autoload_unregister([$this, 'loadClass']); } /** * Loads the given class or interface. * * @param string $className The name of the class to load. * * @return boolean TRUE if the class has been successfully loaded, FALSE otherwise. */ public function loadClass($className) { if (self::typeExists($className)) { return true; } if ( ! $this->canLoadClass($className)) { return false; } require($this->includePath !== null ? $this->includePath . DIRECTORY_SEPARATOR : '') . str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension; return self::typeExists($className); } /** * Asks this ClassLoader whether it can potentially load the class (file) with * the given name. * * @param string $className The fully-qualified name of the class. * * @return boolean TRUE if this ClassLoader can load the class, FALSE otherwise. */ public function canLoadClass($className) { if ($this->namespace !== null && strpos($className, $this->namespace . $this->namespaceSeparator) !== 0) { return false; } $file = str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension; if ($this->includePath !== null) { return is_file($this->includePath . DIRECTORY_SEPARATOR . $file); } return (false !== stream_resolve_include_path($file)); } /** * Checks whether a class with a given name exists. A class "exists" if it is either * already defined in the current request or if there is an autoloader on the SPL * autoload stack that is a) responsible for the class in question and b) is able to * load a class file in which the class definition resides. * * If the class is not already defined, each autoloader in the SPL autoload stack * is asked whether it is able to tell if the class exists. If the autoloader is * a ClassLoader, {@link canLoadClass} is used, otherwise the autoload * function of the autoloader is invoked and expected to return a value that * evaluates to TRUE if the class (file) exists. As soon as one autoloader reports * that the class exists, TRUE is returned. * * Note that, depending on what kinds of autoloaders are installed on the SPL * autoload stack, the class (file) might already be loaded as a result of checking * for its existence. This is not the case with a ClassLoader, who separates * these responsibilities. * * @param string $className The fully-qualified name of the class. * * @return boolean TRUE if the class exists as per the definition given above, FALSE otherwise. */ public static function classExists($className) { return self::typeExists($className, true); } /** * Gets the ClassLoader from the SPL autoload stack that is responsible * for (and is able to load) the class with the given name. * * @param string $className The name of the class. * * @return ClassLoader|null The ClassLoader for the class or NULL if no such ClassLoader exists. */ public static function getClassLoader($className) { foreach (spl_autoload_functions() as $loader) { if (is_array($loader) && ($classLoader = reset($loader)) && $classLoader instanceof ClassLoader && $classLoader->canLoadClass($className) ) { return $classLoader; } } return null; } /** * Checks whether a given type exists * * @param string $type * @param bool $autoload * * @return bool */ private static function typeExists($type, $autoload = false) { return class_exists($type, $autoload) || interface_exists($type, $autoload) || trait_exists($type, $autoload); } } php-doctrine-common-2.12.0/lib/Doctrine/Common/CommonException.php000066400000000000000000000004331360676402100250500ustar00rootroot00000000000000 * @author Guilherme Blanco */ interface Comparable { /** * Compares the current object to the passed $other. * * Returns 0 if they are semantically equal, 1 if the other object * is less than the current one, or -1 if its more than the current one. * * This method should not check for identity using ===, only for semantical equality for example * when two different DateTime instances point to the exact same Date + TZ. * * @param mixed $other * * @return int */ public function compareTo($other); } php-doctrine-common-2.12.0/lib/Doctrine/Common/Lexer.php000066400000000000000000000012731360676402100230230ustar00rootroot00000000000000 * @author Jonathan Wage * @author Roman Borschel * * @deprecated Use Doctrine\Common\Lexer\AbstractLexer from doctrine/lexer package instead. */ abstract class Lexer extends AbstractLexer { } php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/000077500000000000000000000000001360676402100223515ustar00rootroot00000000000000php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php000066400000000000000000000174011360676402100272220ustar00rootroot00000000000000 * * @deprecated The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead. */ abstract class AbstractProxyFactory { /** * Never autogenerate a proxy and rely that it was generated by some * process before deployment. * * @var integer */ const AUTOGENERATE_NEVER = 0; /** * Always generates a new proxy in every request. * * This is only sane during development. * * @var integer */ const AUTOGENERATE_ALWAYS = 1; /** * Autogenerate the proxy class when the proxy file does not exist. * * This strategy causes a file exists call whenever any proxy is used the * first time in a request. * * @var integer */ const AUTOGENERATE_FILE_NOT_EXISTS = 2; /** * Generate the proxy classes using eval(). * * This strategy is only sane for development, and even then it gives me * the creeps a little. * * @var integer */ const AUTOGENERATE_EVAL = 3; private const AUTOGENERATE_MODES = [ self::AUTOGENERATE_NEVER, self::AUTOGENERATE_ALWAYS, self::AUTOGENERATE_FILE_NOT_EXISTS, self::AUTOGENERATE_EVAL, ]; /** * @var \Doctrine\Common\Persistence\Mapping\ClassMetadataFactory */ private $metadataFactory; /** * @var \Doctrine\Common\Proxy\ProxyGenerator the proxy generator responsible for creating the proxy classes/files. */ private $proxyGenerator; /** * @var int Whether to automatically (re)generate proxy classes. */ private $autoGenerate; /** * @var \Doctrine\Common\Proxy\ProxyDefinition[] */ private $definitions = []; /** * @param \Doctrine\Common\Proxy\ProxyGenerator $proxyGenerator * @param \Doctrine\Common\Persistence\Mapping\ClassMetadataFactory $metadataFactory * @param bool|int $autoGenerate * * @throws \Doctrine\Common\Proxy\Exception\InvalidArgumentException When auto generate mode is not valid. */ public function __construct(ProxyGenerator $proxyGenerator, ClassMetadataFactory $metadataFactory, $autoGenerate) { $this->proxyGenerator = $proxyGenerator; $this->metadataFactory = $metadataFactory; $this->autoGenerate = (int) $autoGenerate; if ( ! in_array($this->autoGenerate, self::AUTOGENERATE_MODES, true)) { throw InvalidArgumentException::invalidAutoGenerateMode($autoGenerate); } } /** * Gets a reference proxy instance for the entity of the given type and identified by * the given identifier. * * @param string $className * @param array $identifier * * @return \Doctrine\Common\Proxy\Proxy * * @throws \Doctrine\Common\Proxy\Exception\OutOfBoundsException */ public function getProxy($className, array $identifier) { $definition = isset($this->definitions[$className]) ? $this->definitions[$className] : $this->getProxyDefinition($className); $fqcn = $definition->proxyClassName; $proxy = new $fqcn($definition->initializer, $definition->cloner); foreach ($definition->identifierFields as $idField) { if ( ! isset($identifier[$idField])) { throw OutOfBoundsException::missingPrimaryKeyValue($className, $idField); } $definition->reflectionFields[$idField]->setValue($proxy, $identifier[$idField]); } return $proxy; } /** * Generates proxy classes for all given classes. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata[] $classes The classes (ClassMetadata instances) * for which to generate proxies. * @param string $proxyDir The target directory of the proxy classes. If not specified, the * directory configured on the Configuration of the EntityManager used * by this factory is used. * @return int Number of generated proxies. */ public function generateProxyClasses(array $classes, $proxyDir = null) { $generated = 0; foreach ($classes as $class) { if ($this->skipClass($class)) { continue; } $proxyFileName = $this->proxyGenerator->getProxyFileName($class->getName(), $proxyDir); $this->proxyGenerator->generateProxyClass($class, $proxyFileName); $generated += 1; } return $generated; } /** * Reset initialization/cloning logic for an un-initialized proxy * * @param \Doctrine\Common\Proxy\Proxy $proxy * * @return \Doctrine\Common\Proxy\Proxy * * @throws \Doctrine\Common\Proxy\Exception\InvalidArgumentException */ public function resetUninitializedProxy(Proxy $proxy) { if ($proxy->__isInitialized()) { throw InvalidArgumentException::unitializedProxyExpected($proxy); } $className = ClassUtils::getClass($proxy); $definition = isset($this->definitions[$className]) ? $this->definitions[$className] : $this->getProxyDefinition($className); $proxy->__setInitializer($definition->initializer); $proxy->__setCloner($definition->cloner); return $proxy; } /** * Get a proxy definition for the given class name. * * @param string $className * * @return ProxyDefinition */ private function getProxyDefinition($className) { $classMetadata = $this->metadataFactory->getMetadataFor($className); $className = $classMetadata->getName(); // aliases and case sensitivity $this->definitions[$className] = $this->createProxyDefinition($className); $proxyClassName = $this->definitions[$className]->proxyClassName; if ( ! class_exists($proxyClassName, false)) { $fileName = $this->proxyGenerator->getProxyFileName($className); switch ($this->autoGenerate) { case self::AUTOGENERATE_NEVER: require $fileName; break; case self::AUTOGENERATE_FILE_NOT_EXISTS: if ( ! file_exists($fileName)) { $this->proxyGenerator->generateProxyClass($classMetadata, $fileName); } require $fileName; break; case self::AUTOGENERATE_ALWAYS: $this->proxyGenerator->generateProxyClass($classMetadata, $fileName); require $fileName; break; case self::AUTOGENERATE_EVAL: $this->proxyGenerator->generateProxyClass($classMetadata, false); break; } } return $this->definitions[$className]; } /** * Determine if this class should be skipped during proxy generation. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $metadata * * @return bool */ abstract protected function skipClass(ClassMetadata $metadata); /** * @param string $className * * @return ProxyDefinition */ abstract protected function createProxyDefinition($className); } php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/Autoloader.php000066400000000000000000000052361360676402100251670ustar00rootroot00000000000000 * * @internal * * @deprecated The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead. */ class Autoloader { /** * Resolves proxy class name to a filename based on the following pattern. * * 1. Remove Proxy namespace from class name. * 2. Remove namespace separators from remaining class name. * 3. Return PHP filename from proxy-dir with the result from 2. * * @param string $proxyDir * @param string $proxyNamespace * @param string $className * * @return string * * @throws InvalidArgumentException */ public static function resolveFile($proxyDir, $proxyNamespace, $className) { if (0 !== strpos($className, $proxyNamespace)) { throw InvalidArgumentException::notProxyClass($className, $proxyNamespace); } // remove proxy namespace from class name $classNameRelativeToProxyNamespace = substr($className, strlen($proxyNamespace)); // remove namespace separators from remaining class name $fileName = str_replace('\\', '', $classNameRelativeToProxyNamespace); return $proxyDir . DIRECTORY_SEPARATOR . $fileName . '.php'; } /** * Registers and returns autoloader callback for the given proxy dir and namespace. * * @param string $proxyDir * @param string $proxyNamespace * @param callable|null $notFoundCallback Invoked when the proxy file is not found. * * @return \Closure * * @throws InvalidArgumentException */ public static function register($proxyDir, $proxyNamespace, $notFoundCallback = null) { $proxyNamespace = ltrim($proxyNamespace, '\\'); if ( ! (null === $notFoundCallback || is_callable($notFoundCallback))) { throw InvalidArgumentException::invalidClassNotFoundCallback($notFoundCallback); } $autoloader = function ($className) use ($proxyDir, $proxyNamespace, $notFoundCallback) { if (0 === strpos($className, $proxyNamespace)) { $file = Autoloader::resolveFile($proxyDir, $proxyNamespace, $className); if ($notFoundCallback && ! file_exists($file)) { call_user_func($notFoundCallback, $proxyDir, $proxyNamespace, $className); } require $file; } }; spl_autoload_register($autoloader); return $autoloader; } } php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/Exception/000077500000000000000000000000001360676402100243075ustar00rootroot00000000000000php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/Exception/InvalidArgumentException.php000066400000000000000000000053131360676402100317720ustar00rootroot00000000000000 * * @deprecated The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead. */ class InvalidArgumentException extends BaseInvalidArgumentException implements ProxyException { /** * @return self */ public static function proxyDirectoryRequired() { return new self('You must configure a proxy directory. See docs for details'); } /** * @param string $className * @param string $proxyNamespace * * @return self */ public static function notProxyClass($className, $proxyNamespace) { return new self(sprintf('The class "%s" is not part of the proxy namespace "%s"', $className, $proxyNamespace)); } /** * @param string $name * * @return self */ public static function invalidPlaceholder($name) { return new self(sprintf('Provided placeholder for "%s" must be either a string or a valid callable', $name)); } /** * @return self */ public static function proxyNamespaceRequired() { return new self('You must configure a proxy namespace'); } /** * @param Proxy $proxy * * @return self */ public static function unitializedProxyExpected(Proxy $proxy) { return new self(sprintf('Provided proxy of type "%s" must not be initialized.', get_class($proxy))); } /** * @param mixed $callback * * @return self */ public static function invalidClassNotFoundCallback($callback) { $type = is_object($callback) ? get_class($callback) : gettype($callback); return new self(sprintf('Invalid \$notFoundCallback given: must be a callable, "%s" given', $type)); } /** * @param string $className * * @return self */ public static function classMustNotBeAbstract($className) { return new self(sprintf('Unable to create a proxy for an abstract class "%s".', $className)); } /** * @param string $className * * @return self */ public static function classMustNotBeFinal($className) { return new self(sprintf('Unable to create a proxy for a final class "%s".', $className)); } /** * @param mixed $value * * @return self */ public static function invalidAutoGenerateMode($value) : self { return new self(sprintf('Invalid auto generate mode "%s" given.', $value)); } } php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/Exception/OutOfBoundsException.php000066400000000000000000000013421360676402100311060ustar00rootroot00000000000000 * * @deprecated The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead. */ class OutOfBoundsException extends BaseOutOfBoundsException implements ProxyException { /** * @param string $className * @param string $idField * * @return self */ public static function missingPrimaryKeyValue($className, $idField) { return new self(sprintf("Missing value for primary key %s on %s", $idField, $className)); } } php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/Exception/ProxyException.php000066400000000000000000000005351360676402100300230ustar00rootroot00000000000000 * * @deprecated The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead. */ interface ProxyException { } php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/Exception/UnexpectedValueException.php000066400000000000000000000035551360676402100320100ustar00rootroot00000000000000 * * @deprecated The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead. */ class UnexpectedValueException extends BaseUnexpectedValueException implements ProxyException { /** * @param string $proxyDirectory * * @return self */ public static function proxyDirectoryNotWritable($proxyDirectory) { return new self(sprintf('Your proxy directory "%s" must be writable', $proxyDirectory)); } /** * @param string $className * @param string $methodName * @param string $parameterName * @param \Exception|null $previous * * @return self */ public static function invalidParameterTypeHint( $className, $methodName, $parameterName, \Exception $previous = null ) { return new self( sprintf( 'The type hint of parameter "%s" in method "%s" in class "%s" is invalid.', $parameterName, $methodName, $className ), 0, $previous ); } /** * @param string $className * @param string $methodName * @param \Exception|null $previous * * @return self */ public static function invalidReturnTypeHint($className, $methodName, \Exception $previous = null) { return new self( sprintf( 'The return type of method "%s" in class "%s" is invalid.', $methodName, $className ), 0, $previous ); } } php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/Proxy.php000066400000000000000000000037571360676402100242170ustar00rootroot00000000000000 * @author Marco Pivetta * @since 2.4 * * @deprecated The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead. */ interface Proxy extends BaseProxy { /** * Marks the proxy as initialized or not. * * @param boolean $initialized * * @return void */ public function __setInitialized($initialized); /** * Sets the initializer callback to be used when initializing the proxy. That * initializer should accept 3 parameters: $proxy, $method and $params. Those * are respectively the proxy object that is being initialized, the method name * that triggered initialization and the parameters passed to that method. * * @param Closure|null $initializer * * @return void */ public function __setInitializer(Closure $initializer = null); /** * Retrieves the initializer callback used to initialize the proxy. * * @see __setInitializer * * @return Closure|null */ public function __getInitializer(); /** * Sets the callback to be used when cloning the proxy. That initializer should accept * a single parameter, which is the cloned proxy instance itself. * * @param Closure|null $cloner * * @return void */ public function __setCloner(Closure $cloner = null); /** * Retrieves the callback to be used when cloning the proxy. * * @see __setCloner * * @return Closure|null */ public function __getCloner(); /** * Retrieves the list of lazy loaded properties for a given proxy * * @return array Keys are the property names, and values are the default values * for those properties. */ public function __getLazyProperties(); } php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/ProxyDefinition.php000066400000000000000000000022631360676402100262170ustar00rootroot00000000000000 * * @deprecated The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead. */ class ProxyDefinition { /** * @var string */ public $proxyClassName; /** * @var array */ public $identifierFields; /** * @var \ReflectionProperty[] */ public $reflectionFields; /** * @var callable */ public $initializer; /** * @var callable */ public $cloner; /** * @param string $proxyClassName * @param array $identifierFields * @param array $reflectionFields * @param callable $initializer * @param callable $cloner */ public function __construct($proxyClassName, array $identifierFields, array $reflectionFields, $initializer, $cloner) { $this->proxyClassName = $proxyClassName; $this->identifierFields = $identifierFields; $this->reflectionFields = $reflectionFields; $this->initializer = $initializer; $this->cloner = $cloner; } } php-doctrine-common-2.12.0/lib/Doctrine/Common/Proxy/ProxyGenerator.php000066400000000000000000001007321360676402100260550ustar00rootroot00000000000000 * @since 2.4 * * @deprecated The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead. */ class ProxyGenerator { /** * Used to match very simple id methods that don't need * to be decorated since the identifier is known. */ const PATTERN_MATCH_ID_METHOD = '((public\s+)?(function\s+%s\s*\(\)\s*)\s*(?::\s*\??\s*\\\\?[a-z_\x7f-\xff][\w\x7f-\xff]*(?:\\\\[a-z_\x7f-\xff][\w\x7f-\xff]*)*\s*)?{\s*return\s*\$this->%s;\s*})i'; /** * The namespace that contains all proxy classes. * * @var string */ private $proxyNamespace; /** * The directory that contains all proxy classes. * * @var string */ private $proxyDirectory; /** * Map of callables used to fill in placeholders set in the template. * * @var string[]|callable[] */ protected $placeholders = [ 'baseProxyInterface' => Proxy::class, 'additionalProperties' => '', ]; /** * Template used as a blueprint to generate proxies. * * @var string */ protected $proxyClassTemplate = '; /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE\'S PROXY GENERATOR */ class extends \ implements \ { /** * @var \Closure the callback responsible for loading properties in the proxy object. This callback is called with * three parameters, being respectively the proxy object to be initialized, the method that triggered the * initialization process and an array of ordered parameters that were passed to that method. * * @see \Doctrine\Common\Proxy\Proxy::__setInitializer */ public $__initializer__; /** * @var \Closure the callback responsible of loading properties that need to be copied in the cloned object * * @see \Doctrine\Common\Proxy\Proxy::__setCloner */ public $__cloner__; /** * @var boolean flag indicating if this object was already initialized * * @see \Doctrine\Common\Persistence\Proxy::__isInitialized */ public $__isInitialized__ = false; /** * @var array properties to be lazy loaded, indexed by property name */ public static $lazyPropertiesNames = ; /** * @var array default values of properties to be lazy loaded, with keys being the property names * * @see \Doctrine\Common\Proxy\Proxy::__getLazyProperties */ public static $lazyPropertiesDefaults = ; /** * Forces initialization of the proxy */ public function __load() { $this->__initializer__ && $this->__initializer__->__invoke($this, \'__load\', []); } /** * {@inheritDoc} * @internal generated method: use only when explicitly handling proxy specific loading logic */ public function __isInitialized() { return $this->__isInitialized__; } /** * {@inheritDoc} * @internal generated method: use only when explicitly handling proxy specific loading logic */ public function __setInitialized($initialized) { $this->__isInitialized__ = $initialized; } /** * {@inheritDoc} * @internal generated method: use only when explicitly handling proxy specific loading logic */ public function __setInitializer(\Closure $initializer = null) { $this->__initializer__ = $initializer; } /** * {@inheritDoc} * @internal generated method: use only when explicitly handling proxy specific loading logic */ public function __getInitializer() { return $this->__initializer__; } /** * {@inheritDoc} * @internal generated method: use only when explicitly handling proxy specific loading logic */ public function __setCloner(\Closure $cloner = null) { $this->__cloner__ = $cloner; } /** * {@inheritDoc} * @internal generated method: use only when explicitly handling proxy specific cloning logic */ public function __getCloner() { return $this->__cloner__; } /** * {@inheritDoc} * @internal generated method: use only when explicitly handling proxy specific loading logic * @deprecated no longer in use - generated code now relies on internal components rather than generated public API * @static */ public function __getLazyProperties() { return self::$lazyPropertiesDefaults; } } '; /** * Initializes a new instance of the ProxyFactory class that is * connected to the given EntityManager. * * @param string $proxyDirectory The directory to use for the proxy classes. It must exist. * @param string $proxyNamespace The namespace to use for the proxy classes. * * @throws InvalidArgumentException */ public function __construct($proxyDirectory, $proxyNamespace) { if ( ! $proxyDirectory) { throw InvalidArgumentException::proxyDirectoryRequired(); } if ( ! $proxyNamespace) { throw InvalidArgumentException::proxyNamespaceRequired(); } $this->proxyDirectory = $proxyDirectory; $this->proxyNamespace = $proxyNamespace; } /** * Sets a placeholder to be replaced in the template. * * @param string $name * @param string|callable $placeholder * * @throws InvalidArgumentException */ public function setPlaceholder($name, $placeholder) { if ( ! is_string($placeholder) && ! is_callable($placeholder)) { throw InvalidArgumentException::invalidPlaceholder($name); } $this->placeholders[$name] = $placeholder; } /** * Sets the base template used to create proxy classes. * * @param string $proxyClassTemplate */ public function setProxyClassTemplate($proxyClassTemplate) { $this->proxyClassTemplate = (string) $proxyClassTemplate; } /** * Generates a proxy class file. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class Metadata for the original class. * @param string|bool $fileName Filename (full path) for the generated class. If none is given, eval() is used. * * @throws InvalidArgumentException * @throws UnexpectedValueException */ public function generateProxyClass(ClassMetadata $class, $fileName = false) { $this->verifyClassCanBeProxied($class); preg_match_all('(<([a-zA-Z]+)>)', $this->proxyClassTemplate, $placeholderMatches); $placeholderMatches = array_combine($placeholderMatches[0], $placeholderMatches[1]); $placeholders = []; foreach ($placeholderMatches as $placeholder => $name) { $placeholders[$placeholder] = isset($this->placeholders[$name]) ? $this->placeholders[$name] : [$this, 'generate' . $name]; } foreach ($placeholders as & $placeholder) { if (is_callable($placeholder)) { $placeholder = call_user_func($placeholder, $class); } } $proxyCode = strtr($this->proxyClassTemplate, $placeholders); if ( ! $fileName) { $proxyClassName = $this->generateNamespace($class) . '\\' . $this->generateProxyShortClassName($class); if ( ! class_exists($proxyClassName)) { eval(substr($proxyCode, 5)); } return; } $parentDirectory = dirname($fileName); if ( ! is_dir($parentDirectory) && (false === @mkdir($parentDirectory, 0775, true))) { throw UnexpectedValueException::proxyDirectoryNotWritable($this->proxyDirectory); } if ( ! is_writable($parentDirectory)) { throw UnexpectedValueException::proxyDirectoryNotWritable($this->proxyDirectory); } $tmpFileName = $fileName . '.' . uniqid('', true); file_put_contents($tmpFileName, $proxyCode); @chmod($tmpFileName, 0664); rename($tmpFileName, $fileName); } /** * @param ClassMetadata $class * * @throws InvalidArgumentException */ private function verifyClassCanBeProxied(ClassMetadata $class) { if ($class->getReflectionClass()->isFinal()) { throw InvalidArgumentException::classMustNotBeFinal($class->getName()); } if ($class->getReflectionClass()->isAbstract()) { throw InvalidArgumentException::classMustNotBeAbstract($class->getName()); } } /** * Generates the proxy short class name to be used in the template. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateProxyShortClassName(ClassMetadata $class) { $proxyClassName = ClassUtils::generateProxyClassName($class->getName(), $this->proxyNamespace); $parts = explode('\\', strrev($proxyClassName), 2); return strrev($parts[0]); } /** * Generates the proxy namespace. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateNamespace(ClassMetadata $class) { $proxyClassName = ClassUtils::generateProxyClassName($class->getName(), $this->proxyNamespace); $parts = explode('\\', strrev($proxyClassName), 2); return strrev($parts[1]); } /** * Generates the original class name. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateClassName(ClassMetadata $class) { return ltrim($class->getName(), '\\'); } /** * Generates the array representation of lazy loaded public properties and their default values. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateLazyPropertiesNames(ClassMetadata $class) { $lazyPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class); $values = []; foreach ($lazyPublicProperties as $name) { $values[$name] = null; } return var_export($values, true); } /** * Generates the array representation of lazy loaded public properties names. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateLazyPropertiesDefaults(ClassMetadata $class) { return var_export($this->getLazyLoadedPublicProperties($class), true); } /** * Generates the constructor code (un-setting public lazy loaded properties, setting identifier field values). * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateConstructorImpl(ClassMetadata $class) { $constructorImpl = <<<'EOT' public function __construct(?\Closure $initializer = null, ?\Closure $cloner = null) { EOT; $toUnset = array_map(static function (string $name) : string { return '$this->' . $name; }, $this->getLazyLoadedPublicPropertiesNames($class)); $constructorImpl .= ($toUnset === [] ? '' : ' unset(' . implode(', ', $toUnset) . ");\n") . <<<'EOT' $this->__initializer__ = $initializer; $this->__cloner__ = $cloner; } EOT; return $constructorImpl; } /** * Generates the magic getter invoked when lazy loaded public properties are requested. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateMagicGet(ClassMetadata $class) { $lazyPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class); $reflectionClass = $class->getReflectionClass(); $hasParentGet = false; $returnReference = ''; $inheritDoc = ''; if ($reflectionClass->hasMethod('__get')) { $hasParentGet = true; $inheritDoc = '{@inheritDoc}'; if ($reflectionClass->getMethod('__get')->returnsReference()) { $returnReference = '& '; } } if (empty($lazyPublicProperties) && ! $hasParentGet) { return ''; } $magicGet = <<__initializer__ && $this->__initializer__->__invoke($this, '__get', [$name]); return $this->$name; } EOT; } if ($hasParentGet) { $magicGet .= <<<'EOT' $this->__initializer__ && $this->__initializer__->__invoke($this, '__get', [$name]); return parent::__get($name); EOT; } else { $magicGet .= <<<'EOT' trigger_error(sprintf('Undefined property: %s::$%s', __CLASS__, $name), E_USER_NOTICE); EOT; } $magicGet .= " }"; return $magicGet; } /** * Generates the magic setter (currently unused). * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateMagicSet(ClassMetadata $class) { $lazyPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class); $hasParentSet = $class->getReflectionClass()->hasMethod('__set'); if (empty($lazyPublicProperties) && ! $hasParentSet) { return ''; } $inheritDoc = $hasParentSet ? '{@inheritDoc}' : ''; $magicSet = <<__initializer__ && $this->__initializer__->__invoke($this, '__set', [$name, $value]); $this->$name = $value; return; } EOT; } if ($hasParentSet) { $magicSet .= <<<'EOT' $this->__initializer__ && $this->__initializer__->__invoke($this, '__set', [$name, $value]); return parent::__set($name, $value); EOT; } else { $magicSet .= " \$this->\$name = \$value;"; } $magicSet .= "\n }"; return $magicSet; } /** * Generates the magic issetter invoked when lazy loaded public properties are checked against isset(). * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateMagicIsset(ClassMetadata $class) { $lazyPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class); $hasParentIsset = $class->getReflectionClass()->hasMethod('__isset'); if (empty($lazyPublicProperties) && ! $hasParentIsset) { return ''; } $inheritDoc = $hasParentIsset ? '{@inheritDoc}' : ''; $magicIsset = <<__initializer__ && $this->__initializer__->__invoke($this, '__isset', [$name]); return isset($this->$name); } EOT; } if ($hasParentIsset) { $magicIsset .= <<<'EOT' $this->__initializer__ && $this->__initializer__->__invoke($this, '__isset', [$name]); return parent::__isset($name); EOT; } else { $magicIsset .= " return false;"; } return $magicIsset . "\n }"; } /** * Generates implementation for the `__sleep` method of proxies. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateSleepImpl(ClassMetadata $class) { $hasParentSleep = $class->getReflectionClass()->hasMethod('__sleep'); $inheritDoc = $hasParentSleep ? '{@inheritDoc}' : ''; $sleepImpl = <<__isInitialized__) { $properties = array_diff($properties, array_keys(self::$lazyPropertiesNames)); } return $properties; } EOT; } $allProperties = ['__isInitialized__']; /* @var $prop \ReflectionProperty */ foreach ($class->getReflectionClass()->getProperties() as $prop) { if ($prop->isStatic()) { continue; } $allProperties[] = $prop->isPrivate() ? "\0" . $prop->getDeclaringClass()->getName() . "\0" . $prop->getName() : $prop->getName(); } $lazyPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class); $protectedProperties = array_diff($allProperties, $lazyPublicProperties); foreach ($allProperties as &$property) { $property = var_export($property, true); } foreach ($protectedProperties as &$property) { $property = var_export($property, true); } $allProperties = implode(', ', $allProperties); $protectedProperties = implode(', ', $protectedProperties); return $sleepImpl . <<__isInitialized__) { return [$allProperties]; } return [$protectedProperties]; } EOT; } /** * Generates implementation for the `__wakeup` method of proxies. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateWakeupImpl(ClassMetadata $class) { $unsetPublicProperties = []; $hasWakeup = $class->getReflectionClass()->hasMethod('__wakeup'); foreach ($this->getLazyLoadedPublicPropertiesNames($class) as $lazyPublicProperty) { $unsetPublicProperties[] = '$this->' . $lazyPublicProperty; } $shortName = $this->generateProxyShortClassName($class); $inheritDoc = $hasWakeup ? '{@inheritDoc}' : ''; $wakeupImpl = <<__isInitialized__) { \$this->__initializer__ = function ($shortName \$proxy) { \$proxy->__setInitializer(null); \$proxy->__setCloner(null); \$existingProperties = get_object_vars(\$proxy); foreach (\$proxy::\$lazyPropertiesDefaults as \$property => \$defaultValue) { if ( ! array_key_exists(\$property, \$existingProperties)) { \$proxy->\$property = \$defaultValue; } } }; EOT; if ( ! empty($unsetPublicProperties)) { $wakeupImpl .= "\n unset(" . implode(', ', $unsetPublicProperties) . ");"; } $wakeupImpl .= "\n }"; if ($hasWakeup) { $wakeupImpl .= "\n parent::__wakeup();"; } $wakeupImpl .= "\n }"; return $wakeupImpl; } /** * Generates implementation for the `__clone` method of proxies. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateCloneImpl(ClassMetadata $class) { $hasParentClone = $class->getReflectionClass()->hasMethod('__clone'); $inheritDoc = $hasParentClone ? '{@inheritDoc}' : ''; $callParentClone = $hasParentClone ? "\n parent::__clone();\n" : ''; return <<__cloner__ && \$this->__cloner__->__invoke(\$this, '__clone', []); $callParentClone } EOT; } /** * Generates decorated methods by picking those available in the parent class. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return string */ private function generateMethods(ClassMetadata $class) { $methods = ''; $methodNames = []; $reflectionMethods = $class->getReflectionClass()->getMethods(\ReflectionMethod::IS_PUBLIC); $skippedMethods = [ '__sleep' => true, '__clone' => true, '__wakeup' => true, '__get' => true, '__set' => true, '__isset' => true, ]; foreach ($reflectionMethods as $method) { $name = $method->getName(); if ($method->isConstructor() || isset($skippedMethods[strtolower($name)]) || isset($methodNames[$name]) || $method->isFinal() || $method->isStatic() || ( ! $method->isPublic()) ) { continue; } $methodNames[$name] = true; $methods .= "\n /**\n" . " * {@inheritDoc}\n" . " */\n" . ' public function '; if ($method->returnsReference()) { $methods .= '&'; } $methods .= $name . '(' . $this->buildParametersString($method->getParameters()) . ')'; $methods .= $this->getMethodReturnType($method); $methods .= "\n" . ' {' . "\n"; if ($this->isShortIdentifierGetter($method, $class)) { $identifier = lcfirst(substr($name, 3)); $fieldType = $class->getTypeOfField($identifier); $cast = in_array($fieldType, ['integer', 'smallint']) ? '(int) ' : ''; $methods .= ' if ($this->__isInitialized__ === false) {' . "\n"; $methods .= ' '; $methods .= $this->shouldProxiedMethodReturn($method) ? 'return ' : ''; $methods .= $cast . ' parent::' . $method->getName() . "();\n"; $methods .= ' }' . "\n\n"; } $invokeParamsString = implode(', ', $this->getParameterNamesForInvoke($method->getParameters())); $callParamsString = implode(', ', $this->getParameterNamesForParentCall($method->getParameters())); $methods .= "\n \$this->__initializer__ " . "&& \$this->__initializer__->__invoke(\$this, " . var_export($name, true) . ", [" . $invokeParamsString . "]);" . "\n\n " . ($this->shouldProxiedMethodReturn($method) ? 'return ' : '') . "parent::" . $name . '(' . $callParamsString . ');' . "\n" . ' }' . "\n"; } return $methods; } /** * Generates the Proxy file name. * * @param string $className * @param string $baseDirectory Optional base directory for proxy file name generation. * If not specified, the directory configured on the Configuration of the * EntityManager will be used by this factory. * * @return string */ public function getProxyFileName($className, $baseDirectory = null) { $baseDirectory = $baseDirectory ?: $this->proxyDirectory; return rtrim($baseDirectory, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . Proxy::MARKER . str_replace('\\', '', $className) . '.php'; } /** * Checks if the method is a short identifier getter. * * What does this mean? For proxy objects the identifier is already known, * however accessing the getter for this identifier usually triggers the * lazy loading, leading to a query that may not be necessary if only the * ID is interesting for the userland code (for example in views that * generate links to the entity, but do not display anything else). * * @param \ReflectionMethod $method * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return boolean */ private function isShortIdentifierGetter($method, ClassMetadata $class) { $identifier = lcfirst(substr($method->getName(), 3)); $startLine = $method->getStartLine(); $endLine = $method->getEndLine(); $cheapCheck = ( $method->getNumberOfParameters() == 0 && substr($method->getName(), 0, 3) == 'get' && in_array($identifier, $class->getIdentifier(), true) && $class->hasField($identifier) && (($endLine - $startLine) <= 4) ); if ($cheapCheck) { $code = file($method->getFileName()); $code = trim(implode(' ', array_slice($code, $startLine - 1, $endLine - $startLine + 1))); $pattern = sprintf(self::PATTERN_MATCH_ID_METHOD, $method->getName(), $identifier); if (preg_match($pattern, $code)) { return true; } } return false; } /** * Generates the list of public properties to be lazy loaded. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return array */ private function getLazyLoadedPublicPropertiesNames(ClassMetadata $class) : array { $properties = []; foreach ($class->getReflectionClass()->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { $name = $property->getName(); if (($class->hasField($name) || $class->hasAssociation($name)) && ! $class->isIdentifier($name)) { $properties[] = $name; } } return $properties; } /** * Generates the list of default values of public properties. * * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return mixed[] */ private function getLazyLoadedPublicProperties(ClassMetadata $class) { $defaultProperties = $class->getReflectionClass()->getDefaultProperties(); $lazyLoadedPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class); $defaultValues = []; foreach ($class->getReflectionClass()->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { $name = $property->getName(); if ( ! in_array($name, $lazyLoadedPublicProperties, true)) { continue; } if (array_key_exists($name, $defaultProperties)) { $defaultValues[$name] = $defaultProperties[$name]; } elseif (method_exists($property, 'getType')) { $propertyType = $property->getType(); if (null !== $propertyType && $propertyType->allowsNull()) { $defaultValues[$name] = null; } } } return $defaultValues; } /** * @param \ReflectionParameter[] $parameters * * @return string */ private function buildParametersString(array $parameters) { $parameterDefinitions = []; /* @var $param \ReflectionParameter */ foreach ($parameters as $param) { $parameterDefinition = ''; if ($parameterType = $this->getParameterType($param)) { $parameterDefinition .= $parameterType . ' '; } if ($param->isPassedByReference()) { $parameterDefinition .= '&'; } if ($param->isVariadic()) { $parameterDefinition .= '...'; } $parameterDefinition .= '$' . $param->getName(); if ($param->isDefaultValueAvailable()) { $parameterDefinition .= ' = ' . var_export($param->getDefaultValue(), true); } $parameterDefinitions[] = $parameterDefinition; } return implode(', ', $parameterDefinitions); } /** * @param \ReflectionParameter $parameter * * @return string|null */ private function getParameterType(\ReflectionParameter $parameter) { if ( ! $parameter->hasType()) { return null; } return $this->formatType($parameter->getType(), $parameter->getDeclaringFunction(), $parameter); } /** * @param \ReflectionParameter[] $parameters * * @return string[] */ private function getParameterNamesForInvoke(array $parameters) { return array_map( function (\ReflectionParameter $parameter) { return '$' . $parameter->getName(); }, $parameters ); } /** * @param \ReflectionParameter[] $parameters * * @return string[] */ private function getParameterNamesForParentCall(array $parameters) { return array_map( function (\ReflectionParameter $parameter) { $name = ''; if ($parameter->isVariadic()) { $name .= '...'; } $name .= '$' . $parameter->getName(); return $name; }, $parameters ); } /** * @param \ReflectionMethod $method * * @return string */ private function getMethodReturnType(\ReflectionMethod $method) { if ( ! $method->hasReturnType()) { return ''; } return ': ' . $this->formatType($method->getReturnType(), $method); } /** * @param \ReflectionMethod $method * * @return bool */ private function shouldProxiedMethodReturn(\ReflectionMethod $method) { if ( ! $method->hasReturnType()) { return true; } return 'void' !== strtolower($this->formatType($method->getReturnType(), $method)); } /** * @param \ReflectionType $type * @param \ReflectionMethod $method * @param \ReflectionParameter|null $parameter * * @return string */ private function formatType( \ReflectionType $type, \ReflectionMethod $method, \ReflectionParameter $parameter = null ) { $name = $type->getName(); $nameLower = strtolower($name); if ('self' === $nameLower) { $name = $method->getDeclaringClass()->getName(); } if ('parent' === $nameLower) { $name = $method->getDeclaringClass()->getParentClass()->getName(); } if ( ! $type->isBuiltin() && ! class_exists($name) && ! interface_exists($name)) { if (null !== $parameter) { throw UnexpectedValueException::invalidParameterTypeHint( $method->getDeclaringClass()->getName(), $method->getName(), $parameter->getName() ); } throw UnexpectedValueException::invalidReturnTypeHint( $method->getDeclaringClass()->getName(), $method->getName() ); } if ( ! $type->isBuiltin()) { $name = '\\' . $name; } if ($type->allowsNull() && (null === $parameter || ! $parameter->isDefaultValueAvailable() || null !== $parameter->getDefaultValue()) ) { $name = '?' . $name; } return $name; } } php-doctrine-common-2.12.0/lib/Doctrine/Common/Util/000077500000000000000000000000001360676402100221455ustar00rootroot00000000000000php-doctrine-common-2.12.0/lib/Doctrine/Common/Util/ClassUtils.php000066400000000000000000000042531360676402100247500ustar00rootroot00000000000000 * @author Johannes Schmitt * * @deprecated The ClassUtils class is deprecated. */ class ClassUtils { /** * Gets the real class name of a class name that could be a proxy. * * @param string $class * * @return string */ public static function getRealClass($class) { if (false === $pos = strrpos($class, '\\' . Proxy::MARKER . '\\')) { return $class; } return substr($class, $pos + Proxy::MARKER_LENGTH + 2); } /** * Gets the real class name of an object (even if its a proxy). * * @param object $object * * @return string */ public static function getClass($object) { return self::getRealClass(get_class($object)); } /** * Gets the real parent class name of a class or object. * * @param string $className * * @return string */ public static function getParentClass($className) { return get_parent_class(self::getRealClass($className)); } /** * Creates a new reflection class. * * @param string $class * * @return \ReflectionClass */ public static function newReflectionClass($class) { return new \ReflectionClass(self::getRealClass($class)); } /** * Creates a new reflection object. * * @param object $object * * @return \ReflectionClass */ public static function newReflectionObject($object) { return self::newReflectionClass(self::getClass($object)); } /** * Given a class name and a proxy namespace returns the proxy name. * * @param string $className * @param string $proxyNamespace * * @return string */ public static function generateProxyClassName($className, $proxyNamespace) { return rtrim($proxyNamespace, '\\') . '\\' . Proxy::MARKER . '\\' . ltrim($className, '\\'); } } php-doctrine-common-2.12.0/lib/Doctrine/Common/Util/Debug.php000066400000000000000000000106111360676402100237030ustar00rootroot00000000000000 * @author Jonathan Wage * @author Roman Borschel * @author Giorgio Sironi * * @deprecated The Debug class is deprecated, please use symfony/var-dumper instead. */ final class Debug { /** * Private constructor (prevents instantiation). */ private function __construct() { } /** * Prints a dump of the public, protected and private properties of $var. * * @link https://xdebug.org/ * * @param mixed $var The variable to dump. * @param integer $maxDepth The maximum nesting level for object properties. * @param boolean $stripTags Whether output should strip HTML tags. * @param boolean $echo Send the dumped value to the output buffer * * @return string */ public static function dump($var, $maxDepth = 2, $stripTags = true, $echo = true) { $html = ini_get('html_errors'); if ($html !== true) { ini_set('html_errors', true); } if (extension_loaded('xdebug')) { ini_set('xdebug.var_display_max_depth', $maxDepth); } $var = self::export($var, $maxDepth); ob_start(); var_dump($var); $dump = ob_get_contents(); ob_end_clean(); $dumpText = ($stripTags ? strip_tags(html_entity_decode($dump)) : $dump); ini_set('html_errors', $html); if ($echo) { echo $dumpText; } return $dumpText; } /** * @param mixed $var * @param int $maxDepth * * @return mixed */ public static function export($var, $maxDepth) { $return = null; $isObj = is_object($var); if ($var instanceof Collection) { $var = $var->toArray(); } if ( ! $maxDepth) { return is_object($var) ? get_class($var) : (is_array($var) ? 'Array(' . count($var) . ')' : $var); } if (is_array($var)) { $return = []; foreach ($var as $k => $v) { $return[$k] = self::export($v, $maxDepth - 1); } return $return; } if ( ! $isObj) { return $var; } $return = new \stdClass(); if ($var instanceof \DateTimeInterface) { $return->__CLASS__ = get_class($var); $return->date = $var->format('c'); $return->timezone = $var->getTimezone()->getName(); return $return; } $return->__CLASS__ = ClassUtils::getClass($var); if ($var instanceof Proxy) { $return->__IS_PROXY__ = true; $return->__PROXY_INITIALIZED__ = $var->__isInitialized(); } if ($var instanceof \ArrayObject || $var instanceof \ArrayIterator) { $return->__STORAGE__ = self::export($var->getArrayCopy(), $maxDepth - 1); } return self::fillReturnWithClassAttributes($var, $return, $maxDepth); } /** * Fill the $return variable with class attributes * Based on obj2array function from {@see https://secure.php.net/manual/en/function.get-object-vars.php#47075} * * @param object $var * @param \stdClass $return * @param int $maxDepth * * @return mixed */ private static function fillReturnWithClassAttributes($var, \stdClass $return, $maxDepth) { $clone = (array) $var; foreach (array_keys($clone) as $key) { $aux = explode("\0", $key); $name = end($aux); if ($aux[0] === '') { $name .= ':' . ($aux[1] === '*' ? 'protected' : $aux[1] . ':private'); } $return->$name = self::export($clone[$key], $maxDepth - 1); ; } return $return; } /** * Returns a string representation of an object. * * @param object $obj * * @return string */ public static function toString($obj) { return method_exists($obj, '__toString') ? (string) $obj : get_class($obj) . '@' . spl_object_hash($obj); } } php-doctrine-common-2.12.0/lib/Doctrine/Common/Util/Inflector.php000066400000000000000000000010531360676402100246020ustar00rootroot00000000000000 * @author Guilherme Blanco * @author Jonathan Wage * @author Roman Borschel * * @deprecated The Version class is deprecated, please refrain from checking the version of doctrine/common. */ class Version { /** * Current Doctrine Version. */ const VERSION = '2.12.0-DEV'; /** * Compares a Doctrine version with the current one. * * @param string $version Doctrine version to compare. * * @return int -1 if older, 0 if it is the same, 1 if version passed as argument is newer. */ public static function compare($version) { $currentVersion = str_replace(' ', '', strtolower(self::VERSION)); $version = str_replace(' ', '', $version); return version_compare($version, $currentVersion); } } php-doctrine-common-2.12.0/phpcs.xml.dist000066400000000000000000000021351360676402100202650ustar00rootroot00000000000000 lib tests */tests/* tests/Doctrine/Tests/Common/ClassLoaderTest/*.class.php tests/Doctrine/Tests/Common/Util/ClassUtilsTest.php tests/Doctrine/Tests/Common/ClassLoaderTest/*.class.php tests/Doctrine/Tests/Common/Proxy/*HintClass.php php-doctrine-common-2.12.0/phpstan.neon.dist000066400000000000000000000051361360676402100207700ustar00rootroot00000000000000parameters: level: 3 paths: - %currentWorkingDirectory%/lib - %currentWorkingDirectory%/tests autoload_directories: - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/ClassLoaderTest excludes_analyse: - %currentWorkingDirectory%/lib/vendor/doctrine-build-common - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/InvalidReturnTypeClass.php - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/InvalidTypeHintClass.php - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/SerializedClass.php - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/VariadicTypeHintClass.php - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/ProxyLogicTypedPropertiesTest.php - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/LazyLoadableObjectWithTypedProperties.php ignoreErrors: - '#Access to an undefined property Doctrine\\Common\\Proxy\\Proxy::\$publicField#' - message: '#^Result of method Doctrine\\Tests\\Common\\Proxy\\LazyLoadableObjectWithVoid::(adding|incrementing)AndReturningVoid\(\) \(void\) is used\.$#' path: '%currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/ProxyLogicVoidReturnTypeTest.php' - message: '#^Property Doctrine\\Tests\\Common\\Proxy\\ProxyLogicTest::\$initializerCallbackMock \(callable&PHPUnit\\Framework\\MockObject\\MockObject\) does not accept PHPUnit\\Framework\\MockObject\\MockObject&stdClass\.$#' path: '%currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/ProxyLogicTest.php' - message: '#^Call to an undefined method PHPUnit\\Framework\\MockObject\\MockObject(&stdClass)?::(load|getName)\(\)\.$#' path: '%currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/ProxyLogicTest.php' - message: '#^Access to an undefined property Doctrine\\Common\\Proxy\\Proxy&Doctrine\\Tests\\Common\\Proxy\\LazyLoadableObject::\$non_existing_property\.$#' path: '%currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/ProxyLogicTest.php' - message: '#^Property Doctrine\\Tests\\Common\\Proxy\\ProxyLogicVoidReturnTypeTest::\$initializerCallbackMock \(callable&PHPUnit\\Framework\\MockObject\\MockObject\) does not accept PHPUnit\\Framework\\MockObject\\MockObject&stdClass\.$#' path: '%currentWorkingDirectory%/tests/Doctrine/Tests/Common/Proxy/ProxyLogicVoidReturnTypeTest.php' includes: - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/phpstan/phpstan-phpunit/rules.neon php-doctrine-common-2.12.0/phpunit.xml.dist000066400000000000000000000012111360676402100206310ustar00rootroot00000000000000 ./tests/Doctrine/ ./lib/Doctrine/ php-doctrine-common-2.12.0/tests/000077500000000000000000000000001360676402100166255ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/.gitignore000066400000000000000000000001431360676402100206130ustar00rootroot00000000000000Doctrine/Tests/Proxies/ Doctrine/Tests/ORM/Proxy/generated/ Doctrine/Tests/ORM/Tools/Export/export php-doctrine-common-2.12.0/tests/Doctrine/000077500000000000000000000000001360676402100203745ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/000077500000000000000000000000001360676402100214765ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/000077500000000000000000000000001360676402100227265ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/ClassLoaderTest.php000066400000000000000000000116141360676402100264760ustar00rootroot00000000000000setIncludePath(__DIR__); $classLoader->setFileExtension('.class.php'); $classLoader->setNamespaceSeparator('_'); self::assertTrue($classLoader->canLoadClass('ClassLoaderTest_ClassA')); self::assertTrue($classLoader->canLoadClass('ClassLoaderTest_ClassB')); self::assertTrue($classLoader->canLoadClass('ClassLoaderTest_ClassC')); self::assertFalse($classLoader->canLoadClass('OtherClass')); self::assertEquals($classLoader->loadClass('ClassLoaderTest_ClassA'), true); self::assertEquals($classLoader->loadClass('ClassLoaderTest_ClassB'), true); self::assertEquals($classLoader->loadClass('ClassLoaderTest_ClassC'), true); } public function testClassExists() { self::assertFalse(ClassLoader::classExists('ClassLoaderTest\ClassD')); $badLoader = function ($className) { require __DIR__ . '/ClassLoaderTest/ClassD.php'; return true; }; spl_autoload_register($badLoader); self::assertTrue(ClassLoader::classExists('ClassLoaderTest\ClassD')); spl_autoload_unregister($badLoader); } public function testGetClassLoader() { $cl = new ClassLoader('ClassLoaderTest', __DIR__); $cl->register(); self::assertTrue(ClassLoader::getClassLoader('ClassLoaderTest\ClassD') instanceof \Doctrine\Common\ClassLoader); self::assertNull(ClassLoader::getClassLoader('This\Class\Does\Not\Exist')); $cl->unregister(); } public function testClassExistsWithSilentAutoloader() { $test = $this; $silentLoader = function ($className) use ($test) { $test->assertSame('ClassLoaderTest\ClassE', $className); require __DIR__ . '/ClassLoaderTest/ClassE.php'; }; $additionalLoader = function () use ($test) { $test->fail('Should not call this loader, class was already loaded'); }; self::assertFalse(ClassLoader::classExists('ClassLoaderTest\ClassE')); spl_autoload_register($silentLoader); spl_autoload_register($additionalLoader); self::assertTrue(ClassLoader::classExists('ClassLoaderTest\ClassE')); spl_autoload_unregister($additionalLoader); spl_autoload_unregister($silentLoader); } public function testClassExistsWhenLoaderIsProtected() { require_once __DIR__ . '/ClassLoaderTest/ExternalLoader.php'; // Test static call \ClassLoaderTest\ExternalLoader::registerStatic(); self::assertFalse(ClassLoader::classExists('ClassLoaderTest\Class\That\Does\Not\Exist')); \ClassLoaderTest\ExternalLoader::unregisterStatic(); // Test object $loader = new \ClassLoaderTest\ExternalLoader(); $loader->register(); self::assertFalse(ClassLoader::classExists('ClassLoaderTest\Class\That\Does\Not\Exist')); $loader->unregister(); } public function testLoadNonExistingClass() { $classLoader = new ClassLoader('ClassLoaderTest', __DIR__); self::assertFalse($classLoader->loadClass('ClassLoaderTest\Non\Existing\ClassName')); } public function testLoadFileNotContainingClassClass() { $classLoader = new ClassLoader('ClassLoaderTest', __DIR__); $classLoader->setFileExtension('.class.php'); self::assertFalse($classLoader->loadClass('ClassLoaderTest\EmptyFile')); } public function testSupportsInterfaceAutoloading() { $classLoader = new ClassLoader(); $classLoader->setIncludePath(__DIR__); $classLoader->setFileExtension('.class.php'); $classLoader->setNamespaceSeparator('_'); self::assertTrue($classLoader->loadClass('ClassLoaderTest_InterfaceA')); self::assertTrue(interface_exists('ClassLoaderTest_InterfaceA', false)); } public function testSupportsTraitAutoloading() { $classLoader = new ClassLoader(); $classLoader->setIncludePath(__DIR__); $classLoader->setFileExtension('.class.php'); $classLoader->setNamespaceSeparator('_'); self::assertTrue($classLoader->loadClass('ClassLoaderTest_TraitA')); self::assertTrue(trait_exists('ClassLoaderTest_TraitA', false)); } public function testMultipleAutoloadRequestsWillProduceSameResult() { $classLoader = new ClassLoader(); $classLoader->setIncludePath(__DIR__); $classLoader->setFileExtension('.class.php'); $classLoader->setNamespaceSeparator('_'); self::assertTrue($classLoader->loadClass('ClassLoaderTest_ClassA')); self::assertTrue($classLoader->loadClass('ClassLoaderTest_ClassA')); } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/ClassLoaderTest/000077500000000000000000000000001360676402100257625ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/ClassLoaderTest/ClassA.class.php000066400000000000000000000000511360676402100307410ustar00rootroot00000000000000createMock(ProxyGenerator::class); $metadataFactory = $this->createMock(ClassMetadataFactory::class); $proxyFactory = $this->getMockForAbstractClass( AbstractProxyFactory::class, [$proxyGenerator, $metadataFactory, $autoGenerate] ); self::assertAttributeSame($expected, 'autoGenerate', $proxyFactory); } public function testInvalidAutoGenerateValueThrowsException() : void { $proxyGenerator = $this->createMock(ProxyGenerator::class); $metadataFactory = $this->createMock(ClassMetadataFactory::class); $this->expectException(InvalidArgumentException::class); $this->getMockForAbstractClass( AbstractProxyFactory::class, [$proxyGenerator, $metadataFactory, 5] ); } public function testGenerateProxyClasses() { $metadata = $this->createMock(ClassMetadata::class); $proxyGenerator = $this->createMock(ProxyGenerator::class); $proxyGenerator ->expects($this->once()) ->method('getProxyFileName'); $proxyGenerator ->expects($this->once()) ->method('generateProxyClass'); $metadataFactory = $this->createMock(ClassMetadataFactory::class); /* @var $proxyFactory \PHPUnit\Framework\MockObject\MockObject&AbstractProxyFactory */ $proxyFactory = $this->getMockForAbstractClass( AbstractProxyFactory::class, [$proxyGenerator, $metadataFactory, true] ); $proxyFactory ->expects($this->any()) ->method('skipClass') ->will($this->returnValue(false)); $generated = $proxyFactory->generateProxyClasses([$metadata], sys_get_temp_dir()); self::assertEquals(1, $generated, 'One proxy was generated'); } public function testGetProxy() { $metadata = $this->createMock(ClassMetadata::class); $proxy = $this->createMock(Proxy::class); $definition = new ProxyDefinition(get_class($proxy), [], [], null, null); $proxyGenerator = $this->createMock(ProxyGenerator::class); $metadataFactory = $this->createMock(ClassMetadataFactory::class); $metadataFactory ->expects($this->once()) ->method('getMetadataFor') ->will($this->returnValue($metadata)); /* @var $proxyFactory \PHPUnit\Framework\MockObject\MockObject&AbstractProxyFactory */ $proxyFactory = $this->getMockForAbstractClass( AbstractProxyFactory::class, [$proxyGenerator, $metadataFactory, true] ); $proxyFactory ->expects($this->any()) ->method('createProxyDefinition') ->will($this->returnValue($definition)); $generatedProxy = $proxyFactory->getProxy('Class', ['id' => 1]); self::assertInstanceOf(get_class($proxy), $generatedProxy); } public function testResetUnitializedProxy() { $metadata = $this->createMock(ClassMetadata::class); /* @var $proxy \PHPUnit\Framework\MockObject\MockObject&Proxy */ $proxy = $this->createMock(Proxy::class); $definition = new ProxyDefinition(get_class($proxy), [], [], null, null); $proxyGenerator = $this->createMock(ProxyGenerator::class); $metadataFactory = $this->createMock(ClassMetadataFactory::class); $metadataFactory ->expects($this->once()) ->method('getMetadataFor') ->will($this->returnValue($metadata)); /* @var $proxyFactory \PHPUnit\Framework\MockObject\MockObject&AbstractProxyFactory */ $proxyFactory = $this->getMockForAbstractClass( AbstractProxyFactory::class, [$proxyGenerator, $metadataFactory, true] ); $proxyFactory ->expects($this->any()) ->method('createProxyDefinition') ->will($this->returnValue($definition)); $proxy ->expects($this->once()) ->method('__isInitialized') ->will($this->returnValue(false)); $proxy ->expects($this->once()) ->method('__setInitializer'); $proxy ->expects($this->once()) ->method('__setCloner'); $proxyFactory->resetUninitializedProxy($proxy); } public function testDisallowsResettingInitializedProxy() { /* @var $proxyFactory AbstractProxyFactory */ $proxyFactory = $this->getMockForAbstractClass(AbstractProxyFactory::class, [], '', false); /* @var $proxy Proxy&\PHPUnit\Framework\MockObject\MockObject */ $proxy = $this->createMock(Proxy::class); $proxy ->expects($this->any()) ->method('__isInitialized') ->will($this->returnValue(true)); $this->expectException(InvalidArgumentException::class); $proxyFactory->resetUninitializedProxy($proxy); } public function testMissingPrimaryKeyValue() { $metadata = $this->createMock(ClassMetadata::class); $proxy = $this->createMock(Proxy::class); $definition = new ProxyDefinition(get_class($proxy), ['missingKey'], [], null, null); $proxyGenerator = $this->createMock(ProxyGenerator::class); $metadataFactory = $this->createMock(ClassMetadataFactory::class); $metadataFactory ->expects($this->once()) ->method('getMetadataFor') ->will($this->returnValue($metadata)); /* @var $proxyFactory AbstractProxyFactory&\PHPUnit\Framework\MockObject\MockObject */ $proxyFactory = $this->getMockForAbstractClass( AbstractProxyFactory::class, [$proxyGenerator, $metadataFactory, true] ); $proxyFactory ->expects($this->any()) ->method('createProxyDefinition') ->will($this->returnValue($definition)); $this->expectException(OutOfBoundsException::class); $proxyFactory->getProxy('Class', []); } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/AutoloaderTest.php000066400000000000000000000040301360676402100275140ustar00rootroot00000000000000expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid \$notFoundCallback given: must be a callable, "stdClass" given'); Autoloader::register('', '', new \stdClass()); } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/CallableTypeHintClass.php000066400000000000000000000003131360676402100307270ustar00rootroot00000000000000identifierFieldInTrait; } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/InvalidReturnTypeClass.php000066400000000000000000000004141360676402100311750ustar00rootroot00000000000000 * @since 2.4 */ class LazyLoadableObject { /** * @var string */ public $publicIdentifierField; /** * @var string */ protected $protectedIdentifierField; /** * @var string */ public $publicTransientField = 'publicTransientFieldValue'; /** * @var string */ protected $protectedTransientField = 'protectedTransientFieldValue'; /** * @var string */ public $publicPersistentField = 'publicPersistentFieldValue'; /** * @var string */ protected $protectedPersistentField = 'protectedPersistentFieldValue'; /** * @var string */ public $publicAssociation = 'publicAssociationValue'; /** * @var string */ protected $protectedAssociation = 'protectedAssociationValue'; /** * @return string */ public function getProtectedIdentifierField() { return $this->protectedIdentifierField; } /** * @return string */ public function testInitializationTriggeringMethod() { return 'testInitializationTriggeringMethod'; } /** * @return string */ public function getProtectedAssociation() { return $this->protectedAssociation; } /** * @param \stdClass $param */ public function publicTypeHintedMethod(\stdClass $param) { } /** * */ public function &byRefMethod() { } /** * @param mixed $thisIsNotByRef * @param mixed $thisIsByRef */ public function byRefParamMethod($thisIsNotByRef, &$thisIsByRef) { } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/LazyLoadableObjectClassMetadata.php000066400000000000000000000066551360676402100327150ustar00rootroot00000000000000 * @since 2.4 */ class LazyLoadableObjectClassMetadata implements ClassMetadata { /** * @var ReflectionClass */ protected $reflectionClass; /** * @var array */ protected $identifier = [ 'publicIdentifierField' => true, 'protectedIdentifierField' => true, ]; /** * @var array */ protected $fields = [ 'publicIdentifierField' => true, 'protectedIdentifierField' => true, 'publicPersistentField' => true, 'protectedPersistentField' => true, ]; /** * @var array */ protected $associations = [ 'publicAssociation' => true, 'protectedAssociation' => true, ]; /** * {@inheritDoc} */ public function getName() { return $this->getReflectionClass()->getName(); } /** * {@inheritDoc} */ public function getIdentifier() { return array_keys($this->identifier); } /** * {@inheritDoc} */ public function getReflectionClass() { if (null === $this->reflectionClass) { $this->reflectionClass = new \ReflectionClass(__NAMESPACE__ . '\LazyLoadableObject'); } return $this->reflectionClass; } /** * {@inheritDoc} */ public function isIdentifier($fieldName) { return isset($this->identifier[$fieldName]); } /** * {@inheritDoc} */ public function hasField($fieldName) { return isset($this->fields[$fieldName]); } /** * {@inheritDoc} */ public function hasAssociation($fieldName) { return isset($this->associations[$fieldName]); } /** * {@inheritDoc} */ public function isSingleValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isCollectionValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getFieldNames() { return array_keys($this->fields); } /** * {@inheritDoc} */ public function getIdentifierFieldNames() { return $this->getIdentifier(); } /** * {@inheritDoc} */ public function getAssociationNames() { return array_keys($this->associations); } /** * {@inheritDoc} */ public function getTypeOfField($fieldName) { return 'string'; } /** * {@inheritDoc} */ public function getAssociationTargetClass($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isAssociationInverseSide($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getAssociationMappedByTargetField($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getIdentifierValues($object) { throw new \BadMethodCallException('not implemented'); } } LazyLoadableObjectWithNullableTypehints.php000066400000000000000000000013661360676402100344240ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy * @since 2.4 */ class LazyLoadableObjectWithNullableTypehints { /** @var \stdClass */ private $identifierFieldReturnClassOneLetterNullable; /** @var \stdClass */ private $identifierFieldReturnClassOneLetterNullableWithSpace; public function getIdentifierFieldReturnClassOneLetterNullable() : ?A { return $this->identifierFieldReturnClassOneLetterNullable; } public function getIdentifierFieldReturnClassOneLetterNullableWithSpace() : ? A { return $this->identifierFieldReturnClassOneLetterNullableWithSpace; } } LazyLoadableObjectWithNullableTypehintsClassMetadata.php000066400000000000000000000063751360676402100370600ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy * @since 2.4 */ class LazyLoadableObjectWithNullableTypehintsClassMetadata implements ClassMetadata { /** * @var ReflectionClass */ protected $reflectionClass; /** * @var array */ protected $identifier = [ 'identifierFieldReturnClassOneLetterNullable' => true, 'identifierFieldReturnClassOneLetterNullableWithSpace' => true, ]; /** * @var array */ protected $fields = [ 'identifierFieldReturnClassOneLetterNullable' => true, 'identifierFieldReturnClassOneLetterNullableWithSpace' => true, ]; /** * {@inheritDoc} */ public function getName() { return $this->getReflectionClass()->getName(); } /** * {@inheritDoc} */ public function getIdentifier() { return array_keys($this->identifier); } /** * {@inheritDoc} */ public function getReflectionClass() { if (null === $this->reflectionClass) { $this->reflectionClass = new \ReflectionClass(__NAMESPACE__ . '\LazyLoadableObjectWithNullableTypehints'); } return $this->reflectionClass; } /** * {@inheritDoc} */ public function isIdentifier($fieldName) { return isset($this->identifier[$fieldName]); } /** * {@inheritDoc} */ public function hasField($fieldName) { return isset($this->fields[$fieldName]); } /** * {@inheritDoc} */ public function hasAssociation($fieldName) { return false; } /** * {@inheritDoc} */ public function isSingleValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isCollectionValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getFieldNames() { return array_keys($this->fields); } /** * {@inheritDoc} */ public function getIdentifierFieldNames() { return $this->getIdentifier(); } /** * {@inheritDoc} */ public function getAssociationNames() { return []; } /** * {@inheritDoc} */ public function getTypeOfField($fieldName) { return 'string'; } /** * {@inheritDoc} */ public function getAssociationTargetClass($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isAssociationInverseSide($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getAssociationMappedByTargetField($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getIdentifierValues($object) { throw new \BadMethodCallException('not implemented'); } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/LazyLoadableObjectWithTrait.php000066400000000000000000000003451360676402100321140ustar00rootroot00000000000000 true, ]; /** * @var array */ protected $fields = [ 'identifierFieldInTrait' => true, ]; /** * {@inheritDoc} */ public function getName() { return $this->getReflectionClass()->getName(); } /** * {@inheritDoc} */ public function getIdentifier() { return array_keys($this->identifier); } /** * {@inheritDoc} */ public function getReflectionClass() { if (null === $this->reflectionClass) { $this->reflectionClass = new \ReflectionClass(__NAMESPACE__ . '\LazyLoadableObjectWithTrait'); } return $this->reflectionClass; } /** * {@inheritDoc} */ public function isIdentifier($fieldName) { return isset($this->identifier[$fieldName]); } /** * {@inheritDoc} */ public function hasField($fieldName) { return isset($this->fields[$fieldName]); } /** * {@inheritDoc} */ public function hasAssociation($fieldName) { return false; } /** * {@inheritDoc} */ public function isSingleValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isCollectionValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getFieldNames() { return array_keys($this->fields); } /** * {@inheritDoc} */ public function getIdentifierFieldNames() { return $this->getIdentifier(); } /** * {@inheritDoc} */ public function getAssociationNames() { return []; } /** * {@inheritDoc} */ public function getTypeOfField($fieldName) { return 'string'; } /** * {@inheritDoc} */ public function getAssociationTargetClass($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isAssociationInverseSide($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getAssociationMappedByTargetField($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getIdentifierValues($object) { throw new \BadMethodCallException('not implemented'); } } LazyLoadableObjectWithTypedProperties.php000066400000000000000000000027401360676402100341150ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/ProxyprotectedIdentifierField; } /** * @return string */ public function testInitializationTriggeringMethod() { return 'testInitializationTriggeringMethod'; } /** * @return string */ public function getProtectedAssociation() { return $this->protectedAssociation; } /** * @param \stdClass $param */ public function publicTypeHintedMethod(\stdClass $param) { } public function &byRefMethod() { } /** * @param mixed $thisIsNotByRef * @param mixed $thisIsByRef */ public function byRefParamMethod($thisIsNotByRef, &$thisIsByRef) { } } LazyLoadableObjectWithTypedPropertiesClassMetadata.php000066400000000000000000000066461360676402100365550ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy true, 'protectedIdentifierField' => true, ]; /** * @var array */ protected $fields = [ 'publicIdentifierField' => true, 'protectedIdentifierField' => true, 'publicPersistentField' => true, 'protectedPersistentField' => true, ]; /** * @var array */ protected $associations = [ 'publicAssociation' => true, 'protectedAssociation' => true, ]; /** * {@inheritDoc} */ public function getName() { return $this->getReflectionClass()->getName(); } /** * {@inheritDoc} */ public function getIdentifier() { return array_keys($this->identifier); } /** * {@inheritDoc} */ public function getReflectionClass() { if (null === $this->reflectionClass) { $this->reflectionClass = new \ReflectionClass(__NAMESPACE__ . '\LazyLoadableObjectWithTypedProperties'); } return $this->reflectionClass; } /** * {@inheritDoc} */ public function isIdentifier($fieldName) { return isset($this->identifier[$fieldName]); } /** * {@inheritDoc} */ public function hasField($fieldName) { return isset($this->fields[$fieldName]); } /** * {@inheritDoc} */ public function hasAssociation($fieldName) { return isset($this->associations[$fieldName]); } /** * {@inheritDoc} */ public function isSingleValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isCollectionValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getFieldNames() { return array_keys($this->fields); } /** * {@inheritDoc} */ public function getIdentifierFieldNames() { return $this->getIdentifier(); } /** * {@inheritDoc} */ public function getAssociationNames() { return array_keys($this->associations); } /** * {@inheritDoc} */ public function getTypeOfField($fieldName) { return 'string'; } /** * {@inheritDoc} */ public function getAssociationTargetClass($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isAssociationInverseSide($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getAssociationMappedByTargetField($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getIdentifierValues($object) { throw new \BadMethodCallException('not implemented'); } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/LazyLoadableObjectWithTypehints.php000066400000000000000000000037061360676402100330240ustar00rootroot00000000000000 * @since 2.4 */ class LazyLoadableObjectWithTypehints { /** @var string */ private $identifierFieldNoReturnTypehint; /** @var string */ private $identifierFieldReturnTypehintScalar; /** @var LazyLoadableObjectWithTypehints */ private $identifierFieldReturnClassFullyQualified; /** @var LazyLoadableObjectWithTypehints */ private $identifierFieldReturnClassPartialUse; /** @var LazyLoadableObjectWithTypehints */ private $identifierFieldReturnClassFullUse; /** @var \stdClass */ private $identifierFieldReturnClassOneWord; /** @var \stdClass */ private $identifierFieldReturnClassOneLetter; /** * @return string */ public function getIdentifierFieldNoReturnTypehint() { return $this->identifierFieldNoReturnTypehint; } public function getIdentifierFieldReturnTypehintScalar() : string { return $this->identifierFieldReturnTypehintScalar; } public function getIdentifierFieldReturnClassFullyQualified() : \Doctrine\Tests\Common\Proxy\LazyLoadableObjectWithTypehints { return $this->identifierFieldReturnClassFullyQualified; } public function getIdentifierFieldReturnClassPartialUse() : Doctrine\Tests\Common\Proxy\LazyLoadableObjectWithTypehints { return $this->identifierFieldReturnClassPartialUse; } public function getIdentifierFieldReturnClassFullUse() : LazyLoadableObjectWithTypehints { return $this->identifierFieldReturnClassFullUse; } public function getIdentifierFieldReturnClassOneWord() : \stdClass { return $this->identifierFieldReturnClassOneWord; } public function getIdentifierFieldReturnClassOneLetter() : A { return $this->identifierFieldReturnClassOneLetter; } } LazyLoadableObjectWithTypehintsClassMetadata.php000066400000000000000000000073351360676402100353760ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy * @since 2.4 */ class LazyLoadableObjectWithTypehintsClassMetadata implements ClassMetadata { /** * @var ReflectionClass */ protected $reflectionClass; /** * @var array */ protected $identifier = [ 'identifierFieldNoReturnTypehint' => true, 'identifierFieldReturnTypehintScalar' => true, 'identifierFieldReturnClassFullyQualified' => true, 'identifierFieldReturnClassPartialUse' => true, 'identifierFieldReturnClassFullUse' => true, 'identifierFieldReturnClassOneWord' => true, 'identifierFieldReturnClassOneLetter' => true, ]; /** * @var array */ protected $fields = [ 'identifierFieldNoReturnTypehint' => true, 'identifierFieldReturnTypehintScalar' => true, 'identifierFieldReturnClassFullyQualified' => true, 'identifierFieldReturnClassPartialUse' => true, 'identifierFieldReturnClassFullUse' => true, 'identifierFieldReturnClassOneWord' => true, 'identifierFieldReturnClassOneLetter' => true, ]; /** * {@inheritDoc} */ public function getName() { return $this->getReflectionClass()->getName(); } /** * {@inheritDoc} */ public function getIdentifier() { return array_keys($this->identifier); } /** * {@inheritDoc} */ public function getReflectionClass() { if (null === $this->reflectionClass) { $this->reflectionClass = new \ReflectionClass(__NAMESPACE__ . '\LazyLoadableObjectWithTypehints'); } return $this->reflectionClass; } /** * {@inheritDoc} */ public function isIdentifier($fieldName) { return isset($this->identifier[$fieldName]); } /** * {@inheritDoc} */ public function hasField($fieldName) { return isset($this->fields[$fieldName]); } /** * {@inheritDoc} */ public function hasAssociation($fieldName) { return false; } /** * {@inheritDoc} */ public function isSingleValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isCollectionValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getFieldNames() { return array_keys($this->fields); } /** * {@inheritDoc} */ public function getIdentifierFieldNames() { return $this->getIdentifier(); } /** * {@inheritDoc} */ public function getAssociationNames() { return []; } /** * {@inheritDoc} */ public function getTypeOfField($fieldName) { return 'string'; } /** * {@inheritDoc} */ public function getAssociationTargetClass($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isAssociationInverseSide($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getAssociationMappedByTargetField($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getIdentifierValues($object) { throw new \BadMethodCallException('not implemented'); } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/LazyLoadableObjectWithVoid.php000066400000000000000000000006351360676402100317340ustar00rootroot00000000000000value++; } public function addingAndReturningVoid(int $i) : void { $this->value += $i; } } LazyLoadableObjectWithVoidClassMetadata.php000066400000000000000000000052701360676402100343040ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/ProxygetReflectionClass()->getName(); } /** * {@inheritDoc} */ public function getIdentifier() { return []; } /** * {@inheritDoc} */ public function getReflectionClass() { if (null === $this->reflectionClass) { $this->reflectionClass = new \ReflectionClass(__NAMESPACE__ . '\LazyLoadableObjectWithVoid'); } return $this->reflectionClass; } /** * {@inheritDoc} */ public function isIdentifier($fieldName) { return false; } /** * {@inheritDoc} */ public function hasField($fieldName) { return false; } /** * {@inheritDoc} */ public function hasAssociation($fieldName) { return false; } /** * {@inheritDoc} */ public function isSingleValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isCollectionValuedAssociation($fieldName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getFieldNames() { return []; } /** * {@inheritDoc} */ public function getIdentifierFieldNames() { return $this->getIdentifier(); } /** * {@inheritDoc} */ public function getAssociationNames() { return []; } /** * {@inheritDoc} */ public function getTypeOfField($fieldName) { return 'integer'; } /** * {@inheritDoc} */ public function getAssociationTargetClass($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function isAssociationInverseSide($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getAssociationMappedByTargetField($assocName) { throw new \BadMethodCallException('not implemented'); } /** * {@inheritDoc} */ public function getIdentifierValues($object) { throw new \BadMethodCallException('not implemented'); } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/MagicCloneClass.php000066400000000000000000000007711360676402100275540ustar00rootroot00000000000000clonedValue = 'newClonedValue'; } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/MagicGetByRefClass.php000066400000000000000000000007701360676402100301620ustar00rootroot00000000000000valueField; } throw new InvalidArgumentException(); } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/MagicGetClass.php000066400000000000000000000012221360676402100272230ustar00rootroot00000000000000testAttribute = $value; } if ($name === 'publicField' || $name === 'id') { throw new \BadMethodCallException('Should never be called for "publicField" or "id"'); } $this->testAttribute = $value; } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/MagicSleepClass.php000066400000000000000000000010071360676402100275550ustar00rootroot00000000000000wakeupValue = 'newWakeupValue'; } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/NullableNonOptionalHintClass.php000066400000000000000000000007351360676402100323150ustar00rootroot00000000000000 * @author Marco Pivetta */ class ProxyGeneratorTest extends \PHPUnit\Framework\TestCase { /** * @var string */ protected $proxyClass = 'Doctrine\Tests\Common\ProxyProxy\__CG__\Doctrine\Tests\Common\Proxy\LazyLoadableObject'; /** * @var LazyLoadableObjectClassMetadata */ protected $metadata; /** * @var ProxyGenerator */ protected $proxyGenerator; /** * {@inheritDoc} */ protected function setUp(): void { $this->metadata = new LazyLoadableObjectClassMetadata(); $this->proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); if (class_exists($this->proxyClass, false)) { return; } $this->generateAndRequire($this->proxyGenerator, $this->metadata); } public function testReferenceProxyRespectsMethodsParametersTypeHinting() { $method = new ReflectionMethod($this->proxyClass, 'publicTypeHintedMethod'); $params = $method->getParameters(); self::assertEquals(1, count($params)); self::assertEquals('stdClass', $params[0]->getClass()->getName()); } public function testProxyRespectsMethodsWhichReturnValuesByReference() { $method = new ReflectionMethod($this->proxyClass, 'byRefMethod'); self::assertTrue($method->returnsReference()); } public function testProxyRespectsByRefMethodParameters() { $method = new ReflectionMethod($this->proxyClass, 'byRefParamMethod'); $parameters = $method->getParameters(); self::assertSame('thisIsNotByRef', $parameters[0]->getName()); self::assertFalse($parameters[0]->isPassedByReference()); self::assertSame('thisIsByRef', $parameters[1]->getName()); self::assertTrue($parameters[1]->isPassedByReference()); } public function testCreatesAssociationProxyAsSubclassOfTheOriginalOne() { self::assertTrue(is_subclass_of($this->proxyClass, $this->metadata->getName())); } public function testNonNamespacedProxyGeneration() { $classCode = file_get_contents($this->proxyGenerator->getProxyFileName($this->metadata->getName())); self::assertNotContains("class LazyLoadableObject extends \\\\" . $this->metadata->getName(), $classCode); self::assertContains("class LazyLoadableObject extends \\" . $this->metadata->getName(), $classCode); } public function testClassWithSleepProxyGeneration() { if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\SleepClass', false)) { $className = SleepClass::class; $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } $classCode = file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxySleepClass.php'); self::assertEquals(1, substr_count($classCode, 'function __sleep')); self::assertEquals(1, substr_count($classCode, 'parent::__sleep()')); } /** * Check that the proxy doesn't serialize static properties (in __sleep() method) * @group DCOM-212 */ public function testClassWithStaticPropertyProxyGeneration() { if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\StaticPropertyClass', false)) { $className = StaticPropertyClass::class; $metadata = $this->createClassMetadata($className, []); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } $classCode = file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyStaticPropertyClass.php'); self::assertEquals(1, substr_count($classCode, 'function __sleep')); self::assertNotContains('protectedStaticProperty', $classCode); } private function generateAndRequire($proxyGenerator, $metadata) { $proxyGenerator->generateProxyClass($metadata, $proxyGenerator->getProxyFileName($metadata->getName())); require_once $proxyGenerator->getProxyFileName($metadata->getName()); } public function testClassWithCallableTypeHintOnProxiedMethod() { if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\CallableTypeHintClass', false)) { $className = CallableTypeHintClass::class; $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } $classCode = file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyCallableTypeHintClass.php'); self::assertEquals(1, substr_count($classCode, 'call(callable $foo)')); } public function testClassWithVariadicArgumentOnProxiedMethod() { if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\VariadicTypeHintClass', false)) { $className = VariadicTypeHintClass::class; $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } $classCode = file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyVariadicTypeHintClass.php'); self::assertEquals(1, substr_count($classCode, 'function addType(...$types)')); self::assertEquals(1, substr_count($classCode, '__invoke($this, \'addType\', [$types])')); self::assertEquals(1, substr_count($classCode, 'parent::addType(...$types)')); } public function testClassWithScalarTypeHintsOnProxiedMethods() { if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\ScalarTypeHintsClass', false)) { $className = ScalarTypeHintsClass::class; $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } $classCode = file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyScalarTypeHintsClass.php'); self::assertEquals(1, substr_count($classCode, 'function singleTypeHint(string $param)')); self::assertEquals(1, substr_count($classCode, 'function multipleTypeHints(int $a, float $b, bool $c, string $d)')); self::assertEquals(1, substr_count($classCode, 'function combinationOfTypeHintsAndNormal(\stdClass $a, \Countable $b, $c, int $d)')); self::assertEquals(1, substr_count($classCode, 'function typeHintsWithVariadic(int ...$foo)')); self::assertEquals(1, substr_count($classCode, 'function withDefaultValue(int $foo = 123)')); self::assertEquals(1, substr_count($classCode, 'function withDefaultValueNull(int $foo = NULL)')); } public function testClassWithReturnTypesOnProxiedMethods() { $className = ReturnTypesClass::class; if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\ReturnTypesClass', false)) { $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } $classCode = file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyReturnTypesClass.php'); self::assertEquals(1, substr_count($classCode, 'function returnsClass(): \stdClass')); self::assertEquals(1, substr_count($classCode, 'function returnsScalar(): int')); self::assertEquals(1, substr_count($classCode, 'function returnsArray(): array')); self::assertEquals(1, substr_count($classCode, 'function returnsCallable(): callable')); self::assertEquals(1, substr_count($classCode, 'function returnsSelf(): \\' . $className)); self::assertEquals(1, substr_count($classCode, 'function returnsParent(): \stdClass')); self::assertEquals(1, substr_count($classCode, 'function returnsInterface(): \Countable')); } public function testClassWithNullableTypeHintsOnProxiedMethods() { $className = NullableTypeHintsClass::class; if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\NullableTypeHintsClass', false)) { $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } $classCode = file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyNullableTypeHintsClass.php'); self::assertEquals(1, substr_count($classCode, 'function nullableTypeHintInt(?int $param)')); self::assertEquals(1, substr_count($classCode, 'function nullableTypeHintObject(?\stdClass $param)')); self::assertEquals(1, substr_count($classCode, 'function nullableTypeHintSelf(?\\' . $className . ' $param)')); self::assertEquals(1, substr_count($classCode, 'function nullableTypeHintWithDefault(?int $param = 123)')); self::assertEquals(1, substr_count($classCode, 'function nullableTypeHintWithDefaultNull(int $param = NULL)')); self::assertEquals(1, substr_count($classCode, 'function notNullableTypeHintWithDefaultNull(int $param = NULL)')); } public function testClassWithNullableReturnTypesOnProxiedMethods() { $className = NullableTypeHintsClass::class; if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\NullableTypeHintsClass', false)) { $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } $classCode = file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyNullableTypeHintsClass.php'); self::assertEquals(1, substr_count($classCode, 'function returnsNullableInt(): ?int')); self::assertEquals(1, substr_count($classCode, 'function returnsNullableObject(): ?\stdClass')); self::assertEquals(1, substr_count($classCode, 'function returnsNullableSelf(): ?\\' . $className)); } /** * @group #751 */ public function testClassWithNullableOptionalNonLastParameterOnProxiedMethods() { $className = NullableNonOptionalHintClass::class; if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\NullableNonOptionalHintClass', false)) { $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } self::assertContains( 'public function midSignatureNullableParameter(\stdClass $param = NULL, $secondParam)', file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyNullableNonOptionalHintClass.php') ); self::assertContains( 'public function midSignatureNotNullableHintedParameter(string $param = \'foo\', $secondParam)', file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyNullableNonOptionalHintClass.php') ); } /** * @group #751 */ public function testClassWithPhp71NullableOptionalNonLastParameterOnProxiedMethods() { $className = Php71NullableDefaultedNonOptionalHintClass::class; if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\Php71NullableDefaultedNonOptionalHintClass', false)) { $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } self::assertContains( 'public function midSignatureNullableParameter(string $param = NULL, $secondParam)', file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyPhp71NullableDefaultedNonOptionalHintClass.php'), 'Signature allows nullable type, although explicit "?" marker isn\'t used in the proxy' ); self::assertContains( 'public function midSignatureNotNullableHintedParameter(?string $param = \'foo\', $secondParam)', file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyPhp71NullableDefaultedNonOptionalHintClass.php') ); } public function testClassWithVoidReturnType() { $className = VoidReturnTypeClass::class; if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\VoidReturnTypeClass', false)) { $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } $classCode = file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyVoidReturnTypeClass.php'); self::assertEquals(1, substr_count($classCode, 'function returnsVoid(): void')); } public function testClassWithIterableTypeHint() { $className = IterableTypeHintClass::class; if ( ! class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\IterableTypeHintClass', false)) { $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->generateAndRequire($proxyGenerator, $metadata); } $classCode = file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyIterableTypeHintClass.php'); self::assertEquals(1, substr_count($classCode, 'function parameterType(iterable $param)')); self::assertEquals(1, substr_count($classCode, 'function returnType(): iterable')); } public function testClassWithInvalidTypeHintOnProxiedMethod() { $className = InvalidTypeHintClass::class; $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage( 'The type hint of parameter "foo" in method "invalidTypeHintMethod"' . ' in class "' . $className . '" is invalid.' ); $proxyGenerator->generateProxyClass($metadata); } public function testClassWithInvalidReturnTypeOnProxiedMethod() { $className = InvalidReturnTypeClass::class; $metadata = $this->createClassMetadata($className, ['id']); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage( 'The return type of method "invalidReturnTypeMethod"' . ' in class "' . $className . '" is invalid.' ); $proxyGenerator->generateProxyClass($metadata); } public function testNoConfigDirThrowsException() { $this->expectException(InvalidArgumentException::class); new ProxyGenerator(null, null); } public function testNoNamespaceThrowsException() { $this->expectException(InvalidArgumentException::class); new ProxyGenerator(__DIR__ . '/generated', null); } public function testInvalidPlaceholderThrowsException() { $this->expectException(InvalidArgumentException::class); $generator = new ProxyGenerator(__DIR__ . '/generated', 'SomeNamespace'); $generator->setPlaceholder('', []); } public function testUseEvalIfNoFilenameIsGiven() { $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $proxyGenerator->generateProxyClass($this->createClassMetadata(EvalBase::class, ['id'])); $reflClass = new ReflectionClass('Doctrine\Tests\Common\ProxyProxy\__CG__\Doctrine\Tests\Common\Proxy\EvalBase'); self::assertContains("eval()'d code", $reflClass->getFileName()); } public function testAbstractClassThrowsException() { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Unable to create a proxy for an abstract class "' . AbstractClass::class . '".'); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $proxyGenerator->generateProxyClass($this->createClassMetadata(AbstractClass::class, [])); } public function testFinalClassThrowsException() { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Unable to create a proxy for a final class "' . FinalClass::class . '".'); $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $proxyGenerator->generateProxyClass($this->createClassMetadata(FinalClass::class, [])); } /** * @param string $className * @param array $ids * * @return \PHPUnit\Framework\MockObject\MockObject&ClassMetadata */ private function createClassMetadata($className, array $ids) { $metadata = $this->createMock(ClassMetadata::class); $reflClass = new ReflectionClass($className); $metadata->expects($this->any())->method('getReflectionClass')->will($this->returnValue($reflClass)); $metadata->expects($this->any())->method('getIdentifierFieldNames')->will($this->returnValue($ids)); $metadata->expects($this->any())->method('getName')->will($this->returnValue($className)); return $metadata; } } class EvalBase { } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/ProxyLogicIdentifierGetterTest.php000066400000000000000000000065461360676402100327100ustar00rootroot00000000000000 * @author Jan Langer */ class ProxyLogicIdentifierGetterTest extends \PHPUnit\Framework\TestCase { /** * @dataProvider methodsForWhichLazyLoadingShouldBeDisabled * * @param ClassMetadata $metadata * @param string $fieldName * @param mixed $expectedReturnedValue */ public function testNoLazyLoadingForIdentifier(ClassMetadata $metadata, $fieldName, $expectedReturnedValue) { $className = $metadata->getName(); $proxyClassName = 'Doctrine\Tests\Common\ProxyProxy\__CG__\\' . $className; $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $proxyFileName = $proxyGenerator->getProxyFileName($className); if ( ! class_exists($proxyClassName, false)) { $proxyGenerator->generateProxyClass($metadata, $proxyFileName); /** @noinspection PhpIncludeInspection */ require_once $proxyFileName; } $proxy = new $proxyClassName( function () { self::fail('Initialization is never supposed to happen'); }, function () { self::fail('Initialization is never supposed to happen'); } ); $reflection = $metadata->getReflectionClass()->getProperty($fieldName); $reflection->setAccessible(true); $reflection->setValue($proxy, $expectedReturnedValue); self::assertSame($expectedReturnedValue, $proxy->{'get' . $fieldName}()); } /** * @return array */ public function methodsForWhichLazyLoadingShouldBeDisabled() { return [ [new LazyLoadableObjectClassMetadata(), 'protectedIdentifierField', 'foo'], [new LazyLoadableObjectWithTypehintsClassMetadata(), 'identifierFieldNoReturnTypehint', 'noTypeHint'], [new LazyLoadableObjectWithTypehintsClassMetadata(), 'identifierFieldReturnTypehintScalar', 'scalarValue'], [new LazyLoadableObjectWithTypehintsClassMetadata(), 'identifierFieldReturnClassFullyQualified', new LazyLoadableObjectWithTypehints()], [new LazyLoadableObjectWithTypehintsClassMetadata(), 'identifierFieldReturnClassPartialUse', new LazyLoadableObjectWithTypehints()], [new LazyLoadableObjectWithTypehintsClassMetadata(), 'identifierFieldReturnClassFullUse', new LazyLoadableObjectWithTypehints()], [new LazyLoadableObjectWithTypehintsClassMetadata(), 'identifierFieldReturnClassOneWord', new stdClass()], [new LazyLoadableObjectWithTypehintsClassMetadata(), 'identifierFieldReturnClassOneLetter', new stdClass()], [new LazyLoadableObjectWithTraitClassMetadata(), 'identifierFieldInTrait', 123], [new LazyLoadableObjectWithNullableTypehintsClassMetadata(), 'identifierFieldReturnClassOneLetterNullable', new stdClass()], [new LazyLoadableObjectWithNullableTypehintsClassMetadata(), 'identifierFieldReturnClassOneLetterNullableWithSpace', new stdClass()], ]; } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/ProxyLogicTest.php000066400000000000000000000667421360676402100275360ustar00rootroot00000000000000 */ class ProxyLogicTest extends \PHPUnit\Framework\TestCase { /** * @var \PHPUnit\Framework\MockObject\MockObject&\stdClass */ protected $proxyLoader; /** * @var ClassMetadata */ protected $lazyLoadableObjectMetadata; /** * @var LazyLoadableObject&Proxy */ protected $lazyObject; protected $identifier = [ 'publicIdentifierField' => 'publicIdentifierFieldValue', 'protectedIdentifierField' => 'protectedIdentifierFieldValue', ]; /** * @var \PHPUnit\Framework\MockObject\MockObject&Callable */ protected $initializerCallbackMock; /** * {@inheritDoc} */ public function setUp(): void { $loader = $this->proxyLoader = $this->getMockBuilder(stdClass::class)->setMethods(['load'])->getMock(); $this->initializerCallbackMock = $this->getMockBuilder(stdClass::class)->setMethods(['__invoke'])->getMock(); $identifier = $this->identifier; $this->lazyLoadableObjectMetadata = $metadata = new LazyLoadableObjectClassMetadata(); // emulating what should happen in a proxy factory $cloner = function (LazyLoadableObject $proxy) use ($loader, $identifier, $metadata) { /** @var LazyLoadableObject&Proxy $proxy */ $proxy = $proxy; if ($proxy->__isInitialized()) { return; } $proxy->__setInitialized(true); $proxy->__setInitializer(null); $original = $loader->load($identifier); if (null === $original) { throw new UnexpectedValueException(); } foreach ($metadata->getReflectionClass()->getProperties() as $reflProperty) { $propertyName = $reflProperty->getName(); if ($metadata->hasField($propertyName) || $metadata->hasAssociation($propertyName)) { $reflProperty->setAccessible(true); $reflProperty->setValue($proxy, $reflProperty->getValue($original)); } } }; $proxyClassName = 'Doctrine\Tests\Common\ProxyProxy\__CG__\Doctrine\Tests\Common\Proxy\LazyLoadableObject'; // creating the proxy class if ( ! class_exists($proxyClassName, false)) { $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $proxyFileName = $proxyGenerator->getProxyFileName($metadata->getName()); $proxyGenerator->generateProxyClass($metadata, $proxyFileName); require_once $proxyFileName; } $this->lazyObject = new $proxyClassName($this->getClosure($this->initializerCallbackMock), $cloner); // setting identifiers in the proxy via reflection foreach ($metadata->getIdentifierFieldNames() as $idField) { $prop = $metadata->getReflectionClass()->getProperty($idField); $prop->setAccessible(true); $prop->setValue($this->lazyObject, $identifier[$idField]); } self::assertFalse($this->lazyObject->__isInitialized()); } public function testFetchingPublicIdentifierDoesNotCauseLazyLoading() { $this->configureInitializerMock(0); self::assertSame('publicIdentifierFieldValue', $this->lazyObject->publicIdentifierField); } public function testFetchingIdentifiersViaPublicGetterDoesNotCauseLazyLoading() { $this->configureInitializerMock(0); self::assertSame('protectedIdentifierFieldValue', $this->lazyObject->getProtectedIdentifierField()); } public function testCallingMethodCausesLazyLoading() { $this->configureInitializerMock( 1, [$this->lazyObject, 'testInitializationTriggeringMethod', []], function (Proxy $proxy) { $proxy->__setInitializer(null); } ); $this->lazyObject->testInitializationTriggeringMethod(); $this->lazyObject->testInitializationTriggeringMethod(); } public function testFetchingPublicFieldsCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__get', ['publicPersistentField']], function () use ($test) { $test->setProxyValue('publicPersistentField', 'loadedValue'); } ); self::assertSame('loadedValue', $this->lazyObject->publicPersistentField); self::assertSame('loadedValue', $this->lazyObject->publicPersistentField); } public function testFetchingPublicAssociationCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__get', ['publicAssociation']], function () use ($test) { $test->setProxyValue('publicAssociation', 'loadedAssociation'); } ); self::assertSame('loadedAssociation', $this->lazyObject->publicAssociation); self::assertSame('loadedAssociation', $this->lazyObject->publicAssociation); } public function testFetchingProtectedAssociationViaPublicGetterCausesLazyLoading() { $this->configureInitializerMock( 1, [$this->lazyObject, 'getProtectedAssociation', []], function (Proxy $proxy) { $proxy->__setInitializer(null); } ); self::assertSame('protectedAssociationValue', $this->lazyObject->getProtectedAssociation()); self::assertSame('protectedAssociationValue', $this->lazyObject->getProtectedAssociation()); } public function testLazyLoadingTriggeredOnlyAtFirstPublicPropertyRead() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__get', ['publicPersistentField']], function () use ($test) { $test->setProxyValue('publicPersistentField', 'loadedValue'); $test->setProxyValue('publicAssociation', 'publicAssociationValue'); } ); self::assertSame('loadedValue', $this->lazyObject->publicPersistentField); self::assertSame('publicAssociationValue', $this->lazyObject->publicAssociation); } public function testNoticeWhenReadingNonExistentPublicProperties() { $this->configureInitializerMock(0); $class = get_class($this->lazyObject); $this->expectException(Notice::class); $this->expectExceptionMessage('Undefined property: ' . $class . '::$non_existing_property'); $this->lazyObject->non_existing_property; } public function testFalseWhenCheckingNonExistentProperty() { $this->configureInitializerMock(0); self::assertFalse(isset($this->lazyObject->non_existing_property)); } public function testNoErrorWhenSettingNonExistentProperty() { $this->configureInitializerMock(0); $this->lazyObject->non_existing_property = 'now has a value'; self::assertSame('now has a value', $this->lazyObject->non_existing_property); } public function testCloningCallsClonerWithClonedObject() { $lazyObject = $this->lazyObject; $test = $this; $cb = $this->getMockBuilder(stdClass::class)->setMethods(['cb'])->getMock(); $cb ->expects($this->once()) ->method('cb') ->will($this->returnCallback(function (LazyLoadableObject $proxy) use ($lazyObject, $test) { /** @var LazyLoadableObject&Proxy $proxy */ $proxy = $proxy; $test->assertNotSame($proxy, $lazyObject); $proxy->__setInitializer(null); $proxy->publicAssociation = 'clonedAssociation'; })); $this->lazyObject->__setCloner($this->getClosure([$cb, 'cb'])); $cloned = clone $this->lazyObject; self::assertSame('clonedAssociation', $cloned->publicAssociation); self::assertNotSame($cloned, $lazyObject, 'a clone of the lazy object is retrieved'); } public function testFetchingTransientPropertiesWillNotTriggerLazyLoading() { $this->configureInitializerMock(0); self::assertSame( 'publicTransientFieldValue', $this->lazyObject->publicTransientField, 'fetching public transient field won\'t trigger lazy loading' ); $property = $this ->lazyLoadableObjectMetadata ->getReflectionClass() ->getProperty('protectedTransientField'); $property->setAccessible(true); self::assertSame( 'protectedTransientFieldValue', $property->getValue($this->lazyObject), 'fetching protected transient field via reflection won\'t trigger lazy loading' ); } /** * Provided to guarantee backwards compatibility */ public function testLoadProxyMethod() { $this->configureInitializerMock(2, [$this->lazyObject, '__load', []]); $this->lazyObject->__load(); $this->lazyObject->__load(); } public function testLoadingWithPersisterWillBeTriggeredOnlyOnce() { $this ->proxyLoader ->expects($this->once()) ->method('load') ->with( [ 'publicIdentifierField' => 'publicIdentifierFieldValue', 'protectedIdentifierField' => 'protectedIdentifierFieldValue', ], $this->lazyObject ) ->will($this->returnCallback(function ($id, LazyLoadableObject $lazyObject) { // setting a value to verify that the persister can actually set something in the object $lazyObject->publicAssociation = $id['publicIdentifierField'] . '-test'; return true; })); $this->lazyObject->__setInitializer($this->getSuggestedInitializerImplementation()); $this->lazyObject->__load(); $this->lazyObject->__load(); self::assertSame('publicIdentifierFieldValue-test', $this->lazyObject->publicAssociation); } public function testFailedLoadingWillThrowException() { $this->proxyLoader->expects($this->any())->method('load')->will($this->returnValue(null)); $this->expectException(\UnexpectedValueException::class); $this->lazyObject->__setInitializer($this->getSuggestedInitializerImplementation()); $this->lazyObject->__load(); } public function testCloningWithPersister() { $this->lazyObject->publicTransientField = 'should-not-change'; $this ->proxyLoader ->expects($this->exactly(2)) ->method('load') ->with([ 'publicIdentifierField' => 'publicIdentifierFieldValue', 'protectedIdentifierField' => 'protectedIdentifierFieldValue', ]) ->will($this->returnCallback(function () { $blueprint = new LazyLoadableObject(); $blueprint->publicPersistentField = 'checked-persistent-field'; $blueprint->publicAssociation = 'checked-association-field'; $blueprint->publicTransientField = 'checked-transient-field'; return $blueprint; })); $firstClone = clone $this->lazyObject; self::assertSame( 'checked-persistent-field', $firstClone->publicPersistentField, 'Persistent fields are cloned correctly' ); self::assertSame( 'checked-association-field', $firstClone->publicAssociation, 'Associations are cloned correctly' ); self::assertSame( 'should-not-change', $firstClone->publicTransientField, 'Transient fields are not overwritten' ); $secondClone = clone $this->lazyObject; self::assertSame( 'checked-persistent-field', $secondClone->publicPersistentField, 'Persistent fields are cloned correctly' ); self::assertSame( 'checked-association-field', $secondClone->publicAssociation, 'Associations are cloned correctly' ); self::assertSame( 'should-not-change', $secondClone->publicTransientField, 'Transient fields are not overwritten' ); // those should not trigger lazy loading $firstClone->__load(); $secondClone->__load(); } public function testNotInitializedProxyUnserialization() { $this->configureInitializerMock(); $serialized = serialize($this->lazyObject); /** @var LazyLoadableObject&Proxy $unserialized */ $unserialized = unserialize($serialized); $reflClass = $this->lazyLoadableObjectMetadata->getReflectionClass(); self::assertFalse($unserialized->__isInitialized(), 'serialization didn\'t cause intialization'); // Checking identifiers self::assertSame('publicIdentifierFieldValue', $unserialized->publicIdentifierField, 'identifiers are kept'); $protectedIdentifierField = $reflClass->getProperty('protectedIdentifierField'); $protectedIdentifierField->setAccessible(true); self::assertSame( 'protectedIdentifierFieldValue', $protectedIdentifierField->getValue($unserialized), 'identifiers are kept' ); // Checking transient fields self::assertSame( 'publicTransientFieldValue', $unserialized->publicTransientField, 'transient fields are kept' ); $protectedTransientField = $reflClass->getProperty('protectedTransientField'); $protectedTransientField->setAccessible(true); self::assertSame( 'protectedTransientFieldValue', $protectedTransientField->getValue($unserialized), 'transient fields are kept' ); // Checking persistent fields self::assertSame( 'publicPersistentFieldValue', $unserialized->publicPersistentField, 'persistent fields are kept' ); $protectedPersistentField = $reflClass->getProperty('protectedPersistentField'); $protectedPersistentField->setAccessible(true); self::assertSame( 'protectedPersistentFieldValue', $protectedPersistentField->getValue($unserialized), 'persistent fields are kept' ); // Checking associations self::assertSame('publicAssociationValue', $unserialized->publicAssociation, 'associations are kept'); $protectedAssociationField = $reflClass->getProperty('protectedAssociation'); $protectedAssociationField->setAccessible(true); self::assertSame( 'protectedAssociationValue', $protectedAssociationField->getValue($unserialized), 'associations are kept' ); } public function testInitializedProxyUnserialization() { // persister will retrieve the lazy object itself, so that we don't have to re-define all field values $this->proxyLoader->expects($this->once())->method('load')->will($this->returnValue($this->lazyObject)); $this->lazyObject->__setInitializer($this->getSuggestedInitializerImplementation()); $this->lazyObject->__load(); $serialized = serialize($this->lazyObject); $reflClass = $this->lazyLoadableObjectMetadata->getReflectionClass(); /** @var LazyLoadableObject&Proxy $unserialized */ $unserialized = unserialize($serialized); self::assertTrue($unserialized->__isInitialized(), 'serialization didn\'t cause intialization'); // Checking transient fields self::assertSame( 'publicTransientFieldValue', $unserialized->publicTransientField, 'transient fields are kept' ); $protectedTransientField = $reflClass->getProperty('protectedTransientField'); $protectedTransientField->setAccessible(true); self::assertSame( 'protectedTransientFieldValue', $protectedTransientField->getValue($unserialized), 'transient fields are kept' ); // Checking persistent fields self::assertSame( 'publicPersistentFieldValue', $unserialized->publicPersistentField, 'persistent fields are kept' ); $protectedPersistentField = $reflClass->getProperty('protectedPersistentField'); $protectedPersistentField->setAccessible(true); self::assertSame( 'protectedPersistentFieldValue', $protectedPersistentField->getValue($unserialized), 'persistent fields are kept' ); // Checking identifiers self::assertSame( 'publicIdentifierFieldValue', $unserialized->publicIdentifierField, 'identifiers are kept' ); $protectedIdentifierField = $reflClass->getProperty('protectedIdentifierField'); $protectedIdentifierField->setAccessible(true); self::assertSame( 'protectedIdentifierFieldValue', $protectedIdentifierField->getValue($unserialized), 'identifiers are kept' ); // Checking associations self::assertSame('publicAssociationValue', $unserialized->publicAssociation, 'associations are kept'); $protectedAssociationField = $reflClass->getProperty('protectedAssociation'); $protectedAssociationField->setAccessible(true); self::assertSame( 'protectedAssociationValue', $protectedAssociationField->getValue($unserialized), 'associations are kept' ); } public function testInitializationRestoresDefaultPublicLazyLoadedFieldValues() { // setting noop persister $this->proxyLoader->expects($this->once())->method('load')->will($this->returnValue($this->lazyObject)); $this->lazyObject->__setInitializer($this->getSuggestedInitializerImplementation()); self::assertSame( 'publicPersistentFieldValue', $this->lazyObject->publicPersistentField, 'Persistent field is restored to default value' ); self::assertSame( 'publicAssociationValue', $this->lazyObject->publicAssociation, 'Association is restored to default value' ); } public function testSettingPublicFieldsCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__set', ['publicPersistentField', 'newPublicPersistentFieldValue']], function () use ($test) { $test->setProxyValue('publicPersistentField', 'overrideValue'); $test->setProxyValue('publicAssociation', 'newAssociationValue'); } ); $this->lazyObject->publicPersistentField = 'newPublicPersistentFieldValue'; self::assertSame('newPublicPersistentFieldValue', $this->lazyObject->publicPersistentField); self::assertSame('newAssociationValue', $this->lazyObject->publicAssociation); } public function testSettingPublicAssociationCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__set', ['publicAssociation', 'newPublicAssociationValue']], function () use ($test) { $test->setProxyValue('publicPersistentField', 'newPublicPersistentFieldValue'); $test->setProxyValue('publicAssociation', 'overrideValue'); } ); $this->lazyObject->publicAssociation = 'newPublicAssociationValue'; self::assertSame('newPublicAssociationValue', $this->lazyObject->publicAssociation); self::assertSame('newPublicPersistentFieldValue', $this->lazyObject->publicPersistentField); } public function testCheckingPublicFieldsCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__isset', ['publicPersistentField']], function () use ($test) { $test->setProxyValue('publicPersistentField', null); $test->setProxyValue('publicAssociation', 'setPublicAssociation'); } ); self::assertFalse(isset($this->lazyObject->publicPersistentField)); self::assertNull($this->lazyObject->publicPersistentField); self::assertTrue(isset($this->lazyObject->publicAssociation)); self::assertSame('setPublicAssociation', $this->lazyObject->publicAssociation); } public function testCheckingPublicAssociationCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__isset', ['publicAssociation']], function () use ($test) { $test->setProxyValue('publicPersistentField', 'newPersistentFieldValue'); $test->setProxyValue('publicAssociation', 'setPublicAssociation'); } ); self::assertTrue(isset($this->lazyObject->publicAssociation)); self::assertSame('setPublicAssociation', $this->lazyObject->publicAssociation); self::assertTrue(isset($this->lazyObject->publicPersistentField)); self::assertSame('newPersistentFieldValue', $this->lazyObject->publicPersistentField); } public function testCallingVariadicMethodCausesLazyLoading() { $proxyClassName = 'Doctrine\Tests\Common\ProxyProxy\__CG__\Doctrine\Tests\Common\Proxy\VariadicTypeHintClass'; /* @var ClassMetadata&\PHPUnit\Framework\MockObject\MockObject $metadata */ $metadata = $this->createMock(ClassMetadata::class); $metadata ->expects($this->any()) ->method('getName') ->will($this->returnValue(VariadicTypeHintClass::class)); $metadata ->expects($this->any()) ->method('getReflectionClass') ->will($this->returnValue(new \ReflectionClass(VariadicTypeHintClass::class))); // creating the proxy class if ( ! class_exists($proxyClassName, false)) { $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $proxyGenerator->generateProxyClass($metadata, $proxyGenerator->getProxyFileName($metadata->getName())); require_once $proxyGenerator->getProxyFileName($metadata->getName()); } /** @var callable&\PHPUnit\Framework\MockObject\MockObject $invocationMock */ $invocationMock = $this->getMockBuilder(stdClass::class)->setMethods(['__invoke'])->getMock(); /** @var VariadicTypeHintClass $lazyObject */ $lazyObject = new $proxyClassName( function ($proxy, $method, $parameters) use ($invocationMock) { $invocationMock($proxy, $method, $parameters); }, function () { } ); $invocationMock ->expects($this->at(0)) ->method('__invoke') ->with($lazyObject, 'addType', [['type1', 'type2']]); $invocationMock ->expects($this->at(1)) ->method('__invoke') ->with($lazyObject, 'addTypeWithMultipleParameters', ['foo', 'bar', ['baz1', 'baz2']]); $lazyObject->addType('type1', 'type2'); self::assertSame(['type1', 'type2'], $lazyObject->types); $lazyObject->addTypeWithMultipleParameters('foo', 'bar', 'baz1', 'baz2'); self::assertSame('foo', $lazyObject->foo); self::assertSame('bar', $lazyObject->bar); self::assertSame(['baz1', 'baz2'], $lazyObject->baz); } /** * Converts a given callable into a closure * * @param callable $callable * @return \Closure */ public function getClosure($callable) { return function () use ($callable) { call_user_func_array($callable, func_get_args()); }; } /** * Configures the current initializer callback mock with provided matcher params * * @param int $expectedCallCount the number of invocations to be expected. If a value< 0 is provided, `any` is used * @param array $callParamsMatch an ordered array of parameters to be expected * @param \Closure $callbackClosure a return callback closure * * @return void */ protected function configureInitializerMock( $expectedCallCount = 0, array $callParamsMatch = null, \Closure $callbackClosure = null ) { if ( ! $expectedCallCount) { $invocationCountMatcher = $this->exactly((int) $expectedCallCount); } else { $invocationCountMatcher = $expectedCallCount < 0 ? $this->any() : $this->exactly($expectedCallCount); } $invocationMocker = $this->initializerCallbackMock->expects($invocationCountMatcher)->method('__invoke'); if (null !== $callParamsMatch) { call_user_func_array([$invocationMocker, 'with'], $callParamsMatch); } if ($callbackClosure) { $invocationMocker->will($this->returnCallback($callbackClosure)); } } /** * Sets a value in the current proxy object without triggering lazy loading through `__set` * * @link https://bugs.php.net/bug.php?id=63463 * * @param string $property * @param mixed $value */ public function setProxyValue($property, $value) { $reflectionProperty = new \ReflectionProperty($this->lazyObject, $property); $initializer = $this->lazyObject->__getInitializer(); // disabling initializer since setting `publicPersistentField` triggers `__set`/`__get` $this->lazyObject->__setInitializer(null); $reflectionProperty->setValue($this->lazyObject, $value); $this->lazyObject->__setInitializer($initializer); } /** * Retrieves the suggested implementation of an initializer that proxy factories in O*M * are currently following, and that should be used to initialize the current proxy object * * @return \Closure */ protected function getSuggestedInitializerImplementation() { $loader = $this->proxyLoader; $identifier = $this->identifier; return function (LazyLoadableObject $proxy) use ($loader, $identifier) { /** @var LazyLoadableObject&Proxy $proxy */ $proxy = $proxy; $proxy->__setInitializer(null); $proxy->__setCloner(null); if ($proxy->__isInitialized()) { return; } $properties = $proxy->__getLazyProperties(); foreach ($properties as $propertyName => $property) { if ( ! isset($proxy->$propertyName)) { $proxy->$propertyName = $properties[$propertyName]; } } $proxy->__setInitialized(true); if (method_exists($proxy, '__wakeup')) { $proxy->__wakeup(); } if (null === $loader->load($identifier, $proxy)) { throw new \UnexpectedValueException('Couldn\'t load'); } }; } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/ProxyLogicTypedPropertiesTest.php000066400000000000000000000674661360676402100326250ustar00rootroot00000000000000= 7.4 */ class ProxyLogicTypedPropertiesTest extends \PHPUnit\Framework\TestCase { /** * @var \PHPUnit\Framework\MockObject\MockObject&\stdClass */ protected $proxyLoader; /** * @var ClassMetadata */ protected $lazyLoadableObjectMetadata; /** * @var LazyLoadableObjectWithTypedProperties&Proxy */ protected $lazyObject; protected $identifier = [ 'publicIdentifierField' => 'publicIdentifierFieldValue', 'protectedIdentifierField' => 'protectedIdentifierFieldValue', ]; /** * @var \PHPUnit\Framework\MockObject\MockObject&Callable */ protected $initializerCallbackMock; /** * {@inheritDoc} */ public function setUp(): void { $loader = $this->proxyLoader = $this->getMockBuilder(stdClass::class)->setMethods(['load'])->getMock(); $this->initializerCallbackMock = $this->getMockBuilder(stdClass::class)->setMethods(['__invoke'])->getMock(); $identifier = $this->identifier; $this->lazyLoadableObjectMetadata = $metadata = new LazyLoadableObjectWithTypedPropertiesClassMetadata(); // emulating what should happen in a proxy factory $cloner = function (LazyLoadableObjectWithTypedProperties $proxy) use ($loader, $identifier, $metadata) { /** @var LazyLoadableObjectWithTypedProperties&Proxy $proxy */ $proxy = $proxy; if ($proxy->__isInitialized()) { return; } $proxy->__setInitialized(true); $proxy->__setInitializer(null); $original = $loader->load($identifier); if (null === $original) { throw new UnexpectedValueException(); } foreach ($metadata->getReflectionClass()->getProperties() as $reflProperty) { $propertyName = $reflProperty->getName(); if ($metadata->hasField($propertyName) || $metadata->hasAssociation($propertyName)) { $reflProperty->setAccessible(true); if ($reflProperty->isInitialized($original)) { $reflProperty->setValue($proxy, $reflProperty->getValue($original)); } } } }; $proxyClassName = 'Doctrine\Tests\Common\ProxyProxy\__CG__\Doctrine\Tests\Common\Proxy\LazyLoadableObjectWithTypedProperties'; // creating the proxy class if ( ! class_exists($proxyClassName, false)) { $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $proxyFileName = $proxyGenerator->getProxyFileName($metadata->getName()); $proxyGenerator->generateProxyClass($metadata, $proxyFileName); require_once $proxyFileName; } $this->lazyObject = new $proxyClassName($this->getClosure($this->initializerCallbackMock), $cloner); // setting identifiers in the proxy via reflection foreach ($metadata->getIdentifierFieldNames() as $idField) { $prop = $metadata->getReflectionClass()->getProperty($idField); $prop->setAccessible(true); $prop->setValue($this->lazyObject, $identifier[$idField]); } self::assertFalse($this->lazyObject->__isInitialized()); } public function testFetchingPublicIdentifierDoesNotCauseLazyLoading() { $this->configureInitializerMock(0); self::assertSame('publicIdentifierFieldValue', $this->lazyObject->publicIdentifierField); } public function testFetchingIdentifiersViaPublicGetterDoesNotCauseLazyLoading() { $this->configureInitializerMock(0); self::assertSame('protectedIdentifierFieldValue', $this->lazyObject->getProtectedIdentifierField()); } public function testCallingMethodCausesLazyLoading() { $this->configureInitializerMock( 1, [$this->lazyObject, 'testInitializationTriggeringMethod', []], function (Proxy $proxy) { $proxy->__setInitializer(null); } ); $this->lazyObject->testInitializationTriggeringMethod(); $this->lazyObject->testInitializationTriggeringMethod(); } public function testFetchingPublicFieldsCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__get', ['publicPersistentField']], function () use ($test) { $test->setProxyValue('publicPersistentField', 'loadedValue'); } ); self::assertSame('loadedValue', $this->lazyObject->publicPersistentField); self::assertSame('loadedValue', $this->lazyObject->publicPersistentField); } public function testFetchingPublicAssociationCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__get', ['publicAssociation']], function () use ($test) { $test->setProxyValue('publicAssociation', 'loadedAssociation'); } ); self::assertSame('loadedAssociation', $this->lazyObject->publicAssociation); self::assertSame('loadedAssociation', $this->lazyObject->publicAssociation); } public function testFetchingProtectedAssociationViaPublicGetterCausesLazyLoading() { $this->configureInitializerMock( 1, [$this->lazyObject, 'getProtectedAssociation', []], function (Proxy $proxy) { $proxy->__setInitializer(null); } ); self::assertSame('protectedAssociationValue', $this->lazyObject->getProtectedAssociation()); self::assertSame('protectedAssociationValue', $this->lazyObject->getProtectedAssociation()); } public function testLazyLoadingTriggeredOnlyAtFirstPublicPropertyRead() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__get', ['publicPersistentField']], function () use ($test) { $test->setProxyValue('publicPersistentField', 'loadedValue'); $test->setProxyValue('publicAssociation', 'publicAssociationValue'); } ); self::assertSame('loadedValue', $this->lazyObject->publicPersistentField); self::assertSame('publicAssociationValue', $this->lazyObject->publicAssociation); } public function testNoticeWhenReadingNonExistentPublicProperties() { $this->configureInitializerMock(0); $class = get_class($this->lazyObject); $this->expectException(Notice::class); $this->expectExceptionMessage('Undefined property: ' . $class . '::$non_existing_property'); $this->lazyObject->non_existing_property; } public function testFalseWhenCheckingNonExistentProperty() { $this->configureInitializerMock(0); self::assertFalse(isset($this->lazyObject->non_existing_property)); } public function testNoErrorWhenSettingNonExistentProperty() { $this->configureInitializerMock(0); $this->lazyObject->non_existing_property = 'now has a value'; self::assertSame('now has a value', $this->lazyObject->non_existing_property); } public function testCloningCallsClonerWithClonedObject() { $lazyObject = $this->lazyObject; $test = $this; $cb = $this->getMockBuilder(stdClass::class)->setMethods(['cb'])->getMock(); $cb ->expects($this->once()) ->method('cb') ->will($this->returnCallback(function (LazyLoadableObjectWithTypedProperties $proxy) use ($lazyObject, $test) { /** @var LazyLoadableObjectWithTypedProperties&Proxy $proxy */ $proxy = $proxy; $test->assertNotSame($proxy, $lazyObject); $proxy->__setInitializer(null); $proxy->publicAssociation = 'clonedAssociation'; })); $this->lazyObject->__setCloner($this->getClosure([$cb, 'cb'])); $cloned = clone $this->lazyObject; self::assertSame('clonedAssociation', $cloned->publicAssociation); self::assertNotSame($cloned, $lazyObject, 'a clone of the lazy object is retrieved'); } public function testFetchingTransientPropertiesWillNotTriggerLazyLoading() { $this->configureInitializerMock(0); self::assertSame( 'publicTransientFieldValue', $this->lazyObject->publicTransientField, 'fetching public transient field won\'t trigger lazy loading' ); $property = $this ->lazyLoadableObjectMetadata ->getReflectionClass() ->getProperty('protectedTransientField'); $property->setAccessible(true); self::assertSame( 'protectedTransientFieldValue', $property->getValue($this->lazyObject), 'fetching protected transient field via reflection won\'t trigger lazy loading' ); } /** * Provided to guarantee backwards compatibility */ public function testLoadProxyMethod() { $this->configureInitializerMock(2, [$this->lazyObject, '__load', []]); $this->lazyObject->__load(); $this->lazyObject->__load(); } public function testLoadingWithPersisterWillBeTriggeredOnlyOnce() { $this ->proxyLoader ->expects($this->once()) ->method('load') ->with( [ 'publicIdentifierField' => 'publicIdentifierFieldValue', 'protectedIdentifierField' => 'protectedIdentifierFieldValue', ], $this->lazyObject ) ->will($this->returnCallback(function ($id, LazyLoadableObjectWithTypedProperties $lazyObject) { // setting a value to verify that the persister can actually set something in the object $lazyObject->publicAssociation = $id['publicIdentifierField'] . '-test'; return true; })); $this->lazyObject->__setInitializer($this->getSuggestedInitializerImplementation()); $this->lazyObject->__load(); $this->lazyObject->__load(); self::assertSame('publicIdentifierFieldValue-test', $this->lazyObject->publicAssociation); } public function testFailedLoadingWillThrowException() { $this->proxyLoader->expects($this->any())->method('load')->will($this->returnValue(null)); $this->expectException(\UnexpectedValueException::class); $this->lazyObject->__setInitializer($this->getSuggestedInitializerImplementation()); $this->lazyObject->__load(); } public function testCloningWithPersister() { $this->lazyObject->publicTransientField = 'should-not-change'; $this ->proxyLoader ->expects($this->exactly(2)) ->method('load') ->with([ 'publicIdentifierField' => 'publicIdentifierFieldValue', 'protectedIdentifierField' => 'protectedIdentifierFieldValue', ]) ->will($this->returnCallback(function () { $blueprint = new LazyLoadableObjectWithTypedProperties(); $blueprint->publicPersistentField = 'checked-persistent-field'; $blueprint->publicAssociation = 'checked-association-field'; $blueprint->publicTransientField = 'checked-transient-field'; return $blueprint; })); $firstClone = clone $this->lazyObject; self::assertSame( 'checked-persistent-field', $firstClone->publicPersistentField, 'Persistent fields are cloned correctly' ); self::assertSame( 'checked-association-field', $firstClone->publicAssociation, 'Associations are cloned correctly' ); self::assertSame( 'should-not-change', $firstClone->publicTransientField, 'Transient fields are not overwritten' ); $secondClone = clone $this->lazyObject; self::assertSame( 'checked-persistent-field', $secondClone->publicPersistentField, 'Persistent fields are cloned correctly' ); self::assertSame( 'checked-association-field', $secondClone->publicAssociation, 'Associations are cloned correctly' ); self::assertSame( 'should-not-change', $secondClone->publicTransientField, 'Transient fields are not overwritten' ); // those should not trigger lazy loading $firstClone->__load(); $secondClone->__load(); } public function testNotInitializedProxyUnserialization() { $this->configureInitializerMock(); $serialized = serialize($this->lazyObject); /** @var LazyLoadableObjectWithTypedProperties&Proxy $unserialized */ $unserialized = unserialize($serialized); $reflClass = $this->lazyLoadableObjectMetadata->getReflectionClass(); self::assertFalse($unserialized->__isInitialized(), 'serialization didn\'t cause intialization'); // Checking identifiers self::assertSame('publicIdentifierFieldValue', $unserialized->publicIdentifierField, 'identifiers are kept'); $protectedIdentifierField = $reflClass->getProperty('protectedIdentifierField'); $protectedIdentifierField->setAccessible(true); self::assertSame( 'protectedIdentifierFieldValue', $protectedIdentifierField->getValue($unserialized), 'identifiers are kept' ); // Checking transient fields self::assertSame( 'publicTransientFieldValue', $unserialized->publicTransientField, 'transient fields are kept' ); $protectedTransientField = $reflClass->getProperty('protectedTransientField'); $protectedTransientField->setAccessible(true); self::assertSame( 'protectedTransientFieldValue', $protectedTransientField->getValue($unserialized), 'transient fields are kept' ); // Checking persistent fields self::assertSame( 'publicPersistentFieldValue', $unserialized->publicPersistentField, 'persistent fields are kept' ); $protectedPersistentField = $reflClass->getProperty('protectedPersistentField'); $protectedPersistentField->setAccessible(true); self::assertSame( 'protectedPersistentFieldValue', $protectedPersistentField->getValue($unserialized), 'persistent fields are kept' ); // Checking associations self::assertSame('publicAssociationValue', $unserialized->publicAssociation, 'associations are kept'); $protectedAssociationField = $reflClass->getProperty('protectedAssociation'); $protectedAssociationField->setAccessible(true); self::assertSame( 'protectedAssociationValue', $protectedAssociationField->getValue($unserialized), 'associations are kept' ); } public function testInitializedProxyUnserialization() { // persister will retrieve the lazy object itself, so that we don't have to re-define all field values $this->proxyLoader->expects($this->once())->method('load')->will($this->returnValue($this->lazyObject)); $this->lazyObject->__setInitializer($this->getSuggestedInitializerImplementation()); $this->lazyObject->__load(); $serialized = serialize($this->lazyObject); $reflClass = $this->lazyLoadableObjectMetadata->getReflectionClass(); /** @var LazyLoadableObjectWithTypedProperties&Proxy $unserialized */ $unserialized = unserialize($serialized); self::assertTrue($unserialized->__isInitialized(), 'serialization didn\'t cause intialization'); // Checking transient fields self::assertSame( 'publicTransientFieldValue', $unserialized->publicTransientField, 'transient fields are kept' ); $protectedTransientField = $reflClass->getProperty('protectedTransientField'); $protectedTransientField->setAccessible(true); self::assertSame( 'protectedTransientFieldValue', $protectedTransientField->getValue($unserialized), 'transient fields are kept' ); // Checking persistent fields self::assertSame( 'publicPersistentFieldValue', $unserialized->publicPersistentField, 'persistent fields are kept' ); $protectedPersistentField = $reflClass->getProperty('protectedPersistentField'); $protectedPersistentField->setAccessible(true); self::assertSame( 'protectedPersistentFieldValue', $protectedPersistentField->getValue($unserialized), 'persistent fields are kept' ); // Checking identifiers self::assertSame( 'publicIdentifierFieldValue', $unserialized->publicIdentifierField, 'identifiers are kept' ); $protectedIdentifierField = $reflClass->getProperty('protectedIdentifierField'); $protectedIdentifierField->setAccessible(true); self::assertSame( 'protectedIdentifierFieldValue', $protectedIdentifierField->getValue($unserialized), 'identifiers are kept' ); // Checking associations self::assertSame('publicAssociationValue', $unserialized->publicAssociation, 'associations are kept'); $protectedAssociationField = $reflClass->getProperty('protectedAssociation'); $protectedAssociationField->setAccessible(true); self::assertSame( 'protectedAssociationValue', $protectedAssociationField->getValue($unserialized), 'associations are kept' ); } public function testInitializationRestoresDefaultPublicLazyLoadedFieldValues() { // setting noop persister $this->proxyLoader->expects($this->once())->method('load')->will($this->returnValue($this->lazyObject)); $this->lazyObject->__setInitializer($this->getSuggestedInitializerImplementation()); self::assertSame( 'publicPersistentFieldValue', $this->lazyObject->publicPersistentField, 'Persistent field is restored to default value' ); self::assertSame( 'publicAssociationValue', $this->lazyObject->publicAssociation, 'Association is restored to default value' ); } public function testSettingPublicFieldsCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__set', ['publicPersistentField', 'newPublicPersistentFieldValue']], function () use ($test) { $test->setProxyValue('publicPersistentField', 'overrideValue'); $test->setProxyValue('publicAssociation', 'newAssociationValue'); } ); $this->lazyObject->publicPersistentField = 'newPublicPersistentFieldValue'; self::assertSame('newPublicPersistentFieldValue', $this->lazyObject->publicPersistentField); self::assertSame('newAssociationValue', $this->lazyObject->publicAssociation); } public function testSettingPublicAssociationCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__set', ['publicAssociation', 'newPublicAssociationValue']], function () use ($test) { $test->setProxyValue('publicPersistentField', 'newPublicPersistentFieldValue'); $test->setProxyValue('publicAssociation', 'overrideValue'); } ); $this->lazyObject->publicAssociation = 'newPublicAssociationValue'; self::assertSame('newPublicAssociationValue', $this->lazyObject->publicAssociation); self::assertSame('newPublicPersistentFieldValue', $this->lazyObject->publicPersistentField); } public function testCheckingPublicFieldsCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__isset', ['publicPersistentField']], function () use ($test) { $test->setProxyValue('publicPersistentField', null); $test->setProxyValue('publicAssociation', 'setPublicAssociation'); } ); self::assertFalse(isset($this->lazyObject->publicPersistentField)); self::assertNull($this->lazyObject->publicPersistentField); self::assertTrue(isset($this->lazyObject->publicAssociation)); self::assertSame('setPublicAssociation', $this->lazyObject->publicAssociation); } public function testCheckingPublicAssociationCausesLazyLoading() { $test = $this; $this->configureInitializerMock( 1, [$this->lazyObject, '__isset', ['publicAssociation']], function () use ($test) { $test->setProxyValue('publicPersistentField', 'newPersistentFieldValue'); $test->setProxyValue('publicAssociation', 'setPublicAssociation'); } ); self::assertTrue(isset($this->lazyObject->publicAssociation)); self::assertSame('setPublicAssociation', $this->lazyObject->publicAssociation); self::assertTrue(isset($this->lazyObject->publicPersistentField)); self::assertSame('newPersistentFieldValue', $this->lazyObject->publicPersistentField); } public function testCallingVariadicMethodCausesLazyLoading() { $proxyClassName = 'Doctrine\Tests\Common\ProxyProxy\__CG__\Doctrine\Tests\Common\Proxy\VariadicTypeHintClass'; /* @var ClassMetadata&\PHPUnit\Framework\MockObject\MockObject $metadata */ $metadata = $this->createMock(ClassMetadata::class); $metadata ->expects($this->any()) ->method('getName') ->will($this->returnValue(VariadicTypeHintClass::class)); $metadata ->expects($this->any()) ->method('getReflectionClass') ->will($this->returnValue(new \ReflectionClass(VariadicTypeHintClass::class))); // creating the proxy class if ( ! class_exists($proxyClassName, false)) { $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $proxyGenerator->generateProxyClass($metadata, $proxyGenerator->getProxyFileName($metadata->getName())); require_once $proxyGenerator->getProxyFileName($metadata->getName()); } /** @var callable&\PHPUnit\Framework\MockObject\MockObject $invocationMock */ $invocationMock = $this->getMockBuilder(stdClass::class)->setMethods(['__invoke'])->getMock(); /** @var VariadicTypeHintClass $lazyObject */ $lazyObject = new $proxyClassName( function ($proxy, $method, $parameters) use ($invocationMock) { $invocationMock($proxy, $method, $parameters); }, function () { } ); $invocationMock ->expects($this->at(0)) ->method('__invoke') ->with($lazyObject, 'addType', [['type1', 'type2']]); $invocationMock ->expects($this->at(1)) ->method('__invoke') ->with($lazyObject, 'addTypeWithMultipleParameters', ['foo', 'bar', ['baz1', 'baz2']]); $lazyObject->addType('type1', 'type2'); self::assertSame(['type1', 'type2'], $lazyObject->types); $lazyObject->addTypeWithMultipleParameters('foo', 'bar', 'baz1', 'baz2'); self::assertSame('foo', $lazyObject->foo); self::assertSame('bar', $lazyObject->bar); self::assertSame(['baz1', 'baz2'], $lazyObject->baz); } /** * Converts a given callable into a closure * * @param callable $callable * @return \Closure */ public function getClosure($callable) { return function () use ($callable) { call_user_func_array($callable, func_get_args()); }; } /** * Configures the current initializer callback mock with provided matcher params * * @param int $expectedCallCount the number of invocations to be expected. If a value< 0 is provided, `any` is used * @param array $callParamsMatch an ordered array of parameters to be expected * @param \Closure $callbackClosure a return callback closure * * @return void */ protected function configureInitializerMock( $expectedCallCount = 0, array $callParamsMatch = null, \Closure $callbackClosure = null ) { if ( ! $expectedCallCount) { $invocationCountMatcher = $this->exactly((int) $expectedCallCount); } else { $invocationCountMatcher = $expectedCallCount < 0 ? $this->any() : $this->exactly($expectedCallCount); } $invocationMocker = $this->initializerCallbackMock->expects($invocationCountMatcher)->method('__invoke'); if (null !== $callParamsMatch) { call_user_func_array([$invocationMocker, 'with'], $callParamsMatch); } if ($callbackClosure) { $invocationMocker->will($this->returnCallback($callbackClosure)); } } /** * Sets a value in the current proxy object without triggering lazy loading through `__set` * * @link https://bugs.php.net/bug.php?id=63463 * * @param string $property * @param mixed $value */ public function setProxyValue($property, $value) { $reflectionProperty = new \ReflectionProperty($this->lazyObject, $property); $initializer = $this->lazyObject->__getInitializer(); // disabling initializer since setting `publicPersistentField` triggers `__set`/`__get` $this->lazyObject->__setInitializer(null); $reflectionProperty->setValue($this->lazyObject, $value); $this->lazyObject->__setInitializer($initializer); } /** * Retrieves the suggested implementation of an initializer that proxy factories in O*M * are currently following, and that should be used to initialize the current proxy object * * @return \Closure */ protected function getSuggestedInitializerImplementation() { $loader = $this->proxyLoader; $identifier = $this->identifier; return function (LazyLoadableObjectWithTypedProperties $proxy) use ($loader, $identifier) { /** @var LazyLoadableObjectWithTypedProperties&Proxy $proxy */ $proxy = $proxy; $proxy->__setInitializer(null); $proxy->__setCloner(null); if ($proxy->__isInitialized()) { return; } $properties = $proxy->__getLazyProperties(); foreach ($properties as $propertyName => $property) { if ( ! isset($proxy->$propertyName)) { $proxy->$propertyName = $properties[$propertyName]; } } $proxy->__setInitialized(true); if (method_exists($proxy, '__wakeup')) { $proxy->__wakeup(); } if (null === $loader->load($identifier, $proxy)) { throw new \UnexpectedValueException('Couldn\'t load'); } }; } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/ProxyLogicVoidReturnTypeTest.php000066400000000000000000000103511360676402100324030ustar00rootroot00000000000000 * @author Jan Langer */ class ProxyLogicVoidReturnTypeTest extends \PHPUnit\Framework\TestCase { /** * @var \PHPUnit\Framework\MockObject\MockObject&stdClass */ protected $proxyLoader; /** * @var ClassMetadata */ protected $lazyLoadableObjectMetadata; /** * @var LazyLoadableObjectWithVoid&Proxy */ protected $lazyObject; /** * @var \PHPUnit\Framework\MockObject\MockObject&callable */ protected $initializerCallbackMock; /** * {@inheritDoc} */ public function setUp(): void { $this->proxyLoader = $loader = $this->getMockBuilder(stdClass::class)->setMethods(['load'])->getMock(); $this->initializerCallbackMock = $this->getMockBuilder(stdClass::class)->setMethods(['__invoke'])->getMock(); $this->lazyLoadableObjectMetadata = $metadata = new LazyLoadableObjectWithVoidClassMetadata(); $proxyClassName = 'Doctrine\Tests\Common\ProxyProxy\__CG__\Doctrine\Tests\Common\Proxy\LazyLoadableObjectWithVoid'; // creating the proxy class if ( ! class_exists($proxyClassName, false)) { $proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy'); $proxyFileName = $proxyGenerator->getProxyFileName($metadata->getName()); $proxyGenerator->generateProxyClass($metadata, $proxyFileName); require_once $proxyFileName; } $this->lazyObject = new $proxyClassName($this->getClosure($this->initializerCallbackMock)); self::assertFalse($this->lazyObject->__isInitialized()); } public function testParentVoidMethodIsCalledWithoutParameters() { $this->configureInitializerMock( 1, [$this->lazyObject, 'incrementingAndReturningVoid', []], function () { } ); self::assertNull($this->lazyObject->incrementingAndReturningVoid()); self::assertSame(1, $this->lazyObject->value); } public function testParentVoidMethodIsCalledWithParameters() { $this->configureInitializerMock( 1, [$this->lazyObject, 'addingAndReturningVoid', [10]], function () { } ); self::assertNull($this->lazyObject->addingAndReturningVoid(10)); self::assertSame(10, $this->lazyObject->value); } /** * Converts a given callable into a closure * * @param callable $callable * @return \Closure */ private function getClosure($callable) { return function () use ($callable) { call_user_func_array($callable, func_get_args()); }; } /** * Configures the current initializer callback mock with provided matcher params * * @param int $expectedCallCount the number of invocations to be expected. If a value< 0 is provided, `any` is used * @param array $callParamsMatch an ordered array of parameters to be expected * @param \Closure $callbackClosure a return callback closure * * @return void */ private function configureInitializerMock( $expectedCallCount = 0, array $callParamsMatch = null, \Closure $callbackClosure = null ) { if ( ! $expectedCallCount) { $invocationCountMatcher = $this->exactly((int) $expectedCallCount); } else { $invocationCountMatcher = $expectedCallCount < 0 ? $this->any() : $this->exactly($expectedCallCount); } $invocationMocker = $this->initializerCallbackMock->expects($invocationCountMatcher)->method('__invoke'); if (null !== $callParamsMatch) { call_user_func_array([$invocationMocker, 'with'], $callParamsMatch); } if ($callbackClosure) { $invocationMocker->will($this->returnCallback($callbackClosure)); } } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/ProxyMagicMethodsTest.php000066400000000000000000000225071360676402100310340ustar00rootroot00000000000000 */ class ProxyMagicMethodsTest extends \PHPUnit\Framework\TestCase { /** * @var \Doctrine\Common\Proxy\ProxyGenerator */ protected $proxyGenerator; /** * @var LazyLoadableObject|Proxy */ protected $lazyObject; protected $identifier = [ 'publicIdentifierField' => 'publicIdentifierFieldValue', 'protectedIdentifierField' => 'protectedIdentifierFieldValue', ]; /** * @var \PHPUnit\Framework\MockObject\MockObject#Callable */ protected $initializerCallbackMock; /** * {@inheritDoc} */ public function setUp(): void { $this->proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . '\\MagicMethodProxy'); } public static function tearDownAfterClass(): void { } public function testInheritedMagicGet() { $proxyClassName = $this->generateProxyClass(MagicGetClass::class); $proxy = new $proxyClassName( function (Proxy $proxy, $method, $params) use (&$counter) { if ( ! in_array($params[0], ['publicField', 'test', 'notDefined'])) { throw new InvalidArgumentException('Unexpected access to field "' . $params[0] . '"'); } $initializer = $proxy->__getInitializer(); $proxy->__setInitializer(null); $proxy->publicField = 'modifiedPublicField'; $counter += 1; $proxy->__setInitializer($initializer); } ); self::assertSame('id', $proxy->id); self::assertSame('modifiedPublicField', $proxy->publicField); self::assertSame('test', $proxy->test); self::assertSame('not defined', $proxy->notDefined); self::assertSame(3, $counter); } /** * @group DCOM-194 */ public function testInheritedMagicGetByRef() { $proxyClassName = $this->generateProxyClass(MagicGetByRefClass::class); /* @var $proxy \Doctrine\Tests\Common\Proxy\MagicGetByRefClass */ $proxy = new $proxyClassName(); $proxy->valueField = 123; $value = & $proxy->__get('value'); self::assertSame(123, $value); $value = 456; self::assertSame(456, $proxy->__get('value'), 'Value was fetched by reference'); $this->expectException(InvalidArgumentException::class); $undefined = $proxy->nonExisting; } public function testInheritedMagicSet() { $proxyClassName = $this->generateProxyClass(MagicSetClass::class); $proxy = new $proxyClassName( function (Proxy $proxy, $method, $params) use (&$counter) { if ( ! in_array($params[0], ['publicField', 'test', 'notDefined'])) { throw new InvalidArgumentException('Unexpected access to field "' . $params[0] . '"'); } $counter += 1; } ); self::assertSame('id', $proxy->id); $proxy->publicField = 'publicFieldValue'; self::assertSame('publicFieldValue', $proxy->publicField); $proxy->test = 'testValue'; self::assertSame('testValue', $proxy->testAttribute); $proxy->notDefined = 'not defined'; self::assertSame('not defined', $proxy->testAttribute); self::assertSame(3, $counter); } public function testInheritedMagicSleep() { $proxyClassName = $this->generateProxyClass(MagicSleepClass::class); $proxy = new $proxyClassName(); self::assertSame('defaultValue', $proxy->serializedField); self::assertSame('defaultValue', $proxy->nonSerializedField); $proxy->serializedField = 'changedValue'; $proxy->nonSerializedField = 'changedValue'; $unserialized = unserialize(serialize($proxy)); self::assertSame('changedValue', $unserialized->serializedField); self::assertSame('defaultValue', $unserialized->nonSerializedField, 'Field was not returned by "__sleep"'); } public function testInheritedMagicWakeup() { $proxyClassName = $this->generateProxyClass(MagicWakeupClass::class); $proxy = new $proxyClassName(); self::assertSame('defaultValue', $proxy->wakeupValue); $proxy->wakeupValue = 'changedValue'; $unserialized = unserialize(serialize($proxy)); self::assertSame('newWakeupValue', $unserialized->wakeupValue, '"__wakeup" was called'); $unserialized->__setInitializer(function (Proxy $proxy) { $proxy->__setInitializer(null); $proxy->publicField = 'newPublicFieldValue'; }); self::assertSame('newPublicFieldValue', $unserialized->publicField, 'Proxy can still be initialized'); } public function testInheritedMagicIsset() { $proxyClassName = $this->generateProxyClass(MagicIssetClass::class); $proxy = new $proxyClassName(function (Proxy $proxy, $method, $params) use (&$counter) { if (in_array($params[0], ['publicField', 'test', 'nonExisting'])) { $initializer = $proxy->__getInitializer(); $proxy->__setInitializer(null); $proxy->publicField = 'modifiedPublicField'; $counter += 1; $proxy->__setInitializer($initializer); return; } throw new InvalidArgumentException( sprintf('Should not be initialized when checking isset("%s")', $params[0]) ); }); self::assertTrue(isset($proxy->id)); self::assertTrue(isset($proxy->publicField)); self::assertTrue(isset($proxy->test)); self::assertFalse(isset($proxy->nonExisting)); self::assertSame(3, $counter); } public function testInheritedMagicClone() { $proxyClassName = $this->generateProxyClass(MagicCloneClass::class); $proxy = new $proxyClassName( null, function ($proxy) { $proxy->cloned = true; } ); $cloned = clone $proxy; self::assertSame('newClonedValue', $cloned->clonedValue); self::assertFalse($proxy->cloned); self::assertTrue($cloned->cloned); } /** * @group DCOM-175 */ public function testClonesPrivateProperties() { $proxyClassName = $this->generateProxyClass(SerializedClass::class); /* @var $proxy SerializedClass */ $proxy = new $proxyClassName(); $proxy->setFoo(1); $proxy->setBar(2); $proxy->setBaz(3); $unserialized = unserialize(serialize($proxy)); self::assertSame(1, $unserialized->getFoo()); self::assertSame(2, $unserialized->getBar()); self::assertSame(3, $unserialized->getBaz()); } /** * @param string $className * * @return string */ private function generateProxyClass($className) { $proxyClassName = 'Doctrine\\Tests\\Common\\Proxy\\MagicMethodProxy\\__CG__\\' . $className; if (class_exists($proxyClassName, false)) { return $proxyClassName; } $metadata = $this->createMock(ClassMetadata::class); $metadata ->expects($this->any()) ->method('getName') ->will($this->returnValue($className)); $metadata ->expects($this->any()) ->method('getIdentifier') ->will($this->returnValue(['id'])); $metadata ->expects($this->any()) ->method('getReflectionClass') ->will($this->returnValue(new ReflectionClass($className))); $metadata ->expects($this->any()) ->method('isIdentifier') ->will($this->returnCallback(function ($fieldName) { return 'id' === $fieldName; })); $metadata ->expects($this->any()) ->method('hasField') ->will($this->returnCallback(function ($fieldName) { return in_array($fieldName, ['id', 'publicField']); })); $metadata ->expects($this->any()) ->method('hasAssociation') ->will($this->returnValue(false)); $metadata ->expects($this->any()) ->method('getFieldNames') ->will($this->returnValue(['id', 'publicField'])); $metadata ->expects($this->any()) ->method('getIdentifierFieldNames') ->will($this->returnValue(['id'])); $metadata ->expects($this->any()) ->method('getAssociationNames') ->will($this->returnValue([])); $metadata ->expects($this->any()) ->method('getTypeOfField') ->will($this->returnValue('string')); $this->proxyGenerator->generateProxyClass($metadata, $this->proxyGenerator->getProxyFileName($className)); require_once $this->proxyGenerator->getProxyFileName($className); return $proxyClassName; } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/ReturnTypesClass.php000066400000000000000000000010371360676402100300530ustar00rootroot00000000000000foo = $foo; } /** * @return mixed|string */ public function getFoo() { return $this->foo; } /** * @param $bar */ public function setBar($bar) { $this->bar = $bar; } /** * @return mixed|string */ public function getBar() { return $this->bar; } /** * @param $baz */ public function setBaz($baz) { $this->baz = $baz; } /** * @return mixed|string */ public function getBaz() { return $this->baz; } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/SleepClass.php000066400000000000000000000003271360676402100266200ustar00rootroot00000000000000types = $types; } public function addTypeWithMultipleParameters($foo, $bar, ...$baz) { $this->foo = $foo; $this->bar = $bar; $this->baz = $baz; } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Proxy/VoidReturnTypeClass.php000066400000000000000000000002471360676402100305140ustar00rootroot00000000000000getName()); } /** * @dataProvider dataGetClass */ public function testNewReflectionObject($className, $expectedClassName) { $object = new $className; $reflClass = ClassUtils::newReflectionObject($object); self::assertEquals($expectedClassName, $reflClass->getName()); } } class ChildObject extends \stdClass { } } namespace MyProject\Proxies\__CG__ { class stdClass extends \stdClass { } } namespace MyProject\Proxies\__CG__\Doctrine\Tests\Common\Util { class ChildObject extends \Doctrine\Tests\Common\Util\ChildObject { } } namespace MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__ { class stdClass extends \MyProject\Proxies\__CG__\stdClass { } } namespace MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\Doctrine\Tests\Common\Util { class ChildObject extends \MyProject\Proxies\__CG__\Doctrine\Tests\Common\Util\ChildObject { } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Util/DebugTest.php000066400000000000000000000111161360676402100262420ustar00rootroot00000000000000foo = "bar"; $obj->bar = 1234; $var = Debug::export($obj, 2); self::assertEquals("stdClass", $var->__CLASS__); } public function testExportObjectWithReference() { $foo = 'bar'; $bar = ['foo' => & $foo]; $baz = (object) $bar; $var = Debug::export($baz, 2); $baz->foo = 'tab'; self::assertEquals('bar', $var->foo); self::assertEquals('tab', $bar['foo']); } public function testExportArray() { $array = ['a' => 'b', 'b' => ['c', 'd' => ['e', 'f']]]; $var = Debug::export($array, 2); $expected = $array; $expected['b']['d'] = 'Array(2)'; self::assertEquals($expected, $var); } public function testExportDateTime() { $obj = new \DateTime('2010-10-10 10:10:10', new \DateTimeZone('UTC')); $var = Debug::export($obj, 2); self::assertEquals('DateTime', $var->__CLASS__); self::assertEquals('2010-10-10T10:10:10+00:00', $var->date); } public function testExportDateTimeImmutable() { $obj = new \DateTimeImmutable('2010-10-10 10:10:10', new \DateTimeZone('UTC')); $var = Debug::export($obj, 2); self::assertEquals('DateTimeImmutable', $var->__CLASS__); self::assertEquals('2010-10-10T10:10:10+00:00', $var->date); } public function testExportDateTimeZone() { $obj = new \DateTimeImmutable('2010-10-10 12:34:56', new \DateTimeZone('Europe/Rome')); $var = Debug::export($obj, 2); self::assertEquals('DateTimeImmutable', $var->__CLASS__); self::assertEquals('2010-10-10T12:34:56+02:00', $var->date); } public function testExportArrayTraversable() { $obj = new \ArrayObject(['foobar']); $var = Debug::export($obj, 2); self::assertContains('foobar', $var->__STORAGE__); $it = new \ArrayIterator(['foobar']); $var = Debug::export($it, 5); self::assertContains('foobar', $var->__STORAGE__); } public function testReturnsOutput() { ob_start(); $dump = Debug::dump('foo'); $outputValue = ob_get_contents(); ob_end_clean(); self::assertSame($outputValue, $dump); } public function testDisablesOutput() { ob_start(); $dump = Debug::dump('foo', 2, true, false); $outputValue = ob_get_contents(); ob_end_clean(); self::assertEmpty($outputValue); self::assertNotSame($outputValue, $dump); } /** * @dataProvider provideAttributesCases */ public function testExportParentAttributes(TestAsset\ParentClass $class, array $expected) { $print_r_class = print_r($class, true); $print_r_expected = print_r($expected, true); $print_r_class = substr($print_r_class, strpos($print_r_class, '(')); $print_r_expected = substr($print_r_expected, strpos($print_r_expected, '(')); self::assertSame($print_r_class, $print_r_expected); $var = Debug::export($class, 3); $var = (array) $var; unset($var['__CLASS__']); self::assertSame($expected, $var); } public function provideAttributesCases() { return array( 'different-attributes' => array( new TestAsset\ChildClass(), array( 'childPublicAttribute' => 4, 'childProtectedAttribute:protected' => 5, 'childPrivateAttribute:Doctrine\Tests\Common\Util\TestAsset\ChildClass:private' => 6, 'parentPublicAttribute' => 1, 'parentProtectedAttribute:protected' => 2, 'parentPrivateAttribute:Doctrine\Tests\Common\Util\TestAsset\ParentClass:private' => 3, ), ), 'same-attributes' => array( new TestAsset\ChildWithSameAttributesClass(), array( 'parentPublicAttribute' => 4, 'parentProtectedAttribute:protected' => 5, 'parentPrivateAttribute:Doctrine\Tests\Common\Util\TestAsset\ChildWithSameAttributesClass:private' => 6, 'parentPrivateAttribute:Doctrine\Tests\Common\Util\TestAsset\ParentClass:private' => 3, ), ), ); } } php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Util/TestAsset/000077500000000000000000000000001360676402100255625ustar00rootroot00000000000000php-doctrine-common-2.12.0/tests/Doctrine/Tests/Common/Util/TestAsset/ChildClass.php000066400000000000000000000003531360676402100303050ustar00rootroot00000000000000