Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
197ed0b7
Commit
197ed0b7
authored
Jul 16, 2009
by
piccoloprincipe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2.0] working implementation of reference proxies
parent
0b9a2e0c
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
151 additions
and
80 deletions
+151
-80
Factory.php
lib/Doctrine/ORM/DynamicProxy/Factory.php
+84
-0
Generator.php
lib/Doctrine/ORM/DynamicProxy/Generator.php
+56
-72
EntityManager.php
lib/Doctrine/ORM/EntityManager.php
+11
-8
No files found.
lib/Doctrine/ORM/DynamicProxy/Factory.php
0 → 100644
View file @
197ed0b7
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace
Doctrine\ORM\DynamicProxy
;
use
Doctrine\ORM\EntityManager
;
/**
* This Factory is used to create proxy objects for entities at runtime.
*
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
*/
class
Factory
{
private
$_em
;
private
$_generator
;
/**
* Initializes a new instance of the <tt>DynamicProxyGenerator</tt> class that is
* connected to the given <tt>EntityManager</tt> and stores proxy class files in
* the given cache directory.
*
* @param EntityManager $em
* @param Generator $generator
*/
public
function
__construct
(
EntityManager
$em
,
Generator
$generator
)
{
$this
->
_em
=
$em
;
$this
->
_generator
=
$generator
;
}
/**
* Gets a reference proxy instance.
*
* @param string $className
* @param mixed $identifier
* @return object
*/
public
function
getReferenceProxy
(
$className
,
$identifier
)
{
$proxyClassName
=
$this
->
_generator
->
generateReferenceProxyClass
(
$className
);
$entityPersister
=
$this
->
_em
->
getUnitOfWork
()
->
getEntityPersister
(
$className
);
return
new
$proxyClassName
(
$entityPersister
,
$identifier
);
}
/**
* Gets an association proxy instance.
*/
public
function
getAssociationProxy
(
$owner
,
\Doctrine\ORM\Mapping\AssociationMapping
$assoc
)
{
throw
new
Exception
(
"Not yet implemented."
);
$proxyClassName
=
str_replace
(
'\\'
,
'_'
,
$assoc
->
getTargetEntityName
())
.
'AProxy'
;
if
(
!
class_exists
(
$proxyClassName
,
false
))
{
$this
->
_em
->
getMetadataFactory
()
->
setMetadataFor
(
self
::
$_ns
.
$proxyClassName
,
$this
->
_em
->
getClassMetadata
(
$assoc
->
getTargetEntityName
()));
$fileName
=
$this
->
_cacheDir
.
$proxyClassName
.
'.g.php'
;
if
(
!
file_exists
(
$fileName
))
{
$this
->
_generateAssociationProxyClass
(
$assoc
->
getTargetEntityName
(),
$proxyClassName
,
$fileName
);
}
require
$fileName
;
}
$proxyClassName
=
'\\'
.
self
::
$_ns
.
$proxyClassName
;
return
new
$proxyClassName
(
$this
->
_em
,
$assoc
,
$owner
);
}
}
lib/Doctrine/ORM/DynamicProxyGenerator.php
→
lib/Doctrine/ORM/DynamicProxy
/
Generator.php
View file @
197ed0b7
...
...
@@ -19,7 +19,9 @@
* <http://www.doctrine-project.org>.
*/
namespace
Doctrine\ORM
;
namespace
Doctrine\ORM\DynamicProxy
;
use
Doctrine\ORM\EntityManager
;
use
Doctrine\ORM\Mapping\ClassMetadata
;
/**
* The DynamicProxyGenerator is used to generate proxy objects for entities at runtime.
...
...
@@ -27,17 +29,15 @@ namespace Doctrine\ORM;
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
*/
class
DynamicProxy
Generator
class
Generator
{
/** The namspace for the generated proxy classes. */
/** The nam
e
space for the generated proxy classes. */
private
static
$_ns
=
'Doctrine\Generated\Proxies\\'
;
private
$_cacheDir
;
private
$_em
;
/**
* Initializes a new instance of the <tt>DynamicProxyGenerator</tt> class that is
* connected to the given <tt>EntityManager</tt> and stores proxy class files in
* the given cache directory.
* Generates and stores proxy class files in the given cache directory.
*
* @param EntityManager $em
* @param string $cacheDir
...
...
@@ -48,67 +48,58 @@ class DynamicProxyGenerator
if
(
$cacheDir
===
null
)
{
$cacheDir
=
sys_get_temp_dir
();
}
$this
->
_cacheDir
=
$cacheDir
;
$this
->
_cacheDir
=
rtrim
(
$cacheDir
,
'/'
)
.
'/'
;
}
/**
* Gets a reference proxy instance.
* Generates a reference proxy class.
* This is a proxy for an object which we have the id for retrieval.
*
* @param string $className
* @param
mixed $identifier
* @
return object
* @param
string $proxyClassName
* @
param string $fileName
*/
public
function
ge
tReferenceProxy
(
$className
,
$identifier
)
public
function
ge
nerateReferenceProxyClass
(
$className
)
{
$class
=
$this
->
_em
->
getClassMetadata
(
$className
);
$proxyClassName
=
str_replace
(
'\\'
,
'_'
,
$className
)
.
'RProxy'
;
if
(
!
class_exists
(
$proxyClassName
,
false
))
{
if
(
!
class_exists
(
$proxyClassName
,
false
))
{
$this
->
_em
->
getMetadataFactory
()
->
setMetadataFor
(
self
::
$_ns
.
$proxyClassName
,
$class
);
$fileName
=
$this
->
_cacheDir
.
$proxyClassName
.
'.g.php'
;
if
(
!
file_exists
(
$fileName
))
{
$this
->
_generateReferenceProxyClass
(
$className
,
$identifier
,
$proxyClassName
,
$fileName
);
}
if
(
file_exists
(
$fileName
))
{
require
$fileName
;
}
$proxyClassName
=
'\\'
.
self
::
$_ns
.
$proxyClassName
;
return
new
$proxyClassName
(
$this
->
_em
,
$class
,
$identifier
);
return
$proxyClassName
;
}
/**
* Gets an association proxy instance.
*/
public
function
getAssociationProxy
(
$owner
,
\Doctrine\ORM\Mapping\AssociationMapping
$assoc
)
{
$proxyClassName
=
str_replace
(
'\\'
,
'_'
,
$assoc
->
getTargetEntityName
())
.
'AProxy'
;
if
(
!
class_exists
(
$proxyClassName
,
false
))
{
$this
->
_em
->
getMetadataFactory
()
->
setMetadataFor
(
self
::
$_ns
.
$proxyClassName
,
$this
->
_em
->
getClassMetadata
(
$assoc
->
getTargetEntityName
()));
$fileName
=
$this
->
_cacheDir
.
$proxyClassName
.
'.g.php'
;
if
(
!
file_exists
(
$fileName
))
{
$this
->
_generateAssociationProxyClass
(
$assoc
->
getTargetEntityName
(),
$proxyClassName
,
$fileName
);
}
$file
=
self
::
$_proxyClassTemplate
;
$methods
=
$this
->
_generateMethods
(
$class
);
$sleepImpl
=
$this
->
_generateSleep
(
$class
);
$placeholders
=
array
(
'<proxyClassName>'
,
'<className>'
,
'<methods>'
,
'<sleepImpl>'
);
$replacements
=
array
(
$proxyClassName
,
$className
,
$methods
,
$sleepImpl
);
$file
=
str_replace
(
$placeholders
,
$replacements
,
$file
);
file_put_contents
(
$fileName
,
$file
);
require
$fileName
;
}
$proxyClassName
=
'\\'
.
self
::
$_ns
.
$proxyClassName
;
return
new
$proxyClassName
(
$this
->
_em
,
$assoc
,
$owner
);
return
$proxyClassName
;
}
/**
* Generates a proxy class.
*
* @param string $className
* @param mixed $id
* @param string $proxyClassName
* @param string $fileName
*/
private
function
_generateReferenceProxyClass
(
$className
,
$id
,
$proxyClassName
,
$fileName
)
protected
function
_generateMethods
(
ClassMetadata
$class
)
{
$class
=
$this
->
_em
->
getClassMetadata
(
$className
);
$file
=
self
::
$_proxyClassTemplate
;
$methods
=
''
;
foreach
(
$class
->
reflClass
->
getMethods
()
as
$method
)
{
if
(
$method
->
getName
()
==
'__construct'
)
{
continue
;
}
if
(
$method
->
isPublic
()
&&
!
$method
->
isFinal
())
{
$methods
.=
PHP_EOL
.
'public function '
.
$method
->
getName
()
.
'('
;
$firstParam
=
true
;
...
...
@@ -127,7 +118,11 @@ class DynamicProxyGenerator
$methods
.=
'}'
.
PHP_EOL
;
}
}
return
$methods
;
}
public
function
_generateSleep
(
ClassMetadata
$class
)
{
$sleepImpl
=
''
;
if
(
$class
->
reflClass
->
hasMethod
(
'__sleep'
))
{
$sleepImpl
.=
'return parent::__sleep();'
;
...
...
@@ -144,29 +139,18 @@ class DynamicProxyGenerator
}
$sleepImpl
.=
');'
;
}
$placeholders
=
array
(
'<proxyClassName>'
,
'<className>'
,
'<methods>'
,
'<sleepImpl>'
);
$replacements
=
array
(
$proxyClassName
,
$className
,
$methods
,
$sleepImpl
);
$file
=
str_replace
(
$placeholders
,
$replacements
,
$file
);
file_put_contents
(
$fileName
,
$file
);
return
$sleepImpl
;
}
/**
* Generates a proxy class.
* This is a proxy class for an object which we have the association where
* it is involved, but no primary key to retrieve it.
*
* @param string $className
* @param mixed $id
* @param string $proxyClassName
* @param string $fileName
*/
p
rivate
function
_generateAssociationProxyClass
(
$className
,
$proxyClassName
,
$file
Name
)
p
ublic
function
generateAssociationProxyClass
(
$className
,
$proxyClass
Name
)
{
$class
=
$this
->
_em
->
getClassMetadata
(
$className
);
$file
=
self
::
$_assocProxyClassTemplate
;
...
...
@@ -220,6 +204,7 @@ class DynamicProxyGenerator
$file
=
str_replace
(
$placeholders
,
$replacements
,
$file
);
file_put_contents
(
$fileName
,
$file
);
return
$fileName
;
}
/** Proxy class code template */
...
...
@@ -228,19 +213,18 @@ class DynamicProxyGenerator
/** This class was generated by the Doctrine ORM. DO NOT EDIT THIS FILE. */
namespace Doctrine\Generated\Proxies {
class <proxyClassName> extends \<className> {
private $_e
m
;
private $_
class
;
private $_e
ntityPersister
;
private $_
identifier
;
private $_loaded = false;
public function __construct($em, $class, $identifier) {
$this->_em = $em;
$this->_class = $class;
$this->_class->setIdentifierValues($this, $identifier);
public function __construct($entityPersister, $identifier) {
$this->_entityPersister = $entityPersister;
$this->_identifier = $identifier;
}
private function _load() {
if ( ! $this->_loaded) {
$this->_e
m->getUnitOfWork()->getEntityPersister($this->_class->name)
->load($this->_identifier, $this);
unset($this->_e
m
);
unset($this->_
class
);
$this->_e
ntityPersister
->load($this->_identifier, $this);
unset($this->_e
ntityPersister
);
unset($this->_
identifier
);
$this->_loaded = true;
}
}
...
...
lib/Doctrine/ORM/EntityManager.php
View file @
197ed0b7
...
...
@@ -26,6 +26,8 @@ use Doctrine\Common\DoctrineException;
use
Doctrine\DBAL\Connection
;
use
Doctrine\ORM\Mapping\ClassMetadata
;
use
Doctrine\ORM\Mapping\ClassMetadataFactory
;
use
Doctrine\ORM\DynamicProxy\Factory
as
ProxyFactory
;
use
Doctrine\ORM\DynamicProxy\Generator
;
/**
* The EntityManager is the central access point to ORM functionality.
...
...
@@ -116,11 +118,11 @@ class EntityManager
private
$_hydrators
=
array
();
/**
* The proxy
generator
.
* The proxy
factory which creates association or reference proxies
.
*
* @var
DynamicProxyGenerator
* @var
ProxyFactory
*/
private
$_proxy
Generator
;
private
$_proxy
Factory
;
/**
* Whether the EntityManager is closed or not.
...
...
@@ -144,7 +146,8 @@ class EntityManager
$this
->
_metadataFactory
=
new
ClassMetadataFactory
(
$this
);
$this
->
_metadataFactory
->
setCacheDriver
(
$this
->
_config
->
getMetadataCacheImpl
());
$this
->
_unitOfWork
=
new
UnitOfWork
(
$this
);
$this
->
_proxyGenerator
=
new
DynamicProxyGenerator
(
$this
,
$this
->
_config
->
getCacheDir
());
//FIX: this should be in a factory
$this
->
_proxyFactory
=
new
ProxyFactory
(
$this
,
new
Generator
(
$this
,
$this
->
_config
->
getCacheDir
()));
}
/**
...
...
@@ -559,13 +562,13 @@ class EntityManager
}
/**
* Gets the proxy
generator
used by the EntityManager to create entity proxies.
* Gets the proxy
factory
used by the EntityManager to create entity proxies.
*
* @return
DynamicProxyGenerator
* @return
ProxyFactory
*/
public
function
getProxyGenerator
()
{
return
$this
->
_proxy
Generator
;
return
$this
->
_proxy
Factory
;
}
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment