diff options
Diffstat (limited to 'vendor/doctrine/persistence')
44 files changed, 4128 insertions, 0 deletions
diff --git a/vendor/doctrine/persistence/.doctrine-project.json b/vendor/doctrine/persistence/.doctrine-project.json new file mode 100644 index 0000000..23e2906 --- /dev/null +++ b/vendor/doctrine/persistence/.doctrine-project.json @@ -0,0 +1,60 @@ +{ + "active": true, + "name": "Persistence", + "slug": "persistence", + "docsSlug": "doctrine-persistence", + "versions": [ + { + "name": "3.0", + "branchName": "3.0.x", + "slug": "latest", + "upcoming": true + }, + { + "name": "2.1", + "branchName": "2.1.x", + "slug": "2.1", + "upcoming": true + }, + { + "name": "2.0", + "branchName": "2.0.x", + "slug": "2.0", + "current": true, + "aliases": [ + "current", + "stable" + ] + }, + { + "name": "1.4", + "branchName": "1.4.x", + "slug": "1.4", + "maintained": false + }, + { + "name": "1.3", + "branchName": "1.3.x", + "slug": "1.3", + "maintained": false + }, + { + "name": "1.2", + "branchName": "1.2.x", + "slug": "1.2", + "maintained": false + }, + { + "name": "1.1", + "branchName": "1.1.x", + "slug": "1.1", + "maintained": false + }, + { + "name": "1.0", + "branchName": "1.0.x", + "slug": "1.0", + "maintained": false + } + ] +} diff --git a/vendor/doctrine/persistence/.github/workflows/coding-standards.yml b/vendor/doctrine/persistence/.github/workflows/coding-standards.yml new file mode 100644 index 0000000..18fcfa0 --- /dev/null +++ b/vendor/doctrine/persistence/.github/workflows/coding-standards.yml @@ -0,0 +1,50 @@ + +name: "Coding Standards" + +on: + pull_request: + branches: + - "*.x" + - "master" + push: + branches: + - "*.x" + - "master" + +env: + COMPOSER_ROOT_VERSION: "2.1" + +jobs: + coding-standards: + name: "Coding Standards" + runs-on: "ubuntu-20.04" + + strategy: + matrix: + php-version: + - "7.4" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + tools: "cs2pr" + + - name: "Cache dependencies installed with Composer" + uses: "actions/cache@v2" + with: + path: "~/.composer/cache" + key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-locked-" + + - name: "Install dependencies with Composer" + run: "composer install --no-interaction --no-progress --no-suggest" + + # https://github.com/doctrine/.github/issues/3 + - name: "Run PHP_CodeSniffer" + run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr" diff --git a/vendor/doctrine/persistence/.github/workflows/continuous-integration.yml b/vendor/doctrine/persistence/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..eb32fcb --- /dev/null +++ b/vendor/doctrine/persistence/.github/workflows/continuous-integration.yml @@ -0,0 +1,79 @@ + +name: "Continuous Integration" + +on: + pull_request: null + +env: + COMPOSER_ROOT_VERSION: "2.1" + +jobs: + phpunit: + name: "PHPUnit" + runs-on: "ubuntu-20.04" + + strategy: + matrix: + php-version: + - "7.1" + - "7.2" + - "7.3" + - "7.4" + - "8.0" + deps: + - "normal" + include: + - deps: "low" + php-version: "7.1" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + with: + fetch-depth: 2 + + - name: "Install PHP with pcov" + uses: "shivammathur/setup-php@v2" + if: "${{ matrix.php-version != '7.1' }}" + with: + php-version: "${{ matrix.php-version }}" + coverage: "pcov" + + - name: "Install PHP with xdebug" + uses: "shivammathur/setup-php@v2" + if: "${{ matrix.php-version == '7.1' }}" + with: + php-version: "${{ matrix.php-version }}" + coverage: "xdebug" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2" + with: + path: "~/.composer/cache" + key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-locked-" + + # Remove this block when + # https://github.com/felixfbecker/php-language-server-protocol/pull/15 is + # merged and released + - name: "Remove dependency on vimeo/psalm for PHP8" + run: "composer remove --dev --no-update vimeo/psalm" + if: "${{ matrix.php-version == '8.0' }}" + + - name: "Downgrade Composer" + run: "composer self-update --1" + if: "${{ matrix.php-version == '7.1' }}" + + - name: "Update dependencies with composer" + run: "composer update --no-interaction --no-progress --no-suggest" + if: "${{ matrix.deps == 'normal' }}" + + - name: "Install lowest possible dependencies with composer" + run: "composer update --no-interaction --no-progress --no-suggest --prefer-dist --prefer-lowest" + if: "${{ matrix.deps == 'low' }}" + + - name: "Run PHPUnit" + run: "vendor/bin/phpunit --coverage-clover=coverage.xml" + + - name: "Upload to Codecov" + uses: "codecov/codecov-action@v1" diff --git a/vendor/doctrine/persistence/.github/workflows/release-on-milestone-closed.yml b/vendor/doctrine/persistence/.github/workflows/release-on-milestone-closed.yml new file mode 100644 index 0000000..70ccbdb --- /dev/null +++ b/vendor/doctrine/persistence/.github/workflows/release-on-milestone-closed.yml @@ -0,0 +1,55 @@ +name: "Automatic Releases" + +on: + milestone: + types: + - "closed" + +jobs: + release: + name: "Git tag, release & create merge-up PR" + runs-on: "ubuntu-20.04" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Release" + uses: "laminas/automatic-releases@v1" + with: + command-name: "laminas:automatic-releases:release" + env: + "GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Create Merge-Up Pull Request" + uses: "laminas/automatic-releases@v1" + with: + command-name: "laminas:automatic-releases:create-merge-up-pull-request" + env: + "GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Create and/or Switch to new Release Branch" + uses: "laminas/automatic-releases@v1" + with: + command-name: "laminas:automatic-releases:switch-default-branch-to-next-minor" + env: + "GITHUB_TOKEN": ${{ secrets.ORGANIZATION_ADMIN_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Create new milestones" + uses: "laminas/automatic-releases@v1" + with: + command-name: "laminas:automatic-releases:create-milestones" + env: + "GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} diff --git a/vendor/doctrine/persistence/.github/workflows/static-analysis.yml b/vendor/doctrine/persistence/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..5288ee1 --- /dev/null +++ b/vendor/doctrine/persistence/.github/workflows/static-analysis.yml @@ -0,0 +1,64 @@ + +name: "Static Analysis" + +on: + pull_request: + branches: + - "*.x" + - "master" + push: + branches: + - "*.x" + - "master" +env: + COMPOSER_ROOT_VERSION: "2.1" + +jobs: + static-analysis-phpstan: + name: "Static Analysis with PHPStan" + runs-on: "ubuntu-20.04" + + strategy: + matrix: + php-version: + - "7.4" + + steps: + - name: "Checkout code" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + tools: "cs2pr" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2" + with: + path: "~/.composer/cache" + key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-locked-" + + - name: "Install dependencies with composer" + run: "composer install --no-interaction --no-progress --no-suggest" + + - name: "Run a static analysis with phpstan/phpstan" + run: "vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr" + + static-analysis-psalm: + name: "Static Analysis with Psalm" + runs-on: "ubuntu-20.04" + + strategy: + matrix: + php-version: + - "7.4" + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Psalm + uses: docker://vimeo/psalm-github-actions diff --git a/vendor/doctrine/persistence/LICENSE b/vendor/doctrine/persistence/LICENSE new file mode 100644 index 0000000..8c38cc1 --- /dev/null +++ b/vendor/doctrine/persistence/LICENSE @@ -0,0 +1,19 @@ +Copyright (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. diff --git a/vendor/doctrine/persistence/README.md b/vendor/doctrine/persistence/README.md new file mode 100644 index 0000000..a9f564e --- /dev/null +++ b/vendor/doctrine/persistence/README.md @@ -0,0 +1,12 @@ +# Doctrine Persistence + +[](https://travis-ci.org/doctrine/persistence) +[](https://codecov.io/gh/doctrine/persistence/branch/2.1.x) + +The Doctrine Persistence project is a library that provides common abstractions for object mapper persistence. + +## More resources: + +* [Website](https://www.doctrine-project.org/) +* [Documentation](https://www.doctrine-project.org/projects/doctrine-persistence/en/latest/index.html) +* [Downloads](https://github.com/doctrine/persistence/releases) diff --git a/vendor/doctrine/persistence/UPGRADE-1.2.md b/vendor/doctrine/persistence/UPGRADE-1.2.md new file mode 100644 index 0000000..0c0115d --- /dev/null +++ b/vendor/doctrine/persistence/UPGRADE-1.2.md @@ -0,0 +1,6 @@ +UPGRADE FROM 1.x to 1.2 +======================= + +* Deprecated `ObjectManager::merge()`. Please handle merge operations in your application instead. +* Deprecated `ObjectManager::detach()`. Please use `ObjectManager::clear()` instead. +* Deprecated `PersistentObject` class. Please implement this functionality directly in your application if you want ActiveRecord style functionality. diff --git a/vendor/doctrine/persistence/composer.json b/vendor/doctrine/persistence/composer.json new file mode 100644 index 0000000..ccf0b3d --- /dev/null +++ b/vendor/doctrine/persistence/composer.json @@ -0,0 +1,52 @@ +{ + "name": "doctrine/persistence", + "type": "library", + "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.", + "keywords": [ + "persistence", + "object", + "mapper", + "orm", + "odm" + ], + "homepage": "https://doctrine-project.org/projects/persistence.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 || ^8.0", + "doctrine/annotations": "^1.0", + "doctrine/cache": "^1.0", + "doctrine/collections": "^1.0", + "doctrine/event-manager": "^1.0" + }, + "require-dev": { + "composer/package-versions-deprecated": "^1.11", + "phpstan/phpstan": "^0.12", + "doctrine/coding-standard": "^6.0 || ^8.0", + "doctrine/common": "^3.0", + "phpunit/phpunit": "^7.5.20 || ^8.0 || ^9.0", + "vimeo/psalm": "^3.11" + }, + "conflict": { + "doctrine/common": "<2.10@dev" + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common", + "Doctrine\\Persistence\\": "lib/Doctrine/Persistence" + } + }, + "autoload-dev": { + "psr-4": { + "Doctrine\\Tests\\": "tests/Doctrine/Tests", + "Doctrine\\Tests_PHP74\\": "tests/Doctrine/Tests_PHP74" + } + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/PersistentObject.php b/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/PersistentObject.php new file mode 100644 index 0000000..d75f127 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/PersistentObject.php @@ -0,0 +1,238 @@ +<?php + +namespace Doctrine\Common\Persistence; + +use BadMethodCallException; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\ObjectManager; +use Doctrine\Persistence\ObjectManagerAware; +use InvalidArgumentException; +use RuntimeException; + +use function lcfirst; +use function substr; + +/** + * PersistentObject base class that implements getter/setter methods for all mapped fields and associations + * by overriding __call. + * + * This class is a forward compatible implementation of the PersistentObject trait. + * + * Limitations: + * + * 1. All persistent objects have to be associated with a single ObjectManager, multiple + * ObjectManagers are not supported. You can set the ObjectManager with `PersistentObject#setObjectManager()`. + * 2. Setters and getters only work if a ClassMetadata instance was injected into the PersistentObject. + * This is either done on `postLoad` of an object or by accessing the global object manager. + * 3. There are no hooks for setters/getters. Just implement the method yourself instead of relying on __call(). + * 4. Slower than handcoded implementations: An average of 7 method calls per access to a field and 11 for an association. + * 5. Only the inverse side associations get autoset on the owning side as well. Setting objects on the owning side + * will not set the inverse side associations. + * + * @deprecated Deprecated `PersistentObject` class in 1.2. Please implement this functionality + * directly in your application if you want ActiveRecord style functionality. + * + * @example + * + * PersistentObject::setObjectManager($em); + * + * class Foo extends PersistentObject + * { + * private $id; + * } + * + * $foo = new Foo(); + * $foo->getId(); // method exists through __call + */ +abstract class PersistentObject implements ObjectManagerAware +{ + /** @var ObjectManager|null */ + private static $objectManager = null; + + /** @var ClassMetadata|null */ + private $cm = null; + + /** + * Sets the object manager responsible for all persistent object base classes. + * + * @return void + */ + public static function setObjectManager(?ObjectManager $objectManager = null) + { + self::$objectManager = $objectManager; + } + + /** + * @return ObjectManager|null + */ + public static function getObjectManager() + { + return self::$objectManager; + } + + /** + * Injects the Doctrine Object Manager. + * + * @return void + * + * @throws RuntimeException + */ + public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata) + { + if ($objectManager !== self::$objectManager) { + throw new RuntimeException('Trying to use PersistentObject with different ObjectManager instances. ' . + 'Was PersistentObject::setObjectManager() called?'); + } + + $this->cm = $classMetadata; + } + + /** + * Sets a persistent fields value. + * + * @param string $field + * @param mixed[] $args + * + * @return void + * + * @throws BadMethodCallException When no persistent field exists by that name. + * @throws InvalidArgumentException When the wrong target object type is passed to an association. + */ + private function set($field, $args) + { + if ($this->cm->hasField($field) && ! $this->cm->isIdentifier($field)) { + $this->$field = $args[0]; + } elseif ($this->cm->hasAssociation($field) && $this->cm->isSingleValuedAssociation($field)) { + $targetClass = $this->cm->getAssociationTargetClass($field); + if (! ($args[0] instanceof $targetClass) && $args[0] !== null) { + throw new InvalidArgumentException("Expected persistent object of type '" . $targetClass . "'"); + } + + $this->$field = $args[0]; + $this->completeOwningSide($field, $targetClass, $args[0]); + } else { + throw new BadMethodCallException("no field with name '" . $field . "' exists on '" . $this->cm->getName() . "'"); + } + } + + /** + * Gets a persistent field value. + * + * @param string $field + * + * @return mixed + * + * @throws BadMethodCallException When no persistent field exists by that name. + */ + private function get($field) + { + if ($this->cm->hasField($field) || $this->cm->hasAssociation($field)) { + return $this->$field; + } + + throw new BadMethodCallException("no field with name '" . $field . "' exists on '" . $this->cm->getName() . "'"); + } + + /** + * If this is an inverse side association, completes the owning side. + * + * @param string $field + * @param ClassMetadata $targetClass + * @param object $targetObject + * + * @return void + */ + private function completeOwningSide($field, $targetClass, $targetObject) + { + // add this object on the owning side as well, for obvious infinite recursion + // reasons this is only done when called on the inverse side. + if (! $this->cm->isAssociationInverseSide($field)) { + return; + } + + $mappedByField = $this->cm->getAssociationMappedByTargetField($field); + $targetMetadata = self::$objectManager->getClassMetadata($targetClass); + + $setter = ($targetMetadata->isCollectionValuedAssociation($mappedByField) ? 'add' : 'set') . $mappedByField; + $targetObject->$setter($this); + } + + /** + * Adds an object to a collection. + * + * @param string $field + * @param mixed[] $args + * + * @return void + * + * @throws BadMethodCallException + * @throws InvalidArgumentException + */ + private function add($field, $args) + { + if (! $this->cm->hasAssociation($field) || ! $this->cm->isCollectionValuedAssociation($field)) { + throw new BadMethodCallException('There is no method add' . $field . '() on ' . $this->cm->getName()); + } + + $targetClass = $this->cm->getAssociationTargetClass($field); + if (! ($args[0] instanceof $targetClass)) { + throw new InvalidArgumentException("Expected persistent object of type '" . $targetClass . "'"); + } + + if (! ($this->$field instanceof Collection)) { + $this->$field = new ArrayCollection($this->$field ?: []); + } + + $this->$field->add($args[0]); + $this->completeOwningSide($field, $targetClass, $args[0]); + } + + /** + * Initializes Doctrine Metadata for this class. + * + * @return void + * + * @throws RuntimeException + */ + private function initializeDoctrine() + { + if ($this->cm !== null) { + return; + } + + if (! self::$objectManager) { + throw new RuntimeException('No runtime object manager set. Call PersistentObject#setObjectManager().'); + } + + $this->cm = self::$objectManager->getClassMetadata(static::class); + } + + /** + * Magic methods. + * + * @param string $method + * @param mixed[] $args + * + * @return mixed + * + * @throws BadMethodCallException + */ + public function __call($method, $args) + { + $this->initializeDoctrine(); + + $command = substr($method, 0, 3); + $field = lcfirst(substr($method, 3)); + if ($command === 'set') { + $this->set($field, $args); + } elseif ($command === 'get') { + return $this->get($field); + } elseif ($command === 'add') { + $this->add($field, $args); + } else { + throw new BadMethodCallException('There is no method ' . $method . ' on ' . $this->cm->getName()); + } + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/AbstractManagerRegistry.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/AbstractManagerRegistry.php new file mode 100644 index 0000000..63ff9b0 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/AbstractManagerRegistry.php @@ -0,0 +1,249 @@ +<?php + +namespace Doctrine\Persistence; + +use InvalidArgumentException; +use ReflectionClass; + +use function explode; +use function sprintf; +use function strpos; + +/** + * Abstract implementation of the ManagerRegistry contract. + */ +abstract class AbstractManagerRegistry implements ManagerRegistry +{ + /** @var string */ + private $name; + + /** @var string[] */ + private $connections; + + /** @var string[] */ + private $managers; + + /** @var string */ + private $defaultConnection; + + /** @var string */ + private $defaultManager; + + /** @var string */ + private $proxyInterfaceName; + + /** + * @param string $name + * @param string[] $connections + * @param string[] $managers + * @param string $defaultConnection + * @param string $defaultManager + * @param string $proxyInterfaceName + */ + public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName) + { + $this->name = $name; + $this->connections = $connections; + $this->managers = $managers; + $this->defaultConnection = $defaultConnection; + $this->defaultManager = $defaultManager; + $this->proxyInterfaceName = $proxyInterfaceName; + } + + /** + * Fetches/creates the given services. + * + * A service in this context is connection or a manager instance. + * + * @param string $name The name of the service. + * + * @return ObjectManager The instance of the given service. + */ + abstract protected function getService($name); + + /** + * Resets the given services. + * + * A service in this context is connection or a manager instance. + * + * @param string $name The name of the service. + * + * @return void + */ + abstract protected function resetService($name); + + /** + * Gets the name of the registry. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * {@inheritdoc} + */ + public function getConnection($name = null) + { + if ($name === null) { + $name = $this->defaultConnection; + } + + if (! isset($this->connections[$name])) { + throw new InvalidArgumentException(sprintf('Doctrine %s Connection named "%s" does not exist.', $this->name, $name)); + } + + return $this->getService($this->connections[$name]); + } + + /** + * {@inheritdoc} + */ + public function getConnectionNames() + { + return $this->connections; + } + + /** + * {@inheritdoc} + */ + public function getConnections() + { + $connections = []; + foreach ($this->connections as $name => $id) { + $connections[$name] = $this->getService($id); + } + + return $connections; + } + + /** + * {@inheritdoc} + */ + public function getDefaultConnectionName() + { + return $this->defaultConnection; + } + + /** + * {@inheritdoc} + */ + public function getDefaultManagerName() + { + return $this->defaultManager; + } + + /** + * {@inheritdoc} + * + * @throws InvalidArgumentException + */ + public function getManager($name = null) + { + if ($name === null) { + $name = $this->defaultManager; + } + + if (! isset($this->managers[$name])) { + throw new InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name)); + } + + return $this->getService($this->managers[$name]); + } + + /** + * {@inheritdoc} + */ + public function getManagerForClass($class) + { + // Check for namespace alias + if (strpos($class, ':') !== false) { + [$namespaceAlias, $simpleClassName] = explode(':', $class, 2); + $class = $this->getAliasNamespace($namespaceAlias) . '\\' . $simpleClassName; + } + + $proxyClass = new ReflectionClass($class); + + if ($proxyClass->implementsInterface($this->proxyInterfaceName)) { + $parentClass = $proxyClass->getParentClass(); + + if (! $parentClass) { + return null; + } + + $class = $parentClass->getName(); + } + + foreach ($this->managers as $id) { + $manager = $this->getService($id); + + if (! $manager->getMetadataFactory()->isTransient($class)) { + return $manager; + } + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function getManagerNames() + { + return $this->managers; + } + + /** + * {@inheritdoc} + */ + public function getManagers() + { + $dms = []; + foreach ($this->managers as $name => $id) { + $dms[$name] = $this->getService($id); + } + + return $dms; + } + + /** + * {@inheritdoc} + */ + public function getRepository($persistentObject, $persistentManagerName = null) + { + return $this + ->selectManager($persistentObject, $persistentManagerName) + ->getRepository($persistentObject); + } + + /** + * {@inheritdoc} + */ + public function resetManager($name = null) + { + if ($name === null) { + $name = $this->defaultManager; + } + + if (! isset($this->managers[$name])) { + throw new InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name)); + } + + // force the creation of a new document manager + // if the current one is closed + $this->resetService($this->managers[$name]); + + return $this->getManager($name); + } + + private function selectManager(string $persistentObjectName, ?string $persistentManagerName = null): ObjectManager + { + if ($persistentManagerName !== null) { + return $this->getManager($persistentManagerName); + } + + return $this->getManagerForClass($persistentObjectName) ?? $this->getManager(); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/ConnectionRegistry.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ConnectionRegistry.php new file mode 100644 index 0000000..73e33b5 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ConnectionRegistry.php @@ -0,0 +1,39 @@ +<?php + +namespace Doctrine\Persistence; + +/** + * Contract covering connection for a Doctrine persistence layer ManagerRegistry class to implement. + */ +interface ConnectionRegistry +{ + /** + * Gets the default connection name. + * + * @return string The default connection name. + */ + public function getDefaultConnectionName(); + + /** + * Gets the named connection. + * + * @param string $name The connection name (null for the default one). + * + * @return object + */ + public function getConnection($name = null); + + /** + * Gets an array of all registered connections. + * + * @return object[] An array of Connection instances. + */ + public function getConnections(); + + /** + * Gets all connection names. + * + * @return string[] An array of connection names. + */ + public function getConnectionNames(); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LifecycleEventArgs.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LifecycleEventArgs.php new file mode 100644 index 0000000..a8630cf --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LifecycleEventArgs.php @@ -0,0 +1,60 @@ +<?php + +namespace Doctrine\Persistence\Event; + +use Doctrine\Common\EventArgs; +use Doctrine\Persistence\ObjectManager; + +/** + * Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions + * of entities. + */ +class LifecycleEventArgs extends EventArgs +{ + /** @var ObjectManager */ + private $objectManager; + + /** @var object */ + private $object; + + /** + * @param object $object + */ + public function __construct($object, ObjectManager $objectManager) + { + $this->object = $object; + $this->objectManager = $objectManager; + } + + /** + * Retrieves the associated entity. + * + * @deprecated + * + * @return object + */ + public function getEntity() + { + return $this->object; + } + + /** + * Retrieves the associated object. + * + * @return object + */ + public function getObject() + { + return $this->object; + } + + /** + * Retrieves the associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php new file mode 100644 index 0000000..627cc5c --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php @@ -0,0 +1,45 @@ +<?php + +namespace Doctrine\Persistence\Event; + +use Doctrine\Common\EventArgs; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\ObjectManager; + +/** + * Class that holds event arguments for a loadMetadata event. + */ +class LoadClassMetadataEventArgs extends EventArgs +{ + /** @var ClassMetadata */ + private $classMetadata; + + /** @var ObjectManager */ + private $objectManager; + + public function __construct(ClassMetadata $classMetadata, ObjectManager $objectManager) + { + $this->classMetadata = $classMetadata; + $this->objectManager = $objectManager; + } + + /** + * Retrieves the associated ClassMetadata. + * + * @return ClassMetadata + */ + public function getClassMetadata() + { + return $this->classMetadata; + } + + /** + * Retrieves the associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/ManagerEventArgs.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/ManagerEventArgs.php new file mode 100644 index 0000000..510aff2 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/ManagerEventArgs.php @@ -0,0 +1,30 @@ +<?php + +namespace Doctrine\Persistence\Event; + +use Doctrine\Common\EventArgs; +use Doctrine\Persistence\ObjectManager; + +/** + * Provides event arguments for the preFlush event. + */ +class ManagerEventArgs extends EventArgs +{ + /** @var ObjectManager */ + private $objectManager; + + public function __construct(ObjectManager $objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * Retrieves the associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/OnClearEventArgs.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/OnClearEventArgs.php new file mode 100644 index 0000000..ce288d8 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/OnClearEventArgs.php @@ -0,0 +1,58 @@ +<?php + +namespace Doctrine\Persistence\Event; + +use Doctrine\Common\EventArgs; +use Doctrine\Persistence\ObjectManager; + +/** + * Provides event arguments for the onClear event. + */ +class OnClearEventArgs extends EventArgs +{ + /** @var ObjectManager */ + private $objectManager; + + /** @var string|null */ + private $entityClass; + + /** + * @param ObjectManager $objectManager The object manager. + * @param string|null $entityClass The optional entity class. + */ + public function __construct($objectManager, $entityClass = null) + { + $this->objectManager = $objectManager; + $this->entityClass = $entityClass; + } + + /** + * Retrieves the associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } + + /** + * Returns the name of the entity class that is cleared, or null if all are cleared. + * + * @return string|null + */ + public function getEntityClass() + { + return $this->entityClass; + } + + /** + * Returns whether this event clears all entities. + * + * @return bool + */ + public function clearsAllEntities() + { + return $this->entityClass === null; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php new file mode 100644 index 0000000..177d944 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php @@ -0,0 +1,114 @@ +<?php + +namespace Doctrine\Persistence\Event; + +use Doctrine\Persistence\ObjectManager; +use InvalidArgumentException; + +use function get_class; +use function sprintf; + +/** + * Class that holds event arguments for a preUpdate event. + */ +class PreUpdateEventArgs extends LifecycleEventArgs +{ + /** @var mixed[][] */ + private $entityChangeSet; + + /** + * @param object $entity + * @param mixed[][] $changeSet + */ + public function __construct($entity, ObjectManager $objectManager, array &$changeSet) + { + parent::__construct($entity, $objectManager); + + $this->entityChangeSet = &$changeSet; + } + + /** + * Retrieves the entity changeset. + * + * @return mixed[][] + */ + public function getEntityChangeSet() + { + return $this->entityChangeSet; + } + + /** + * Checks if field has a changeset. + * + * @param string $field + * + * @return bool + */ + public function hasChangedField($field) + { + return isset($this->entityChangeSet[$field]); + } + + /** + * Gets the old value of the changeset of the changed field. + * + * @param string $field + * + * @return mixed + */ + public function getOldValue($field) + { + $this->assertValidField($field); + + return $this->entityChangeSet[$field][0]; + } + + /** + * Gets the new value of the changeset of the changed field. + * + * @param string $field + * + * @return mixed + */ + public function getNewValue($field) + { + $this->assertValidField($field); + + return $this->entityChangeSet[$field][1]; + } + + /** + * Sets the new value of this field. + * + * @param string $field + * @param mixed $value + * + * @return void + */ + public function setNewValue($field, $value) + { + $this->assertValidField($field); + + $this->entityChangeSet[$field][1] = $value; + } + + /** + * Asserts the field exists in changeset. + * + * @param string $field + * + * @return void + * + * @throws InvalidArgumentException + */ + private function assertValidField($field) + { + if (! isset($this->entityChangeSet[$field])) { + throw new InvalidArgumentException(sprintf( + 'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.', + $field, + get_class($this->getObject()) + )); + } + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/ManagerRegistry.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ManagerRegistry.php new file mode 100644 index 0000000..6f89e0c --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ManagerRegistry.php @@ -0,0 +1,92 @@ +<?php + +namespace Doctrine\Persistence; + +/** + * Contract covering object managers for a Doctrine persistence layer ManagerRegistry class to implement. + */ +interface ManagerRegistry extends ConnectionRegistry +{ + /** + * Gets the default object manager name. + * + * @return string The default object manager name. + */ + public function getDefaultManagerName(); + + /** + * Gets a named object manager. + * + * @param string $name The object manager name (null for the default one). + * + * @return ObjectManager + */ + public function getManager($name = null); + + /** + * Gets an array of all registered object managers. + * + * @return ObjectManager[] An array of ObjectManager instances + */ + public function getManagers(); + + /** + * Resets a named object manager. + * + * This method is useful when an object manager has been closed + * because of a rollbacked transaction AND when you think that + * it makes sense to get a new one to replace the closed one. + * + * Be warned that you will get a brand new object manager as + * the existing one is not useable anymore. This means that any + * other object with a dependency on this object manager will + * hold an obsolete reference. You can inject the registry instead + * to avoid this problem. + * + * @param string|null $name The object manager name (null for the default one). + * + * @return ObjectManager + */ + public function resetManager($name = null); + + /** + * Resolves a registered namespace alias to the full namespace. + * + * This method looks for the alias in all registered object managers. + * + * @param string $alias The alias. + * + * @return string The full namespace. + */ + public function getAliasNamespace($alias); + + /** + * Gets all object manager names. + * + * @return string[] An array of object manager names. + */ + public function getManagerNames(); + + /** + * Gets the ObjectRepository for a persistent object. + * + * @param string $persistentObject The name of the persistent object. + * @param string $persistentManagerName The object manager name (null for the default one). + * + * @return ObjectRepository + * + * @template T + * @psalm-param class-string<T> $persistentObject + * @psalm-return ObjectRepository<T> + */ + public function getRepository($persistentObject, $persistentManagerName = null); + + /** + * Gets the object manager associated with a given class. + * + * @param string $class A persistent object class name. + * + * @return ObjectManager|null + */ + public function getManagerForClass($class); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php new file mode 100644 index 0000000..89dfdbb --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php @@ -0,0 +1,416 @@ +<?php + +namespace Doctrine\Persistence\Mapping; + +use Doctrine\Common\Cache\Cache; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; +use Doctrine\Persistence\Proxy; +use ReflectionException; + +use function array_reverse; +use function array_unshift; +use function explode; +use function strpos; +use function strrpos; +use function substr; + +/** + * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the + * metadata mapping informations of a class which describes how a class should be mapped + * to a relational database. + * + * This class was abstracted from the ORM ClassMetadataFactory. + */ +abstract class AbstractClassMetadataFactory implements ClassMetadataFactory +{ + /** + * Salt used by specific Object Manager implementation. + * + * @var string + */ + protected $cacheSalt = '$CLASSMETADATA'; + + /** @var Cache|null */ + private $cacheDriver; + + /** @var ClassMetadata[] */ + private $loadedMetadata = []; + + /** @var bool */ + protected $initialized = false; + + /** @var ReflectionService|null */ + private $reflectionService = null; + + /** + * Sets the cache driver used by the factory to cache ClassMetadata instances. + * + * @return void + */ + public function setCacheDriver(?Cache $cacheDriver = null) + { + $this->cacheDriver = $cacheDriver; + } + + /** + * Gets the cache driver used by the factory to cache ClassMetadata instances. + * + * @return Cache|null + */ + public function getCacheDriver() + { + return $this->cacheDriver; + } + + /** + * Returns an array of all the loaded metadata currently in memory. + * + * @return ClassMetadata[] + */ + public function getLoadedMetadata() + { + return $this->loadedMetadata; + } + + /** + * Forces the factory to load the metadata of all classes known to the underlying + * mapping driver. + * + * @return ClassMetadata[] The ClassMetadata instances of all mapped classes. + */ + public function getAllMetadata() + { + if (! $this->initialized) { + $this->initialize(); + } + + $driver = $this->getDriver(); + $metadata = []; + foreach ($driver->getAllClassNames() as $className) { + $metadata[] = $this->getMetadataFor($className); + } + + return $metadata; + } + + /** + * Lazy initialization of this stuff, especially the metadata driver, + * since these are not needed at all when a metadata cache is active. + * + * @return void + */ + abstract protected function initialize(); + + /** + * Gets the fully qualified class-name from the namespace alias. + * + * @param string $namespaceAlias + * @param string $simpleClassName + * + * @return string + */ + abstract protected function getFqcnFromAlias($namespaceAlias, $simpleClassName); + + /** + * Returns the mapping driver implementation. + * + * @return MappingDriver + */ + abstract protected function getDriver(); + + /** + * Wakes up reflection after ClassMetadata gets unserialized from cache. + * + * @return void + */ + abstract protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService); + + /** + * Initializes Reflection after ClassMetadata was constructed. + * + * @return void + */ + abstract protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService); + + /** + * Checks whether the class metadata is an entity. + * + * This method should return false for mapped superclasses or embedded classes. + * + * @return bool + */ + abstract protected function isEntity(ClassMetadata $class); + + /** + * Gets the class metadata descriptor for a class. + * + * @param string $className The name of the class. + * + * @return ClassMetadata + * + * @throws ReflectionException + * @throws MappingException + */ + public function getMetadataFor($className) + { + if (isset($this->loadedMetadata[$className])) { + return $this->loadedMetadata[$className]; + } + + // Check for namespace alias + if (strpos($className, ':') !== false) { + [$namespaceAlias, $simpleClassName] = explode(':', $className, 2); + + $realClassName = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName); + } else { + $realClassName = $this->getRealClass($className); + } + + if (isset($this->loadedMetadata[$realClassName])) { + // We do not have the alias name in the map, include it + return $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; + } + + $loadingException = null; + + try { + if ($this->cacheDriver) { + $cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt); + if ($cached instanceof ClassMetadata) { + $this->loadedMetadata[$realClassName] = $cached; + + $this->wakeupReflection($cached, $this->getReflectionService()); + } else { + foreach ($this->loadMetadata($realClassName) as $loadedClassName) { + $this->cacheDriver->save( + $loadedClassName . $this->cacheSalt, + $this->loadedMetadata[$loadedClassName] + ); + } + } + } else { + $this->loadMetadata($realClassName); + } + } catch (MappingException $loadingException) { + $fallbackMetadataResponse = $this->onNotFoundMetadata($realClassName); + + if (! $fallbackMetadataResponse) { + throw $loadingException; + } + + $this->loadedMetadata[$realClassName] = $fallbackMetadataResponse; + } + + if ($className !== $realClassName) { + // We do not have the alias name in the map, include it + $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; + } + + return $this->loadedMetadata[$className]; + } + + /** + * Checks whether the factory has the metadata for a class loaded already. + * + * @param string $className + * + * @return bool TRUE if the metadata of the class in question is already loaded, FALSE otherwise. + */ + public function hasMetadataFor($className) + { + return isset($this->loadedMetadata[$className]); + } + + /** + * Sets the metadata descriptor for a specific class. + * + * NOTE: This is only useful in very special cases, like when generating proxy classes. + * + * @param string $className + * @param ClassMetadata $class + * + * @return void + */ + public function setMetadataFor($className, $class) + { + $this->loadedMetadata[$className] = $class; + } + + /** + * Gets an array of parent classes for the given entity class. + * + * @param string $name + * + * @return string[] + */ + protected function getParentClasses($name) + { + // Collect parent classes, ignoring transient (not-mapped) classes. + $parentClasses = []; + + foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) { + if ($this->getDriver()->isTransient($parentClass)) { + continue; + } + + $parentClasses[] = $parentClass; + } + + return $parentClasses; + } + + /** + * Loads the metadata of the class in question and all it's ancestors whose metadata + * is still not loaded. + * + * Important: The class $name does not necessarily exist at this point here. + * Scenarios in a code-generation setup might have access to XML/YAML + * Mapping files without the actual PHP code existing here. That is why the + * {@see Doctrine\Common\Persistence\Mapping\ReflectionService} interface + * should be used for reflection. + * + * @param string $name The name of the class for which the metadata should get loaded. + * + * @return string[] + */ + protected function loadMetadata($name) + { + if (! $this->initialized) { + $this->initialize(); + } + + $loaded = []; + + $parentClasses = $this->getParentClasses($name); + $parentClasses[] = $name; + + // Move down the hierarchy of parent classes, starting from the topmost class + $parent = null; + $rootEntityFound = false; + $visited = []; + $reflService = $this->getReflectionService(); + foreach ($parentClasses as $className) { + if (isset($this->loadedMetadata[$className])) { + $parent = $this->loadedMetadata[$className]; + if ($this->isEntity($parent)) { + $rootEntityFound = true; + array_unshift($visited, $className); + } + + continue; + } + + $class = $this->newClassMetadataInstance($className); + $this->initializeReflection($class, $reflService); + + $this->doLoadMetadata($class, $parent, $rootEntityFound, $visited); + + $this->loadedMetadata[$className] = $class; + + $parent = $class; + + if ($this->isEntity($class)) { + $rootEntityFound = true; + array_unshift($visited, $className); + } + + $this->wakeupReflection($class, $reflService); + + $loaded[] = $className; + } + + return $loaded; + } + + /** + * Provides a fallback hook for loading metadata when loading failed due to reflection/mapping exceptions + * + * Override this method to implement a fallback strategy for failed metadata loading + * + * @param string $className + * + * @return ClassMetadata|null + */ + protected function onNotFoundMetadata($className) + { + return null; + } + + /** + * Actually loads the metadata from the underlying metadata. + * + * @param ClassMetadata $class + * @param ClassMetadata|null $parent + * @param bool $rootEntityFound + * @param string[] $nonSuperclassParents All parent class names + * that are not marked as mapped superclasses. + * + * @return void + */ + abstract protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents); + + /** + * Creates a new ClassMetadata instance for the given class name. + * + * @param string $className + * + * @return ClassMetadata + */ + abstract protected function newClassMetadataInstance($className); + + /** + * {@inheritDoc} + */ + public function isTransient($class) + { + if (! $this->initialized) { + $this->initialize(); + } + + // Check for namespace alias + if (strpos($class, ':') !== false) { + [$namespaceAlias, $simpleClassName] = explode(':', $class, 2); + $class = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName); + } + + return $this->getDriver()->isTransient($class); + } + + /** + * Sets the reflectionService. + * + * @return void + */ + public function setReflectionService(ReflectionService $reflectionService) + { + $this->reflectionService = $reflectionService; + } + + /** + * Gets the reflection service associated with this metadata factory. + * + * @return ReflectionService + */ + public function getReflectionService() + { + if ($this->reflectionService === null) { + $this->reflectionService = new RuntimeReflectionService(); + } + + return $this->reflectionService; + } + + /** + * Gets the real class name of a class name that could be a proxy. + */ + private function getRealClass(string $class): string + { + $pos = strrpos($class, '\\' . Proxy::MARKER . '\\'); + + if ($pos === false) { + return $class; + } + + return substr($class, $pos + Proxy::MARKER_LENGTH + 2); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadata.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadata.php new file mode 100644 index 0000000..7dc556c --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadata.php @@ -0,0 +1,154 @@ +<?php + +namespace Doctrine\Persistence\Mapping; + +use ReflectionClass; + +/** + * Contract for a Doctrine persistence layer ClassMetadata class to implement. + */ +interface ClassMetadata +{ + /** + * Gets the fully-qualified class name of this persistent class. + * + * @return string + */ + public function getName(); + + /** + * Gets the mapped identifier field name. + * + * The returned structure is an array of the identifier field names. + * + * @return mixed[] + */ + public function getIdentifier(); + + /** + * Gets the ReflectionClass instance for this mapped class. + * + * @return ReflectionClass + */ + public function getReflectionClass(); + + /** + * Checks if the given field name is a mapped identifier for this class. + * + * @param string $fieldName + * + * @return bool + */ + public function isIdentifier($fieldName); + + /** + * Checks if the given field is a mapped property for this class. + * + * @param string $fieldName + * + * @return bool + */ + public function hasField($fieldName); + + /** + * Checks if the given field is a mapped association for this class. + * + * @param string $fieldName + * + * @return bool + */ + public function hasAssociation($fieldName); + + /** + * Checks if the given field is a mapped single valued association for this class. + * + * @param string $fieldName + * + * @return bool + */ + public function isSingleValuedAssociation($fieldName); + + /** + * Checks if the given field is a mapped collection valued association for this class. + * + * @param string $fieldName + * + * @return bool + */ + public function isCollectionValuedAssociation($fieldName); + + /** + * A numerically indexed list of field names of this persistent class. + * + * This array includes identifier fields if present on this class. + * + * @return string[] + */ + public function getFieldNames(); + + /** + * Returns an array of identifier field names numerically indexed. + * + * @return string[] + */ + public function getIdentifierFieldNames(); + + /** + * Returns a numerically indexed list of association names of this persistent class. + * + * This array includes identifier associations if present on this class. + * + * @return string[] + */ + public function getAssociationNames(); + + /** + * Returns a type name of this field. + * + * This type names can be implementation specific but should at least include the php types: + * integer, string, boolean, float/double, datetime. + * + * @param string $fieldName + * + * @return string + */ + public function getTypeOfField($fieldName); + + /** + * Returns the target class name of the given association. + * + * @param string $assocName + * + * @return string + */ + public function getAssociationTargetClass($assocName); + + /** + * Checks if the association is the inverse side of a bidirectional association. + * + * @param string $assocName + * + * @return bool + */ + public function isAssociationInverseSide($assocName); + + /** + * Returns the target field of the owning side of the association. + * + * @param string $assocName + * + * @return string + */ + public function getAssociationMappedByTargetField($assocName); + + /** + * Returns the identifier of this object as an array with field name as key. + * + * Has to return an empty array if no identifier isset. + * + * @param object $object + * + * @return mixed[] + */ + public function getIdentifierValues($object); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadataFactory.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadataFactory.php new file mode 100644 index 0000000..8b78239 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadataFactory.php @@ -0,0 +1,53 @@ +<?php + +namespace Doctrine\Persistence\Mapping; + +/** + * Contract for a Doctrine persistence layer ClassMetadata class to implement. + */ +interface ClassMetadataFactory +{ + /** + * Forces the factory to load the metadata of all classes known to the underlying + * mapping driver. + * + * @return ClassMetadata[] The ClassMetadata instances of all mapped classes. + */ + public function getAllMetadata(); + + /** + * Gets the class metadata descriptor for a class. + * + * @param string $className The name of the class. + * + * @return ClassMetadata + */ + public function getMetadataFor($className); + + /** + * Checks whether the factory has the metadata for a class loaded already. + * + * @param string $className + * + * @return bool TRUE if the metadata of the class in question is already loaded, FALSE otherwise. + */ + public function hasMetadataFor($className); + + /** + * Sets the metadata descriptor for a specific class. + * + * @param string $className + * @param ClassMetadata $class + */ + public function setMetadataFor($className, $class); + + /** + * Returns whether the class with the specified name should have its metadata loaded. + * This is only the case if it is either mapped directly or as a MappedSuperclass. + * + * @param string $className + * + * @return bool + */ + public function isTransient($className); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/AnnotationDriver.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/AnnotationDriver.php new file mode 100644 index 0000000..8ea1b05 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/AnnotationDriver.php @@ -0,0 +1,256 @@ +<?php + +namespace Doctrine\Persistence\Mapping\Driver; + +use Doctrine\Common\Annotations\Reader; +use Doctrine\Persistence\Mapping\MappingException; +use FilesystemIterator; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; +use RecursiveRegexIterator; +use ReflectionClass; +use RegexIterator; + +use function array_merge; +use function array_unique; +use function get_class; +use function get_declared_classes; +use function in_array; +use function is_dir; +use function preg_match; +use function preg_quote; +use function realpath; +use function str_replace; +use function strpos; + +/** + * The AnnotationDriver reads the mapping metadata from docblock annotations. + */ +abstract class AnnotationDriver implements MappingDriver +{ + /** + * The annotation reader. + * + * @var Reader + */ + protected $reader; + + /** + * The paths where to look for mapping files. + * + * @var string[] + */ + protected $paths = []; + + /** + * The paths excluded from path where to look for mapping files. + * + * @var string[] + */ + protected $excludePaths = []; + + /** + * The file extension of mapping documents. + * + * @var string + */ + protected $fileExtension = '.php'; + + /** + * Cache for AnnotationDriver#getAllClassNames(). + * + * @var string[]|null + */ + protected $classNames; + + /** + * Name of the entity annotations as keys. + * + * @var string[] + */ + protected $entityAnnotationClasses = []; + + /** + * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading + * docblock annotations. + * + * @param Reader $reader The AnnotationReader to use, duck-typed. + * @param string|string[]|null $paths One or multiple paths where mapping classes can be found. + */ + public function __construct($reader, $paths = null) + { + $this->reader = $reader; + if (! $paths) { + return; + } + + $this->addPaths((array) $paths); + } + + /** + * Appends lookup paths to metadata driver. + * + * @param string[] $paths + * + * @return void + */ + public function addPaths(array $paths) + { + $this->paths = array_unique(array_merge($this->paths, $paths)); + } + + /** + * Retrieves the defined metadata lookup paths. + * + * @return string[] + */ + public function getPaths() + { + return $this->paths; + } + + /** + * Append exclude lookup paths to metadata driver. + * + * @param string[] $paths + */ + public function addExcludePaths(array $paths) + { + $this->excludePaths = array_unique(array_merge($this->excludePaths, $paths)); + } + + /** + * Retrieve the defined metadata lookup exclude paths. + * + * @return string[] + */ + public function getExcludePaths() + { + return $this->excludePaths; + } + + /** + * Retrieve the current annotation reader + * + * @return Reader + */ + public function getReader() + { + return $this->reader; + } + + /** + * Gets the file extension used to look for mapping files under. + * + * @return string + */ + public function getFileExtension() + { + return $this->fileExtension; + } + + /** + * Sets the file extension used to look for mapping files under. + * + * @param string $fileExtension The file extension to set. + * + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->fileExtension = $fileExtension; + } + + /** + * Returns whether the class with the specified name is transient. Only non-transient + * classes, that is entities and mapped superclasses, should have their metadata loaded. + * + * A class is non-transient if it is annotated with an annotation + * from the {@see AnnotationDriver::entityAnnotationClasses}. + * + * @param string $className + * + * @return bool + */ + public function isTransient($className) + { + $classAnnotations = $this->reader->getClassAnnotations(new ReflectionClass($className)); + + foreach ($classAnnotations as $annot) { + if (isset($this->entityAnnotationClasses[get_class($annot)])) { + return false; + } + } + + return true; + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames() + { + if ($this->classNames !== null) { + return $this->classNames; + } + + if (! $this->paths) { + throw MappingException::pathRequired(); + } + + $classes = []; + $includedFiles = []; + + foreach ($this->paths as $path) { + if (! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new RegexIterator( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), + RecursiveIteratorIterator::LEAVES_ONLY + ), + '/^.+' . preg_quote($this->fileExtension) . '$/i', + RecursiveRegexIterator::GET_MATCH + ); + + foreach ($iterator as $file) { + $sourceFile = $file[0]; + + if (! preg_match('(^phar:)i', $sourceFile)) { + $sourceFile = realpath($sourceFile); + } + + foreach ($this->excludePaths as $excludePath) { + $exclude = str_replace('\\', '/', realpath($excludePath)); + $current = str_replace('\\', '/', $sourceFile); + + if (strpos($current, $exclude) !== false) { + continue 2; + } + } + + require_once $sourceFile; + + $includedFiles[] = $sourceFile; + } + } + + $declared = get_declared_classes(); + + foreach ($declared as $className) { + $rc = new ReflectionClass($className); + $sourceFile = $rc->getFileName(); + if (! in_array($sourceFile, $includedFiles) || $this->isTransient($className)) { + continue; + } + + $classes[] = $className; + } + + $this->classNames = $classes; + + return $classes; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php new file mode 100644 index 0000000..a2eb17c --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php @@ -0,0 +1,163 @@ +<?php + +namespace Doctrine\Persistence\Mapping\Driver; + +use Doctrine\Persistence\Mapping\MappingException; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; + +use function array_merge; +use function array_unique; +use function is_dir; +use function is_file; +use function str_replace; + +use const DIRECTORY_SEPARATOR; + +/** + * Locates the file that contains the metadata information for a given class name. + * + * This behavior is independent of the actual content of the file. It just detects + * the file which is responsible for the given class name. + */ +class DefaultFileLocator implements FileLocator +{ + /** + * The paths where to look for mapping files. + * + * @var string[] + */ + protected $paths = []; + + /** + * The file extension of mapping documents. + * + * @var string|null + */ + protected $fileExtension; + + /** + * Initializes a new FileDriver that looks in the given path(s) for mapping + * documents and operates in the specified operating mode. + * + * @param string|string[] $paths One or multiple paths where mapping documents can be found. + * @param string|null $fileExtension The file extension of mapping documents, usually prefixed with a dot. + */ + public function __construct($paths, $fileExtension = null) + { + $this->addPaths((array) $paths); + $this->fileExtension = $fileExtension; + } + + /** + * Appends lookup paths to metadata driver. + * + * @param string[] $paths + * + * @return void + */ + public function addPaths(array $paths) + { + $this->paths = array_unique(array_merge($this->paths, $paths)); + } + + /** + * Retrieves the defined metadata lookup paths. + * + * @return string[] + */ + public function getPaths() + { + return $this->paths; + } + + /** + * Gets the file extension used to look for mapping files under. + * + * @return string|null + */ + public function getFileExtension() + { + return $this->fileExtension; + } + + /** + * Sets the file extension used to look for mapping files under. + * + * @param string|null $fileExtension The file extension to set. + * + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->fileExtension = $fileExtension; + } + + /** + * {@inheritDoc} + */ + public function findMappingFile($className) + { + $fileName = str_replace('\\', '.', $className) . $this->fileExtension; + + // Check whether file exists + foreach ($this->paths as $path) { + if (is_file($path . DIRECTORY_SEPARATOR . $fileName)) { + return $path . DIRECTORY_SEPARATOR . $fileName; + } + } + + throw MappingException::mappingFileNotFound($className, $fileName); + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames($globalBasename) + { + $classes = []; + + if ($this->paths) { + foreach ($this->paths as $path) { + if (! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + $fileName = $file->getBasename($this->fileExtension); + + if ($fileName === $file->getBasename() || $fileName === $globalBasename) { + continue; + } + + // NOTE: All files found here means classes are not transient! + $classes[] = str_replace('.', '\\', $fileName); + } + } + } + + return $classes; + } + + /** + * {@inheritDoc} + */ + public function fileExists($className) + { + $fileName = str_replace('\\', '.', $className) . $this->fileExtension; + + // Check whether file exists + foreach ((array) $this->paths as $path) { + if (is_file($path . DIRECTORY_SEPARATOR . $fileName)) { + return true; + } + } + + return false; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php new file mode 100644 index 0000000..208a334 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php @@ -0,0 +1,195 @@ +<?php + +namespace Doctrine\Persistence\Mapping\Driver; + +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\MappingException; + +use function array_keys; +use function array_merge; +use function array_unique; +use function is_file; +use function str_replace; + +/** + * Base driver for file-based metadata drivers. + * + * A file driver operates in a mode where it loads the mapping files of individual + * classes on demand. This requires the user to adhere to the convention of 1 mapping + * file per class and the file names of the mapping files must correspond to the full + * class name, including namespace, with the namespace delimiters '\', replaced by dots '.'. + */ +abstract class FileDriver implements MappingDriver +{ + /** @var FileLocator */ + protected $locator; + + /** @var ClassMetadata[]|null */ + protected $classCache; + + /** @var string|null */ + protected $globalBasename; + + /** + * Initializes a new FileDriver that looks in the given path(s) for mapping + * documents and operates in the specified operating mode. + * + * @param string|string[]|FileLocator $locator A FileLocator or one/multiple paths + * where mapping documents can be found. + * @param string|null $fileExtension + */ + public function __construct($locator, $fileExtension = null) + { + if ($locator instanceof FileLocator) { + $this->locator = $locator; + } else { + $this->locator = new DefaultFileLocator((array) $locator, $fileExtension); + } + } + + /** + * Sets the global basename. + * + * @param string $file + * + * @return void + */ + public function setGlobalBasename($file) + { + $this->globalBasename = $file; + } + + /** + * Retrieves the global basename. + * + * @return string|null + */ + public function getGlobalBasename() + { + return $this->globalBasename; + } + + /** + * Gets the element of schema meta data for the class from the mapping file. + * This will lazily load the mapping file if it is not loaded yet. + * + * @param string $className + * + * @return ClassMetadata The element of schema meta data. + * + * @throws MappingException + */ + public function getElement($className) + { + if ($this->classCache === null) { + $this->initialize(); + } + + if (isset($this->classCache[$className])) { + return $this->classCache[$className]; + } + + $result = $this->loadMappingFile($this->locator->findMappingFile($className)); + if (! isset($result[$className])) { + throw MappingException::invalidMappingFile($className, str_replace('\\', '.', $className) . $this->locator->getFileExtension()); + } + + $this->classCache[$className] = $result[$className]; + + return $result[$className]; + } + + /** + * {@inheritDoc} + */ + public function isTransient($className) + { + if ($this->classCache === null) { + $this->initialize(); + } + + if (isset($this->classCache[$className])) { + return false; + } + + return ! $this->locator->fileExists($className); + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames() + { + if ($this->classCache === null) { + $this->initialize(); + } + + if (! $this->classCache) { + return (array) $this->locator->getAllClassNames($this->globalBasename); + } + + return array_unique(array_merge( + array_keys($this->classCache), + (array) $this->locator->getAllClassNames($this->globalBasename) + )); + } + + /** + * Loads a mapping file with the given name and returns a map + * from class/entity names to their corresponding file driver elements. + * + * @param string $file The mapping file to load. + * + * @return ClassMetadata[] + */ + abstract protected function loadMappingFile($file); + + /** + * Initializes the class cache from all the global files. + * + * Using this feature adds a substantial performance hit to file drivers as + * more metadata has to be loaded into memory than might actually be + * necessary. This may not be relevant to scenarios where caching of + * metadata is in place, however hits very hard in scenarios where no + * caching is used. + * + * @return void + */ + protected function initialize() + { + $this->classCache = []; + if ($this->globalBasename === null) { + return; + } + + foreach ($this->locator->getPaths() as $path) { + $file = $path . '/' . $this->globalBasename . $this->locator->getFileExtension(); + if (! is_file($file)) { + continue; + } + + $this->classCache = array_merge( + $this->classCache, + $this->loadMappingFile($file) + ); + } + } + + /** + * Retrieves the locator used to discover mapping files by className. + * + * @return FileLocator + */ + public function getLocator() + { + return $this->locator; + } + + /** + * Sets the locator used to discover mapping files by className. + */ + public function setLocator(FileLocator $locator) + { + $this->locator = $locator; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php new file mode 100644 index 0000000..a4dd570 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php @@ -0,0 +1,53 @@ +<?php + +namespace Doctrine\Persistence\Mapping\Driver; + +/** + * Locates the file that contains the metadata information for a given class name. + * + * This behavior is independent of the actual content of the file. It just detects + * the file which is responsible for the given class name. + */ +interface FileLocator +{ + /** + * Locates mapping file for the given class name. + * + * @param string $className + * + * @return string + */ + public function findMappingFile($className); + + /** + * Gets all class names that are found with this file locator. + * + * @param string|null $globalBasename Passed to allow excluding the basename. + * + * @return string[] + */ + public function getAllClassNames($globalBasename); + + /** + * Checks if a file can be found for this class name. + * + * @param string $className + * + * @return bool + */ + public function fileExists($className); + + /** + * Gets all the paths that this file locator looks for mapping files. + * + * @return string[] + */ + public function getPaths(); + + /** + * Gets the file extension that mapping files are suffixed with. + * + * @return string|null + */ + public function getFileExtension(); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriver.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriver.php new file mode 100644 index 0000000..2c39572 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriver.php @@ -0,0 +1,37 @@ +<?php + +namespace Doctrine\Persistence\Mapping\Driver; + +use Doctrine\Persistence\Mapping\ClassMetadata; + +/** + * Contract for metadata drivers. + */ +interface MappingDriver +{ + /** + * Loads the metadata for the specified class into the provided container. + * + * @param string $className + * + * @return void + */ + public function loadMetadataForClass($className, ClassMetadata $metadata); + + /** + * Gets the names of all mapped classes known to this driver. + * + * @return string[] The names of all mapped classes known to this driver. + */ + public function getAllClassNames(); + + /** + * Returns whether the class with the specified name should have its metadata loaded. + * This is only the case if it is either mapped as an Entity or a MappedSuperclass. + * + * @param string $className + * + * @return bool + */ + public function isTransient($className); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriverChain.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriverChain.php new file mode 100644 index 0000000..97fc724 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriverChain.php @@ -0,0 +1,146 @@ +<?php + +namespace Doctrine\Persistence\Mapping\Driver; + +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\MappingException; + +use function array_keys; +use function assert; +use function spl_object_hash; +use function strpos; + +/** + * The DriverChain allows you to add multiple other mapping drivers for + * certain namespaces. + */ +class MappingDriverChain implements MappingDriver +{ + /** + * The default driver. + * + * @var MappingDriver|null + */ + private $defaultDriver; + + /** @var MappingDriver[] */ + private $drivers = []; + + /** + * Gets the default driver. + * + * @return MappingDriver|null + */ + public function getDefaultDriver() + { + return $this->defaultDriver; + } + + /** + * Set the default driver. + * + * @return void + */ + public function setDefaultDriver(MappingDriver $driver) + { + $this->defaultDriver = $driver; + } + + /** + * Adds a nested driver. + * + * @param string $namespace + * + * @return void + */ + public function addDriver(MappingDriver $nestedDriver, $namespace) + { + $this->drivers[$namespace] = $nestedDriver; + } + + /** + * Gets the array of nested drivers. + * + * @return MappingDriver[] $drivers + */ + public function getDrivers() + { + return $this->drivers; + } + + /** + * {@inheritDoc} + */ + public function loadMetadataForClass($className, ClassMetadata $metadata) + { + foreach ($this->drivers as $namespace => $driver) { + assert($driver instanceof MappingDriver); + if (strpos($className, $namespace) === 0) { + $driver->loadMetadataForClass($className, $metadata); + + return; + } + } + + if ($this->defaultDriver !== null) { + $this->defaultDriver->loadMetadataForClass($className, $metadata); + + return; + } + + throw MappingException::classNotFoundInNamespaces($className, array_keys($this->drivers)); + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames() + { + $classNames = []; + $driverClasses = []; + + foreach ($this->drivers as $namespace => $driver) { + assert($driver instanceof MappingDriver); + $oid = spl_object_hash($driver); + + if (! isset($driverClasses[$oid])) { + $driverClasses[$oid] = $driver->getAllClassNames(); + } + + foreach ($driverClasses[$oid] as $className) { + if (strpos($className, $namespace) !== 0) { + continue; + } + + $classNames[$className] = true; + } + } + + if ($this->defaultDriver !== null) { + foreach ($this->defaultDriver->getAllClassNames() as $className) { + $classNames[$className] = true; + } + } + + return array_keys($classNames); + } + + /** + * {@inheritDoc} + */ + public function isTransient($className) + { + foreach ($this->drivers as $namespace => $driver) { + assert($driver instanceof MappingDriver); + if (strpos($className, $namespace) === 0) { + return $driver->isTransient($className); + } + } + + if ($this->defaultDriver !== null) { + return $this->defaultDriver->isTransient($className); + } + + return true; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php new file mode 100644 index 0000000..7b844ca --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php @@ -0,0 +1,44 @@ +<?php + +namespace Doctrine\Persistence\Mapping\Driver; + +use Doctrine\Persistence\Mapping\ClassMetadata; + +/** + * The PHPDriver includes php files which just populate ClassMetadataInfo + * instances with plain PHP code. + */ +class PHPDriver extends FileDriver +{ + /** @var ClassMetadata */ + protected $metadata; + + /** + * {@inheritDoc} + */ + public function __construct($locator) + { + parent::__construct($locator, '.php'); + } + + /** + * {@inheritDoc} + */ + public function loadMetadataForClass($className, ClassMetadata $metadata) + { + $this->metadata = $metadata; + + $this->loadMappingFile($this->locator->findMappingFile($className)); + } + + /** + * {@inheritDoc} + */ + protected function loadMappingFile($file) + { + $metadata = $this->metadata; + include $file; + + return [$metadata->getName() => $metadata]; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php new file mode 100644 index 0000000..3f7b5ca --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php @@ -0,0 +1,130 @@ +<?php + +namespace Doctrine\Persistence\Mapping\Driver; + +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\MappingException; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; +use ReflectionClass; + +use function array_merge; +use function array_unique; +use function get_declared_classes; +use function in_array; +use function is_dir; +use function method_exists; +use function realpath; + +/** + * The StaticPHPDriver calls a static loadMetadata() method on your entity + * classes where you can manually populate the ClassMetadata instance. + */ +class StaticPHPDriver implements MappingDriver +{ + /** + * Paths of entity directories. + * + * @var string[] + */ + private $paths = []; + + /** + * Map of all class names. + * + * @var string[] + */ + private $classNames; + + /** + * @param string[]|string $paths + */ + public function __construct($paths) + { + $this->addPaths((array) $paths); + } + + /** + * Adds paths. + * + * @param string[] $paths + * + * @return void + */ + public function addPaths(array $paths) + { + $this->paths = array_unique(array_merge($this->paths, $paths)); + } + + /** + * {@inheritdoc} + */ + public function loadMetadataForClass($className, ClassMetadata $metadata) + { + $className::loadMetadata($metadata); + } + + /** + * {@inheritDoc} + * + * @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it? + */ + public function getAllClassNames() + { + if ($this->classNames !== null) { + return $this->classNames; + } + + if (! $this->paths) { + throw MappingException::pathRequired(); + } + + $classes = []; + $includedFiles = []; + + foreach ($this->paths as $path) { + if (! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + if ($file->getBasename('.php') === $file->getBasename()) { + continue; + } + + $sourceFile = realpath($file->getPathName()); + require_once $sourceFile; + $includedFiles[] = $sourceFile; + } + } + + $declared = get_declared_classes(); + + foreach ($declared as $className) { + $rc = new ReflectionClass($className); + $sourceFile = $rc->getFileName(); + if (! in_array($sourceFile, $includedFiles) || $this->isTransient($className)) { + continue; + } + + $classes[] = $className; + } + + $this->classNames = $classes; + + return $classes; + } + + /** + * {@inheritdoc} + */ + public function isTransient($className) + { + return ! method_exists($className, 'loadMetadata'); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php new file mode 100644 index 0000000..c7ea1ac --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php @@ -0,0 +1,232 @@ +<?php + +namespace Doctrine\Persistence\Mapping\Driver; + +use Doctrine\Persistence\Mapping\MappingException; +use InvalidArgumentException; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; + +use function array_keys; +use function array_merge; +use function is_dir; +use function is_file; +use function realpath; +use function str_replace; +use function strlen; +use function strpos; +use function strrpos; +use function strtr; +use function substr; + +use const DIRECTORY_SEPARATOR; + +/** + * The Symfony File Locator makes a simplifying assumptions compared + * to the DefaultFileLocator. By assuming paths only contain entities of a certain + * namespace the mapping files consists of the short classname only. + */ +class SymfonyFileLocator implements FileLocator +{ + /** + * The paths where to look for mapping files. + * + * @var string[] + */ + protected $paths = []; + + /** + * A map of mapping directory path to namespace prefix used to expand class shortnames. + * + * @var string[] + */ + protected $prefixes = []; + + /** + * File extension that is searched for. + * + * @var string|null + */ + protected $fileExtension; + + /** + * Represents PHP namespace delimiters when looking for files + * + * @var string + */ + private $nsSeparator; + + /** + * @param string[] $prefixes + * @param string|null $fileExtension + * @param string $nsSeparator String which would be used when converting FQCN to filename and vice versa. Should not be empty + */ + public function __construct(array $prefixes, $fileExtension = null, $nsSeparator = '.') + { + $this->addNamespacePrefixes($prefixes); + $this->fileExtension = $fileExtension; + + if (empty($nsSeparator)) { + throw new InvalidArgumentException('Namespace separator should not be empty'); + } + + $this->nsSeparator = (string) $nsSeparator; + } + + /** + * Adds Namespace Prefixes. + * + * @param string[] $prefixes + * + * @return void + */ + public function addNamespacePrefixes(array $prefixes) + { + $this->prefixes = array_merge($this->prefixes, $prefixes); + $this->paths = array_merge($this->paths, array_keys($prefixes)); + } + + /** + * Gets Namespace Prefixes. + * + * @return string[] + */ + public function getNamespacePrefixes() + { + return $this->prefixes; + } + + /** + * {@inheritDoc} + */ + public function getPaths() + { + return $this->paths; + } + + /** + * {@inheritDoc} + */ + public function getFileExtension() + { + return $this->fileExtension; + } + + /** + * Sets the file extension used to look for mapping files under. + * + * @param string $fileExtension The file extension to set. + * + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->fileExtension = $fileExtension; + } + + /** + * {@inheritDoc} + */ + public function fileExists($className) + { + $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension; + foreach ($this->paths as $path) { + if (! isset($this->prefixes[$path])) { + // global namespace class + if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) { + return true; + } + + continue; + } + + $prefix = $this->prefixes[$path]; + + if (strpos($className, $prefix . '\\') !== 0) { + continue; + } + + $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension; + if (is_file($filename)) { + return true; + } + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames($globalBasename = null) + { + $classes = []; + + if ($this->paths) { + foreach ((array) $this->paths as $path) { + if (! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + $fileName = $file->getBasename($this->fileExtension); + + if ($fileName === $file->getBasename() || $fileName === $globalBasename) { + continue; + } + + // NOTE: All files found here means classes are not transient! + if (isset($this->prefixes[$path])) { + // Calculate namespace suffix for given prefix as a relative path from basepath to file path + $nsSuffix = strtr( + substr(realpath($file->getPath()), strlen(realpath($path))), + $this->nsSeparator, + '\\' + ); + + $classes[] = $this->prefixes[$path] . str_replace(DIRECTORY_SEPARATOR, '\\', $nsSuffix) . '\\' . str_replace($this->nsSeparator, '\\', $fileName); + } else { + $classes[] = str_replace($this->nsSeparator, '\\', $fileName); + } + } + } + } + + return $classes; + } + + /** + * {@inheritDoc} + */ + public function findMappingFile($className) + { + $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension; + foreach ($this->paths as $path) { + if (! isset($this->prefixes[$path])) { + if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) { + return $path . DIRECTORY_SEPARATOR . $defaultFileName; + } + + continue; + } + + $prefix = $this->prefixes[$path]; + + if (strpos($className, $prefix . '\\') !== 0) { + continue; + } + + $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension; + if (is_file($filename)) { + return $filename; + } + } + + throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1) . $this->fileExtension); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php new file mode 100644 index 0000000..1c5e0ca --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php @@ -0,0 +1,96 @@ +<?php + +namespace Doctrine\Persistence\Mapping; + +use Exception; + +use function implode; +use function sprintf; + +/** + * A MappingException indicates that something is wrong with the mapping setup. + */ +class MappingException extends Exception +{ + /** + * @param string $className + * @param string[] $namespaces + * + * @return self + */ + public static function classNotFoundInNamespaces($className, $namespaces) + { + return new self(sprintf( + "The class '%s' was not found in the chain configured namespaces %s", + $className, + implode(', ', $namespaces) + )); + } + + /** + * @return self + */ + public static function pathRequired() + { + return new self('Specifying the paths to your entities is required ' . + 'in the AnnotationDriver to retrieve all class names.'); + } + + /** + * @param string|null $path + * + * @return self + */ + public static function fileMappingDriversRequireConfiguredDirectoryPath($path = null) + { + if (! empty($path)) { + $path = '[' . $path . ']'; + } + + return new self(sprintf( + 'File mapping drivers must have a valid directory path, ' . + 'however the given path %s seems to be incorrect!', + $path + )); + } + + /** + * @param string $entityName + * @param string $fileName + * + * @return self + */ + public static function mappingFileNotFound($entityName, $fileName) + { + return new self(sprintf( + "No mapping file found named '%s' for class '%s'.", + $fileName, + $entityName + )); + } + + /** + * @param string $entityName + * @param string $fileName + * + * @return self + */ + public static function invalidMappingFile($entityName, $fileName) + { + return new self(sprintf( + "Invalid mapping file '%s' for class '%s'.", + $fileName, + $entityName + )); + } + + /** + * @param string $className + * + * @return self + */ + public static function nonExistingClass($className) + { + return new self(sprintf("Class '%s' does not exist", $className)); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ReflectionService.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ReflectionService.php new file mode 100644 index 0000000..bdc414b --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ReflectionService.php @@ -0,0 +1,71 @@ +<?php + +namespace Doctrine\Persistence\Mapping; + +use ReflectionClass; +use ReflectionProperty; + +/** + * Very simple reflection service abstraction. + * + * This is required inside metadata layers that may require either + * static or runtime reflection. + */ +interface ReflectionService +{ + /** + * Returns an array of the parent classes (not interfaces) for the given class. + * + * @param string $class + * + * @return string[] + * + * @throws MappingException + */ + public function getParentClasses($class); + + /** + * Returns the shortname of a class. + * + * @param string $class + * + * @return string + */ + public function getClassShortName($class); + + /** + * @param string $class + * + * @return string + */ + public function getClassNamespace($class); + + /** + * Returns a reflection class instance or null. + * + * @param string $class + * + * @return ReflectionClass|null + */ + public function getClass($class); + + /** + * Returns an accessible property (setAccessible(true)) or null. + * + * @param string $class + * @param string $property + * + * @return ReflectionProperty|null + */ + public function getAccessibleProperty($class, $property); + + /** + * Checks if the class have a public method with the given name. + * + * @param mixed $class + * @param mixed $method + * + * @return bool + */ + public function hasPublicMethod($class, $method); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/RuntimeReflectionService.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/RuntimeReflectionService.php new file mode 100644 index 0000000..241a1ce --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/RuntimeReflectionService.php @@ -0,0 +1,102 @@ +<?php + +namespace Doctrine\Persistence\Mapping; + +use Doctrine\Persistence\Reflection\RuntimePublicReflectionProperty; +use Doctrine\Persistence\Reflection\TypedNoDefaultReflectionProperty; +use ReflectionClass; +use ReflectionException; +use ReflectionMethod; +use ReflectionProperty; + +use function array_key_exists; +use function class_exists; +use function class_parents; +use function phpversion; +use function version_compare; + +/** + * PHP Runtime Reflection Service. + */ +class RuntimeReflectionService implements ReflectionService +{ + /** @var bool */ + private $supportsTypedPropertiesWorkaround; + + public function __construct() + { + $this->supportsTypedPropertiesWorkaround = version_compare((string) phpversion(), '7.4.0') >= 0; + } + + /** + * {@inheritDoc} + */ + public function getParentClasses($class) + { + if (! class_exists($class)) { + throw MappingException::nonExistingClass($class); + } + + return class_parents($class); + } + + /** + * {@inheritDoc} + */ + public function getClassShortName($class) + { + $reflectionClass = new ReflectionClass($class); + + return $reflectionClass->getShortName(); + } + + /** + * {@inheritDoc} + */ + public function getClassNamespace($class) + { + $reflectionClass = new ReflectionClass($class); + + return $reflectionClass->getNamespaceName(); + } + + /** + * {@inheritDoc} + */ + public function getClass($class) + { + return new ReflectionClass($class); + } + + /** + * {@inheritDoc} + */ + public function getAccessibleProperty($class, $property) + { + $reflectionProperty = new ReflectionProperty($class, $property); + + if ($reflectionProperty->isPublic()) { + $reflectionProperty = new RuntimePublicReflectionProperty($class, $property); + } elseif ($this->supportsTypedPropertiesWorkaround && ! array_key_exists($property, $this->getClass($class)->getDefaultProperties())) { + $reflectionProperty = new TypedNoDefaultReflectionProperty($class, $property); + } + + $reflectionProperty->setAccessible(true); + + return $reflectionProperty; + } + + /** + * {@inheritDoc} + */ + public function hasPublicMethod($class, $method) + { + try { + $reflectionMethod = new ReflectionMethod($class, $method); + } catch (ReflectionException $e) { + return false; + } + + return $reflectionMethod->isPublic(); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php new file mode 100644 index 0000000..b2c33ba --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php @@ -0,0 +1,71 @@ +<?php + +namespace Doctrine\Persistence\Mapping; + +use function strpos; +use function strrev; +use function strrpos; +use function substr; + +/** + * PHP Runtime Reflection Service. + */ +class StaticReflectionService implements ReflectionService +{ + /** + * {@inheritDoc} + */ + public function getParentClasses($class) + { + return []; + } + + /** + * {@inheritDoc} + */ + public function getClassShortName($className) + { + if (strpos($className, '\\') !== false) { + $className = substr($className, strrpos($className, '\\') + 1); + } + + return $className; + } + + /** + * {@inheritDoc} + */ + public function getClassNamespace($className) + { + $namespace = ''; + if (strpos($className, '\\') !== false) { + $namespace = strrev(substr(strrev($className), strpos(strrev($className), '\\') + 1)); + } + + return $namespace; + } + + /** + * {@inheritDoc} + */ + public function getClass($class) + { + return null; + } + + /** + * {@inheritDoc} + */ + public function getAccessibleProperty($class, $property) + { + return null; + } + + /** + * {@inheritDoc} + */ + public function hasPublicMethod($class, $method) + { + return true; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/NotifyPropertyChanged.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/NotifyPropertyChanged.php new file mode 100644 index 0000000..246647e --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/NotifyPropertyChanged.php @@ -0,0 +1,20 @@ +<?php + +namespace Doctrine\Persistence; + +/** + * Interface for classes that notify event listeners of changes to their managed properties. + * + * This interface is implemented by objects that manually want to notify their object manager or + * other listeners when properties change, instead of relying on the object manager to compute + * property changes itself when changes are to be persisted. + */ +interface NotifyPropertyChanged +{ + /** + * Adds a listener that wants to be notified about property changes. + * + * @return void + */ + public function addPropertyChangedListener(PropertyChangedListener $listener); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManager.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManager.php new file mode 100644 index 0000000..1d6dc0f --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManager.php @@ -0,0 +1,165 @@ +<?php + +namespace Doctrine\Persistence; + +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\ClassMetadataFactory; + +/** + * Contract for a Doctrine persistence layer ObjectManager class to implement. + */ +interface ObjectManager +{ + /** + * Finds an object by its identifier. + * + * This is just a convenient shortcut for getRepository($className)->find($id). + * + * @param string $className The class name of the object to find. + * @param mixed $id The identity of the object to find. + * + * @return object|null The found object. + * + * @template T + * @psalm-param class-string<T> $className + * @psalm-return T|null + */ + public function find($className, $id); + + /** + * Tells the ObjectManager to make an instance managed and persistent. + * + * The object will be entered into the database as a result of the flush operation. + * + * NOTE: The persist operation always considers objects that are not yet known to + * this ObjectManager as NEW. Do not pass detached objects to the persist operation. + * + * @param object $object The instance to make managed and persistent. + * + * @return void + */ + public function persist($object); + + /** + * Removes an object instance. + * + * A removed object will be removed from the database as a result of the flush operation. + * + * @param object $object The object instance to remove. + * + * @return void + */ + public function remove($object); + + /** + * Merges the state of a detached object into the persistence context + * of this ObjectManager and returns the managed copy of the object. + * The object passed to merge will not become associated/managed with this ObjectManager. + * + * @deprecated Merge operation is deprecated and will be removed in Persistence 2.0. + * Merging should be part of the business domain of an application rather than + * a generic operation of ObjectManager. + * + * @param object $object + * + * @return object + */ + public function merge($object); + + /** + * Clears the ObjectManager. All objects that are currently managed + * by this ObjectManager become detached. + * + * @param string|null $objectName if given, only objects of this type will get detached. + * + * @return void + */ + public function clear($objectName = null); + + /** + * Detaches an object from the ObjectManager, causing a managed object to + * become detached. Unflushed changes made to the object if any + * (including removal of the object), will not be synchronized to the database. + * Objects which previously referenced the detached object will continue to + * reference it. + * + * @deprecated Detach operation is deprecated and will be removed in Persistence 2.0. Please use + * {@see ObjectManager::clear()} instead. + * + * @param object $object The object to detach. + * + * @return void + */ + public function detach($object); + + /** + * Refreshes the persistent state of an object from the database, + * overriding any local changes that have not yet been persisted. + * + * @param object $object The object to refresh. + * + * @return void + */ + public function refresh($object); + + /** + * Flushes all changes to objects that have been queued up to now to the database. + * This effectively synchronizes the in-memory state of managed objects with the + * database. + * + * @return void + */ + public function flush(); + + /** + * Gets the repository for a class. + * + * @param string $className + * + * @return ObjectRepository + * + * @template T + * @psalm-param class-string<T> $className + * @psalm-return ObjectRepository<T> + */ + public function getRepository($className); + + /** + * Returns the ClassMetadata descriptor for a class. + * + * The class name must be the fully-qualified class name without a leading backslash + * (as it is returned by get_class($obj)). + * + * @param string $className + * + * @return ClassMetadata + */ + public function getClassMetadata($className); + + /** + * Gets the metadata factory used to gather the metadata of classes. + * + * @return ClassMetadataFactory + */ + public function getMetadataFactory(); + + /** + * Helper method to initialize a lazy loading proxy or persistent collection. + * + * This method is a no-op for other objects. + * + * @param object $obj + * + * @return void + */ + public function initializeObject($obj); + + /** + * Checks if the object is part of the current UnitOfWork and therefore managed. + * + * @param object $object + * + * @return bool + */ + public function contains($object); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerAware.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerAware.php new file mode 100644 index 0000000..2bf4335 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerAware.php @@ -0,0 +1,29 @@ +<?php + +namespace Doctrine\Persistence; + +use Doctrine\Persistence\Mapping\ClassMetadata; + +/** + * Makes a Persistent Objects aware of its own object-manager. + * + * Using this interface the managing object manager and class metadata instances + * are injected into the persistent object after construction. This allows + * you to implement ActiveRecord functionality on top of the persistence-ignorance + * that Doctrine propagates. + * + * Word of Warning: This is a very powerful hook to change how you can work with your domain models. + * Using this hook will break the Single Responsibility Principle inside your Domain Objects + * and increase the coupling of database and objects. + * + * Every ObjectManager has to implement this functionality itself. + */ +interface ObjectManagerAware +{ + /** + * Injects responsible ObjectManager and the ClassMetadata into this persistent object. + * + * @return void + */ + public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerDecorator.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerDecorator.php new file mode 100644 index 0000000..d7b91ee --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerDecorator.php @@ -0,0 +1,116 @@ +<?php + +namespace Doctrine\Persistence; + +/** + * Base class to simplify ObjectManager decorators + */ +abstract class ObjectManagerDecorator implements ObjectManager +{ + /** @var ObjectManager */ + protected $wrapped; + + /** + * {@inheritdoc} + */ + public function find($className, $id) + { + return $this->wrapped->find($className, $id); + } + + /** + * {@inheritdoc} + */ + public function persist($object) + { + $this->wrapped->persist($object); + } + + /** + * {@inheritdoc} + */ + public function remove($object) + { + $this->wrapped->remove($object); + } + + /** + * {@inheritdoc} + */ + public function merge($object) + { + return $this->wrapped->merge($object); + } + + /** + * {@inheritdoc} + */ + public function clear($objectName = null) + { + $this->wrapped->clear($objectName); + } + + /** + * {@inheritdoc} + */ + public function detach($object) + { + $this->wrapped->detach($object); + } + + /** + * {@inheritdoc} + */ + public function refresh($object) + { + $this->wrapped->refresh($object); + } + + /** + * {@inheritdoc} + */ + public function flush() + { + $this->wrapped->flush(); + } + + /** + * {@inheritdoc} + */ + public function getRepository($className) + { + return $this->wrapped->getRepository($className); + } + + /** + * {@inheritdoc} + */ + public function getClassMetadata($className) + { + return $this->wrapped->getClassMetadata($className); + } + + /** + * {@inheritdoc} + */ + public function getMetadataFactory() + { + return $this->wrapped->getMetadataFactory(); + } + + /** + * {@inheritdoc} + */ + public function initializeObject($obj) + { + $this->wrapped->initializeObject($obj); + } + + /** + * {@inheritdoc} + */ + public function contains($object) + { + return $this->wrapped->contains($object); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectRepository.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectRepository.php new file mode 100644 index 0000000..1450e95 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectRepository.php @@ -0,0 +1,71 @@ +<?php + +namespace Doctrine\Persistence; + +use UnexpectedValueException; + +/** + * Contract for a Doctrine persistence layer ObjectRepository class to implement. + * + * @template T + */ +interface ObjectRepository +{ + /** + * Finds an object by its primary key / identifier. + * + * @param mixed $id The identifier. + * + * @return object|null The object. + * + * @psalm-return T|null + */ + public function find($id); + + /** + * Finds all objects in the repository. + * + * @return array<int, object> The objects. + * + * @psalm-return T[] + */ + public function findAll(); + + /** + * Finds objects by a set of criteria. + * + * Optionally sorting and limiting details can be passed. An implementation may throw + * an UnexpectedValueException if certain values of the sorting or limiting details are + * not supported. + * + * @param mixed[] $criteria + * @param string[]|null $orderBy + * @param int|null $limit + * @param int|null $offset + * + * @return object[] The objects. + * + * @throws UnexpectedValueException + * + * @psalm-return T[] + */ + public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null); + + /** + * Finds a single object by a set of criteria. + * + * @param mixed[] $criteria The criteria. + * + * @return object|null The object. + * + * @psalm-return T|null + */ + public function findOneBy(array $criteria); + + /** + * Returns the class name of the object managed by the repository. + * + * @return string + */ + public function getClassName(); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/PropertyChangedListener.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/PropertyChangedListener.php new file mode 100644 index 0000000..7ab057e --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/PropertyChangedListener.php @@ -0,0 +1,22 @@ +<?php + +namespace Doctrine\Persistence; + +/** + * Contract for classes that are potential listeners of a {@see NotifyPropertyChanged} + * implementor. + */ +interface PropertyChangedListener +{ + /** + * Collect information about a property change. + * + * @param object $sender The object on which the property changed. + * @param string $propertyName The name of the property that changed. + * @param mixed $oldValue The old value of the property that changed. + * @param mixed $newValue The new value of the property that changed. + * + * @return void + */ + public function propertyChanged($sender, $propertyName, $oldValue, $newValue); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Proxy.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Proxy.php new file mode 100644 index 0000000..0d21a70 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Proxy.php @@ -0,0 +1,35 @@ +<?php + +namespace Doctrine\Persistence; + +/** + * Interface for proxy classes. + */ +interface Proxy +{ + /** + * Marker for Proxy class names. + */ + public const MARKER = '__CG__'; + + /** + * Length of the proxy marker. + */ + public const MARKER_LENGTH = 6; + + /** + * Initializes this proxy if its not yet initialized. + * + * Acts as a no-op if already initialized. + * + * @return void + */ + public function __load(); + + /** + * Returns whether this proxy is initialized or not. + * + * @return bool + */ + public function __isInitialized(); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/RuntimePublicReflectionProperty.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/RuntimePublicReflectionProperty.php new file mode 100644 index 0000000..80124c2 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/RuntimePublicReflectionProperty.php @@ -0,0 +1,57 @@ +<?php + +namespace Doctrine\Persistence\Reflection; + +use Doctrine\Common\Proxy\Proxy; +use ReflectionProperty; + +/** + * PHP Runtime Reflection Public Property - special overrides for public properties. + */ +class RuntimePublicReflectionProperty extends ReflectionProperty +{ + /** + * {@inheritDoc} + * + * Checks is the value actually exist before fetching it. + * This is to avoid calling `__get` on the provided $object if it + * is a {@see \Doctrine\Common\Proxy\Proxy}. + */ + public function getValue($object = null) + { + $name = $this->getName(); + + if ($object instanceof Proxy && ! $object->__isInitialized()) { + $originalInitializer = $object->__getInitializer(); + $object->__setInitializer(null); + $val = $object->$name ?? null; + $object->__setInitializer($originalInitializer); + + return $val; + } + + return isset($object->$name) ? parent::getValue($object) : null; + } + + /** + * {@inheritDoc} + * + * Avoids triggering lazy loading via `__set` if the provided object + * is a {@see \Doctrine\Common\Proxy\Proxy}. + * + * @link https://bugs.php.net/bug.php?id=63463 + */ + public function setValue($object, $value = null) + { + if (! ($object instanceof Proxy && ! $object->__isInitialized())) { + parent::setValue($object, $value); + + return; + } + + $originalInitializer = $object->__getInitializer(); + $object->__setInitializer(null); + parent::setValue($object, $value); + $object->__setInitializer($originalInitializer); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/TypedNoDefaultReflectionProperty.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/TypedNoDefaultReflectionProperty.php new file mode 100644 index 0000000..8c0479c --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/TypedNoDefaultReflectionProperty.php @@ -0,0 +1,48 @@ +<?php + +namespace Doctrine\Persistence\Reflection; + +use ReflectionProperty; + +/** + * PHP Typed No Default Reflection Property - special override for typed properties without a default value. + */ +class TypedNoDefaultReflectionProperty extends ReflectionProperty +{ + /** + * {@inheritDoc} + * + * Checks that a typed property is initialized before accessing its value. + * This is necessary to avoid PHP error "Error: Typed property must not be accessed before initialization". + * Should be used only for reflecting typed properties without a default value. + */ + public function getValue($object = null) + { + return $object !== null && $this->isInitialized($object) ? parent::getValue($object) : null; + } + + /** + * {@inheritDoc} + * + * Works around the problem with setting typed no default properties to + * NULL which is not supported, instead unset() to uninitialize. + * + * @link https://github.com/doctrine/orm/issues/7999 + */ + public function setValue($object, $value = null) + { + if ($value === null && $this->hasType() && ! $this->getType()->allowsNull()) { + $propertyName = $this->getName(); + + $unsetter = function () use ($propertyName) { + unset($this->$propertyName); + }; + $unsetter = $unsetter->bindTo($object, $this->getDeclaringClass()->getName()); + $unsetter(); + + return; + } + + parent::setValue($object, $value); + } +} diff --git a/vendor/doctrine/persistence/psalm.xml b/vendor/doctrine/persistence/psalm.xml new file mode 100644 index 0000000..d92c344 --- /dev/null +++ b/vendor/doctrine/persistence/psalm.xml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<psalm + totallyTyped="false" + errorLevel="4" + resolveFromConfigFile="true" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="https://getpsalm.org/schema/config" + xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" +> + <projectFiles> + <directory name="lib/Doctrine/Persistence" /> + <ignoreFiles> + <directory name="vendor" /> + </ignoreFiles> + </projectFiles> + <issueHandlers> + <RedundantCondition> + <errorLevel type="suppress"> + <!-- see https://github.com/JetBrains/phpstorm-stubs/pull/877 --> + <file name="lib/Doctrine/Persistence/Reflection/TypedNoDefaultReflectionProperty.php"/> + </errorLevel> + </RedundantCondition> + </issueHandlers> +</psalm> |