24
24
use Doctrine \Persistence \Mapping \Driver \MappingDriver ;
25
25
use Doctrine \Persistence \ObjectRepository ;
26
26
use InvalidArgumentException ;
27
+ use LogicException ;
27
28
use MongoDB \Driver \WriteConcern ;
28
29
use ProxyManager \Configuration as ProxyManagerConfiguration ;
29
30
use ProxyManager \Factory \LazyLoadingGhostFactory ;
33
34
use ReflectionClass ;
34
35
35
36
use function array_key_exists ;
37
+ use function class_exists ;
36
38
use function interface_exists ;
37
39
use function trigger_deprecation ;
38
40
use function trim ;
@@ -82,12 +84,23 @@ class Configuration
82
84
*/
83
85
public const AUTOGENERATE_EVAL = 3 ;
84
86
87
+ /**
88
+ * Autogenerate the proxy class when the proxy file does not exist or
89
+ * when the proxied file changed.
90
+ *
91
+ * This strategy causes a file_exists() call whenever any proxy is used the
92
+ * first time in a request. When the proxied file is changed, the proxy will
93
+ * be updated.
94
+ */
95
+ public const AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED = 4 ;
96
+
85
97
/**
86
98
* Array of attributes for this configuration instance.
87
99
*
88
100
* @phpstan-var array{
89
101
* autoGenerateHydratorClasses?: self::AUTOGENERATE_*,
90
102
* autoGeneratePersistentCollectionClasses?: self::AUTOGENERATE_*,
103
+ * autoGenerateProxyClasses?: self::AUTOGENERATE_*,
91
104
* classMetadataFactoryName?: class-string<ClassMetadataFactoryInterface>,
92
105
* defaultCommitOptions?: CommitOptions,
93
106
* defaultDocumentRepositoryClassName?: class-string<ObjectRepository<object>>,
@@ -106,24 +119,21 @@ class Configuration
106
119
* persistentCollectionGenerator?: PersistentCollectionGenerator,
107
120
* persistentCollectionDir?: string,
108
121
* persistentCollectionNamespace?: string,
122
+ * proxyDir?: string,
123
+ * proxyNamespace?: string,
109
124
* repositoryFactory?: RepositoryFactory
110
125
* }
111
126
*/
112
127
private array $ attributes = [];
113
128
114
129
private ?CacheItemPoolInterface $ metadataCache = null ;
115
130
131
+ /** @deprecated */
116
132
private ProxyManagerConfiguration $ proxyManagerConfiguration ;
117
133
118
- private int $ autoGenerateProxyClasses = self ::AUTOGENERATE_EVAL ;
119
-
120
134
private bool $ useTransactionalFlush = false ;
121
135
122
- public function __construct ()
123
- {
124
- $ this ->proxyManagerConfiguration = new ProxyManagerConfiguration ();
125
- $ this ->setAutoGenerateProxyClasses (self ::AUTOGENERATE_FILE_NOT_EXISTS );
126
- }
136
+ private bool $ useLazyGhostObject = true ;
127
137
128
138
/**
129
139
* Adds a namespace under a certain alias.
@@ -248,68 +258,52 @@ public function setMetadataCache(CacheItemPoolInterface $cache): void
248
258
*/
249
259
public function setProxyDir (string $ dir ): void
250
260
{
251
- $ this ->getProxyManagerConfiguration ()->setProxiesTargetDir ($ dir );
252
-
253
- // Recreate proxy generator to ensure its path was updated
254
- if ($ this ->autoGenerateProxyClasses !== self ::AUTOGENERATE_FILE_NOT_EXISTS ) {
255
- return ;
256
- }
257
-
258
- $ this ->setAutoGenerateProxyClasses ($ this ->autoGenerateProxyClasses );
261
+ $ this ->attributes ['proxyDir ' ] = $ dir ;
262
+ unset($ this ->proxyManagerConfiguration );
259
263
}
260
264
261
265
/**
262
266
* Gets the directory where Doctrine generates any necessary proxy class files.
263
267
*/
264
268
public function getProxyDir (): ?string
265
269
{
266
- return $ this ->getProxyManagerConfiguration ()-> getProxiesTargetDir () ;
270
+ return $ this ->attributes [ ' proxyDir ' ] ?? null ;
267
271
}
268
272
269
273
/**
270
274
* Gets an int flag that indicates whether proxy classes should always be regenerated
271
275
* during each script execution.
276
+ *
277
+ * @return self::AUTOGENERATE_*
272
278
*/
273
279
public function getAutoGenerateProxyClasses (): int
274
280
{
275
- return $ this ->autoGenerateProxyClasses ;
281
+ return $ this ->attributes [ ' autoGenerateProxyClasses ' ] ?? self :: AUTOGENERATE_FILE_NOT_EXISTS ;
276
282
}
277
283
278
284
/**
279
285
* Sets an int flag that indicates whether proxy classes should always be regenerated
280
286
* during each script execution.
281
287
*
288
+ * @param self::AUTOGENERATE_* $mode
289
+ *
282
290
* @throws InvalidArgumentException If an invalid mode was given.
283
291
*/
284
292
public function setAutoGenerateProxyClasses (int $ mode ): void
285
293
{
286
- $ this ->autoGenerateProxyClasses = $ mode ;
287
- $ proxyManagerConfig = $ this ->getProxyManagerConfiguration ();
288
-
289
- switch ($ mode ) {
290
- case self ::AUTOGENERATE_FILE_NOT_EXISTS :
291
- $ proxyManagerConfig ->setGeneratorStrategy (new FileWriterGeneratorStrategy (
292
- new FileLocator ($ proxyManagerConfig ->getProxiesTargetDir ()),
293
- ));
294
-
295
- break ;
296
- case self ::AUTOGENERATE_EVAL :
297
- $ proxyManagerConfig ->setGeneratorStrategy (new EvaluatingGeneratorStrategy ());
298
-
299
- break ;
300
- default :
301
- throw new InvalidArgumentException ('Invalid proxy generation strategy given - only AUTOGENERATE_FILE_NOT_EXISTS and AUTOGENERATE_EVAL are supported. ' );
302
- }
294
+ $ this ->attributes ['autoGenerateProxyClasses ' ] = $ mode ;
295
+ unset($ this ->proxyManagerConfiguration );
303
296
}
304
297
305
298
public function getProxyNamespace (): ?string
306
299
{
307
- return $ this ->getProxyManagerConfiguration ()-> getProxiesNamespace () ;
300
+ return $ this ->attributes [ ' proxyNamespace ' ] ?? null ;
308
301
}
309
302
310
303
public function setProxyNamespace (string $ ns ): void
311
304
{
312
- $ this ->getProxyManagerConfiguration ()->setProxiesNamespace ($ ns );
305
+ $ this ->attributes ['proxyNamespace ' ] = $ ns ;
306
+ unset($ this ->proxyManagerConfiguration );
313
307
}
314
308
315
309
public function setHydratorDir (string $ dir ): void
@@ -589,14 +583,39 @@ public function getPersistentCollectionGenerator(): PersistentCollectionGenerato
589
583
return $ this ->attributes ['persistentCollectionGenerator ' ];
590
584
}
591
585
586
+ /** @deprecated */
592
587
public function buildGhostObjectFactory (): LazyLoadingGhostFactory
593
588
{
594
- return new LazyLoadingGhostFactory (clone $ this ->getProxyManagerConfiguration ());
589
+ return new LazyLoadingGhostFactory ($ this ->getProxyManagerConfiguration ());
595
590
}
596
591
592
+ /** @deprecated */
597
593
public function getProxyManagerConfiguration (): ProxyManagerConfiguration
598
594
{
599
- return $ this ->proxyManagerConfiguration ;
595
+ if (isset ($ this ->proxyManagerConfiguration )) {
596
+ return $ this ->proxyManagerConfiguration ;
597
+ }
598
+
599
+ $ proxyManagerConfiguration = new ProxyManagerConfiguration ();
600
+ $ proxyManagerConfiguration ->setProxiesTargetDir ($ this ->getProxyDir ());
601
+ $ proxyManagerConfiguration ->setProxiesNamespace ($ this ->getProxyNamespace ());
602
+
603
+ switch ($ this ->getAutoGenerateProxyClasses ()) {
604
+ case self ::AUTOGENERATE_FILE_NOT_EXISTS :
605
+ $ proxyManagerConfiguration ->setGeneratorStrategy (new FileWriterGeneratorStrategy (
606
+ new FileLocator ($ proxyManagerConfiguration ->getProxiesTargetDir ()),
607
+ ));
608
+
609
+ break ;
610
+ case self ::AUTOGENERATE_EVAL :
611
+ $ proxyManagerConfiguration ->setGeneratorStrategy (new EvaluatingGeneratorStrategy ());
612
+
613
+ break ;
614
+ default :
615
+ throw new InvalidArgumentException ('Invalid proxy generation strategy given - only AUTOGENERATE_FILE_NOT_EXISTS and AUTOGENERATE_EVAL are supported. ' );
616
+ }
617
+
618
+ return $ this ->proxyManagerConfiguration = $ proxyManagerConfiguration ;
600
619
}
601
620
602
621
public function setUseTransactionalFlush (bool $ useTransactionalFlush ): void
@@ -608,6 +627,32 @@ public function isTransactionalFlushEnabled(): bool
608
627
{
609
628
return $ this ->useTransactionalFlush ;
610
629
}
630
+
631
+ /**
632
+ * Generate proxy classes using Symfony VarExporter's LazyGhostTrait if true.
633
+ * Otherwise, use ProxyManager's LazyLoadingGhostFactory (deprecated)
634
+ */
635
+ public function setUseLazyGhostObject (bool $ flag ): void
636
+ {
637
+ if ($ flag === false ) {
638
+ if (! class_exists (ProxyManagerConfiguration::class)) {
639
+ throw new LogicException ('Package "friendsofphp/proxy-manager-lts" is required to disable LazyGhostObject. ' );
640
+ }
641
+
642
+ trigger_deprecation (
643
+ 'doctrine/mongodb-odm ' ,
644
+ '2.10 ' ,
645
+ 'Using "friendsofphp/proxy-manager-lts" is deprecated. Use "symfony/var-exporter" LazyGhostObjects instead. ' ,
646
+ );
647
+ }
648
+
649
+ $ this ->useLazyGhostObject = $ flag ;
650
+ }
651
+
652
+ public function isLazyGhostObjectEnabled (): bool
653
+ {
654
+ return $ this ->useLazyGhostObject ;
655
+ }
611
656
}
612
657
613
658
interface_exists (MappingDriver::class);
0 commit comments