Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ jobs:
- name: "Remove optional dependencies"
if: "${{ matrix.remove-optional-dependencies }}"
run: |
composer remove --no-update friendsofphp/proxy-manager-lts symfony/var-exporter
composer remove --no-update --dev symfony/cache doctrine/orm doctrine/annotations
composer remove --no-update --dev doctrine/coding-standard phpstan/phpstan phpstan/phpstan-deprecation-rule phpstan/phpstan-phpunit

Expand All @@ -136,6 +135,4 @@ jobs:
run: "vendor/bin/phpunit --exclude-group=atlas ${{ matrix.dependencies == 'lowest' && '--do-not-fail-on-deprecation --do-not-fail-on-warning --do-not-fail-on-notice' || '' }}"
env:
DOCTRINE_MONGODB_SERVER: ${{ steps.setup-mongodb.outputs.cluster-uri }}
USE_LAZY_GHOST_OBJECT: 0
USE_NATIVE_LAZY_OBJECT: 1
CRYPT_SHARED_LIB_PATH: ${{ steps.setup-mongodb.outputs.crypt-shared-lib-path }}
2 changes: 0 additions & 2 deletions benchmark/BaseBench.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ public function initDocumentManager(): void
{
$config = new Configuration();

$config->setProxyDir(__DIR__ . '/../../tests/Proxies');
$config->setProxyNamespace('Proxies');
$config->setHydratorDir(__DIR__ . '/../../tests/Hydrators');
$config->setHydratorNamespace('Hydrators');
$config->setPersistentCollectionDir(__DIR__ . '/../../tests/PersistentCollections');
Expand Down
4 changes: 1 addition & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,10 @@
"doctrine/event-manager": "^1.0 || ^2.0",
"doctrine/instantiator": "^1.1 || ^2",
"doctrine/persistence": "^3.2 || ^4",
"friendsofphp/proxy-manager-lts": "^1.0",
"mongodb/mongodb": "^2.1.1",
"psr/cache": "^1.0 || ^2.0 || ^3.0",
"symfony/console": "^5.4 || ^6.4 || ^7.0 || ^8.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0",
"symfony/var-exporter": "^6.4 || ^7.0 || ^8.0"
"symfony/deprecation-contracts": "^2.2 || ^3.0"
},
"require-dev": {
"ext-bcmath": "*",
Expand Down
2 changes: 0 additions & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,5 @@
<ini name="error_reporting" value="-1"/>
<const name="DOCTRINE_MONGODB_SERVER" value="mongodb://localhost:27017" />
<const name="DOCTRINE_MONGODB_DATABASE" value="doctrine_odm_tests" />
<env name="USE_LAZY_GHOST_OBJECT" value="1"/>
<env name="USE_NATIVE_LAZY_OBJECT" value="0"/>
</php>
</phpunit>
173 changes: 10 additions & 163 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,26 @@
use Doctrine\ODM\MongoDB\PersistentCollection\DefaultPersistentCollectionGenerator;
use Doctrine\ODM\MongoDB\PersistentCollection\PersistentCollectionFactory;
use Doctrine\ODM\MongoDB\PersistentCollection\PersistentCollectionGenerator;
use Doctrine\ODM\MongoDB\Proxy\FileLocator;
use Doctrine\ODM\MongoDB\Repository\DefaultGridFSRepository;
use Doctrine\ODM\MongoDB\Repository\DefaultRepositoryFactory;
use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
use Doctrine\ODM\MongoDB\Repository\GridFSRepository;
use Doctrine\ODM\MongoDB\Repository\RepositoryFactory;
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\Persistence\ObjectRepository;
use InvalidArgumentException;
use LogicException;
use MongoDB\Client;
use MongoDB\Driver\Manager;
use MongoDB\Driver\WriteConcern;
use ProxyManager\Configuration as ProxyManagerConfiguration;
use ProxyManager\Factory\LazyLoadingGhostFactory;
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
use ProxyManager\GeneratorStrategy\FileWriterGeneratorStrategy;
use Psr\Cache\CacheItemPoolInterface;
use ReflectionClass;
use stdClass;
use Symfony\Component\VarExporter\LazyGhostTrait;
use Throwable;

use function array_diff_key;
use function array_intersect_key;
use function array_key_exists;
use function class_exists;
use function interface_exists;
use function is_string;
use function trait_exists;
use function trigger_deprecation;
use function trim;

Expand All @@ -65,42 +55,39 @@
class Configuration
{
/**
* Never autogenerate a proxy/hydrator/persistent collection and rely that
* it was generated by some process before deployment. Copied from
* \Doctrine\Common\Proxy\AbstractProxyFactory.
* Never autogenerate a hydrator/persistent collection and rely that
* it was generated by some process before deployment.
*/
public const AUTOGENERATE_NEVER = 0;

/**
* Always generates a new proxy/hydrator/persistent collection in every request.
* Always generates a new hydrator/persistent collection in every request.
*
* This is only sane during development.
* Copied from \Doctrine\Common\Proxy\AbstractProxyFactory.
*/
public const AUTOGENERATE_ALWAYS = 1;

/**
* Autogenerate the proxy/hydrator/persistent collection class when the file does not exist.
* Autogenerate the hydrator/persistent collection class when the file does not exist.
*
* This strategy causes a file exists call whenever any proxy/hydrator is used the
* first time in a request. Copied from \Doctrine\Common\Proxy\AbstractProxyFactory.
* This strategy causes a file exists call whenever any hydrator is used the
* first time in a request.
*/
public const AUTOGENERATE_FILE_NOT_EXISTS = 2;

/**
* Generate the proxy/hydrator/persistent collection classes using eval().
* Generate the hydrator/persistent collection classes using eval().
*
* This strategy is only sane for development.
* Copied from \Doctrine\Common\Proxy\AbstractProxyFactory.
*/
public const AUTOGENERATE_EVAL = 3;

/**
* Autogenerate the proxy class when the proxy file does not exist or
* Autogenerate the class when the file does not exist or
* when the proxied file changed.
*
* This strategy causes a file_exists() call whenever any proxy is used the
* first time in a request. When the proxied file is changed, the proxy will
* This strategy causes a file_exists() call whenever any class is used the
* first time in a request. When the proxied file is changed, the class will
* be updated.
*/
public const AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED = 4;
Expand All @@ -111,7 +98,6 @@ class Configuration
* @phpstan-var array{
* autoGenerateHydratorClasses?: self::AUTOGENERATE_*,
* autoGeneratePersistentCollectionClasses?: self::AUTOGENERATE_*,
* autoGenerateProxyClasses?: self::AUTOGENERATE_*,
* classMetadataFactoryName?: class-string<ClassMetadataFactoryInterface>,
* defaultCommitOptions?: CommitOptions,
* defaultDocumentRepositoryClassName?: class-string<ObjectRepository<object>>,
Expand All @@ -130,8 +116,6 @@ class Configuration
* persistentCollectionGenerator?: PersistentCollectionGenerator,
* persistentCollectionDir?: string,
* persistentCollectionNamespace?: string,
* proxyDir?: string,
* proxyNamespace?: string,
* repositoryFactory?: RepositoryFactory,
* kmsProvider?: KmsProvider,
* defaultMasterKey?: array<string, mixed>|null,
Expand All @@ -142,14 +126,8 @@ class Configuration

private ?CacheItemPoolInterface $metadataCache = null;

/** @deprecated */
private ProxyManagerConfiguration $proxyManagerConfiguration;

private bool $useTransactionalFlush = false;

private bool $lazyGhostObject = false;
private bool $nativeLazyObject = false;

private static string $version;

/**
Expand Down Expand Up @@ -312,57 +290,6 @@ public function setMetadataCache(CacheItemPoolInterface $cache): void
$this->attributes['metadataCacheImpl'] = DoctrineProvider::wrap($cache);
}

/**
* Sets the directory where Doctrine generates any necessary proxy class files.
*/
public function setProxyDir(string $dir): void
{
$this->attributes['proxyDir'] = $dir;
unset($this->proxyManagerConfiguration);
}

/**
* Gets the directory where Doctrine generates any necessary proxy class files.
*/
public function getProxyDir(): ?string
{
return $this->attributes['proxyDir'] ?? null;
}

/**
* Gets an int flag that indicates whether proxy classes should always be regenerated
* during each script execution.
*
* @return self::AUTOGENERATE_*
*/
public function getAutoGenerateProxyClasses(): int
{
return $this->attributes['autoGenerateProxyClasses'] ?? self::AUTOGENERATE_FILE_NOT_EXISTS;
}

/**
* Sets an int flag that indicates whether proxy classes should always be regenerated
* during each script execution.
*
* @param self::AUTOGENERATE_* $mode
*/
public function setAutoGenerateProxyClasses(int $mode): void
{
$this->attributes['autoGenerateProxyClasses'] = $mode;
unset($this->proxyManagerConfiguration);
}

public function getProxyNamespace(): ?string
{
return $this->attributes['proxyNamespace'] ?? null;
}

public function setProxyNamespace(string $ns): void
{
$this->attributes['proxyNamespace'] = $ns;
unset($this->proxyManagerConfiguration);
}

public function setHydratorDir(string $dir): void
{
$this->attributes['hydratorDir'] = $dir;
Expand Down Expand Up @@ -640,41 +567,6 @@ public function getPersistentCollectionGenerator(): PersistentCollectionGenerato
return $this->attributes['persistentCollectionGenerator'];
}

/** @deprecated */
public function buildGhostObjectFactory(): LazyLoadingGhostFactory
{
return new LazyLoadingGhostFactory($this->getProxyManagerConfiguration());
}

/** @deprecated */
public function getProxyManagerConfiguration(): ProxyManagerConfiguration
{
if (isset($this->proxyManagerConfiguration)) {
return $this->proxyManagerConfiguration;
}

$proxyManagerConfiguration = new ProxyManagerConfiguration();
$proxyManagerConfiguration->setProxiesTargetDir($this->getProxyDir());
$proxyManagerConfiguration->setProxiesNamespace($this->getProxyNamespace());

switch ($this->getAutoGenerateProxyClasses()) {
case self::AUTOGENERATE_FILE_NOT_EXISTS:
$proxyManagerConfiguration->setGeneratorStrategy(new FileWriterGeneratorStrategy(
new FileLocator($proxyManagerConfiguration->getProxiesTargetDir()),
));

break;
case self::AUTOGENERATE_EVAL:
$proxyManagerConfiguration->setGeneratorStrategy(new EvaluatingGeneratorStrategy());

break;
default:
throw new InvalidArgumentException('Invalid proxy generation strategy given - only AUTOGENERATE_FILE_NOT_EXISTS and AUTOGENERATE_EVAL are supported.');
}

return $this->proxyManagerConfiguration = $proxyManagerConfiguration;
}

public function setUseTransactionalFlush(bool $useTransactionalFlush): void
{
$this->useTransactionalFlush = $useTransactionalFlush;
Expand All @@ -685,51 +577,6 @@ public function isTransactionalFlushEnabled(): bool
return $this->useTransactionalFlush;
}

/**
* Generate proxy classes using Symfony VarExporter's LazyGhostTrait if true.
* Otherwise, use ProxyManager's LazyLoadingGhostFactory (deprecated)
*/
public function setUseLazyGhostObject(bool $flag): void
{
if ($this->nativeLazyObject) {
throw new LogicException('Cannot enable or disable LazyGhostObject when native lazy objects are enabled.');
}

if ($flag && ! trait_exists(LazyGhostTrait::class)) {
throw new LogicException('Package "symfony/var-exporter" >= 8.0 does not provide lazy ghost objects, use native lazy objects instead.');
}

if (! $flag) {
if (! class_exists(ProxyManagerConfiguration::class)) {
throw new LogicException('Package "friendsofphp/proxy-manager-lts" is required to disable LazyGhostObject.');
}

trigger_deprecation('doctrine/mongodb-odm', '2.10', 'Using "friendsofphp/proxy-manager-lts" is deprecated. Use "symfony/var-exporter" LazyGhostObjects instead.');
}

$this->lazyGhostObject = $flag;
}

public function isLazyGhostObjectEnabled(): bool
{
// Always false if native lazy objects are enabled
return $this->lazyGhostObject && ! $this->nativeLazyObject;
}

public function setUseNativeLazyObject(bool $nativeLazyObject): void
{
$this->nativeLazyObject = $nativeLazyObject;
}

public function isNativeLazyObjectEnabled(): bool
{
if (! $this->nativeLazyObject) {
trigger_deprecation('doctrine/mongodb-odm', '2.14', 'Not using native lazy objects is deprecated and will be impossible in Doctrine MongoDB ODM 3.0.');
}

return $this->nativeLazyObject;
}

/**
* Set the KMS provider to use for auto-encryption. The name of the KMS provider
* must be specified in the 'type' key of the array.
Expand Down
5 changes: 0 additions & 5 deletions src/ConfigurationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ public static function noMetadataDriverConfigured(): self
return new self('No metadata driver was configured. Please set a metadata driver implementation in your configuration.');
}

public static function proxyDirMissing(): self
{
return new self('No proxy directory was configured. Please set a target directory first!');
}

public static function clientEncryptionOptionsNotSet(): self
{
return new self('MongoDB client encryption options are not set in configuration');
Expand Down
Loading