Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHPCR-37 - Sync doctrine common metadata changes in master #85

Merged
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 25 additions & 3 deletions lib/Doctrine/ODM/PHPCR/Configuration.php
Expand Up @@ -19,6 +19,7 @@

namespace Doctrine\ODM\PHPCR;

use Doctrine\Common\Cache\Cache;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can probably be removed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use it for setMetadataCacheImpl(Cache $metadataCacheImpl) :)

use Doctrine\ODM\PHPCR\Mapping\Driver\Driver;
use Doctrine\ODM\PHPCR\Mapping\Driver\BuiltinDocumentsDriver;
use Doctrine\ODM\PHPCR\DocumentClassMapperInterface;
Expand All @@ -44,9 +45,10 @@ class Configuration
'writeDoctrineMetadata' => true,
'validateDoctrineMetadata' => true,
'metadataDriverImpl' => null,
'metadataCacheImpl' => null,
'documentClassMapper' => null,
'proxyNamespace' => 'MyPHPCRProxyNS',
'autoGenerateProxyClasses' => true
'autoGenerateProxyClasses' => true,
);

/**
Expand Down Expand Up @@ -128,7 +130,7 @@ public function setDocumentNamespaces(array $documentNamespaces)
}

/**
* Sets the cache driver implementation that is used for metadata caching.
* Sets the driver implementation that is used to retrieve mapping metadata.
*
* @param Driver $driverImpl
* @todo Force parameter to be a Closure to ensure lazy evaluation
Expand All @@ -140,7 +142,7 @@ public function setMetadataDriverImpl(Driver $driverImpl)
}

/**
* Gets the cache driver implementation that is used for the mapping metadata.
* Gets the driver implementation that is used to retrieve mapping metadata.
*
* @return Mapping\Driver\Driver
*/
Expand All @@ -149,6 +151,26 @@ public function getMetadataDriverImpl()
return $this->attributes['metadataDriverImpl'];
}

/**
* Sets the cache driver implementation that is used for metadata caching.
*
* @param Cache $metadataCacheImpl
*/
public function setMetadataCacheImpl(Cache $metadataCacheImpl)
{
$this->attributes['metadataCacheImpl'] = $metadataCacheImpl;
}

/**
* Gets the cache driver implementation that is used for the mapping metadata.
*
* @return Cache|null
*/
public function getMetadataCacheImpl()
{
return $this->attributes['metadataCacheImpl'];
}

/**
* Gets the cache driver implementation that is used for metadata caching.
*
Expand Down
240 changes: 53 additions & 187 deletions lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadataFactory.php
Expand Up @@ -19,10 +19,10 @@

namespace Doctrine\ODM\PHPCR\Mapping;

use Doctrine\ODM\PHPCR\DocumentManager,
Doctrine\ODM\PHPCR\Mapping\ClassMetadata,
Doctrine\ODM\PHPCR\PHPCRException,
Doctrine\Common\Cache\Cache;
use Doctrine\ODM\PHPCR\DocumentManager;
use Doctrine\ODM\PHPCR\Mapping\ClassMetadata;
use Doctrine\ODM\PHPCR\PHPCRException;
use Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory;

/**
* The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
Expand All @@ -35,244 +35,110 @@
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
*/
class ClassMetadataFactory
class ClassMetadataFactory extends AbstractClassMetadataFactory
{
/**
* @var DocumentManager
*/
private $dm;

/**
* @var array
* {@inheritdoc}
*/
private $loadedMetadata = array();

protected $cacheSalt = '\$PHPCRODMCLASSMETADATA';
/**
* @var array
* @var DocumentManager
*/
private $loadedAliases = array();
private $dm;

/**
* The used metadata driver.
*
* @var Doctrine\ODM\PHPCR\Mapping\Driver\Driver
* @var \Doctrine\ODM\PHPCR\Mapping\Driver\Driver
*/
private $driver;

/**
* The used cache driver.
*
* @var Cache
*/
private $cacheDriver;

/**
* Creates a new factory instance that uses the given DocumentManager instance.
*
* @param $dm The DocumentManager instance
* @param $dm The DocumentManager instance
*/
public function __construct(DocumentManager $dm)
{
$this->dm = $dm;
$this->driver = $this->dm->getConfiguration()->getMetadataDriverImpl();
}

/**
* Sets the cache driver used by the factory to cache ClassMetadata instances.
*
* @param Doctrine\Common\Cache\Cache $cacheDriver
*/
public function setCacheDriver($cacheDriver)
{
$this->cacheDriver = $cacheDriver;
$conf = $this->dm->getConfiguration();
$this->setCacheDriver($conf->getMetadataCacheImpl());
$this->driver = $conf->getMetadataDriverImpl();
}

/**
* Gets the cache driver used by the factory to cache ClassMetadata instances.
*
* @return Doctrine\Common\Cache\Cache
* {@inheritdoc}
*
* @throws MappingException
*/
public function getCacheDriver()
{
return $this->cacheDriver;
}

/**
* Gets the array of loaded ClassMetadata instances.
*
* @return array $loadedMetadata The loaded metadata.
*/
public function getLoadedMetadata()
{
return $this->loadedMetadata;
}

/**
* Forces the factory to load the metadata of all classes known to the underlying
* mapping driver.
*
* @return array The ClassMetadata instances of all mapped classes.
*/
public function getAllMetadata()
{
$metadata = array();
foreach ($this->driver->getAllClassNames() as $className) {
$metadata[] = $this->getMetadataFor($className);
}

return $metadata;
}

public function getMetadataForAlias($alias)
public function getMetadataFor($className)
{
if (isset($this->loadedAliases[$alias])) {
return $this->loadedAliases[$alias];
if ($metadata = parent::getMetadataFor($className)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think its better to do the assignment outside of the if statement.

return $metadata;
}

if ($this->cacheDriver && ($cached = $this->cacheDriver->fetch("$alias\$PHPCRODMALIAS")) !== false) {
return $this->loadedAliases[$alias] = $cached;
}

foreach ($this->loadedMetadata as $metadata) {
if ($metadata->alias === $alias) {
$this->loadedAliases[$alias] = $metadata;
if ($this->cacheDriver) {
$this->cacheDriver->save(
"$alias\$PHPCRODMALIAS", $this->loadedAliases[$alias], null
);
}
return $metadata;
}
}

foreach ($this->driver->getAllClassNames() as $className) {
$metadata = $this->getMetadataFor($className);
if ($metadata->alias === $alias) {
$this->loadedAliases[$alias] = $metadata;
if ($this->cacheDriver) {
$this->cacheDriver->save(
"$alias\$PHPCRODMALIAS", $this->loadedAliases[$alias], null
);
}
return $metadata;
}
}

throw new MappingException('Alias '.$alias.' could not be resolved to a document class name');
throw MappingException::classNotMapped($className);
}

/**
* Gets the class metadata descriptor for a class.
*
* @param string $className The name of the class.
* @return Doctrine\ODM\PHPCR\Mapping\ClassMetadata
* {@inheritdoc}
*
* @throws MappingException
*/
public function getMetadataFor($className)
function loadMetadata($className)
{
if (!isset($this->loadedMetadata[$className])) {
$realClassName = $className;

// Check for namespace alias
if (strpos($className, ':') !== false) {
list($namespaceAlias, $simpleClassName) = explode(':', $className);
$realClassName = $this->dm->getConfiguration()->getDocumentNamespace($namespaceAlias) . '\\' . $simpleClassName;

if (isset($this->loadedMetadata[$realClassName])) {
// We do not have the alias name in the map, include it
$this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];

return $this->loadedMetadata[$realClassName];
}
}

if ($this->cacheDriver) {
if (($cached = $this->cacheDriver->fetch("$realClassName\$PHPCRODMCLASSMETADATA")) !== false) {
$this->loadedMetadata[$realClassName] = $cached;
} else {
foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
$this->cacheDriver->save(
"$loadedClassName\$PHPCRODMCLASSMETADATA", $this->loadedMetadata[$loadedClassName], null
);
}
}
} else {
$this->loadMetadata($realClassName);
}

if ($className != $realClassName) {
// We do not have the alias name in the map, include it
$this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
}
}

if (!isset($this->loadedMetadata[$className])) {
throw MappingException::classNotMapped();
if (class_exists($className)) {
return parent::loadMetadata($className);
}

return $this->loadedMetadata[$className];
throw MappingException::classNotFound($className);
}


/**
* Loads the metadata of the class in question and all it's ancestors whose metadata
* is still not loaded.
*
* @param string $className The name of the class for which the metadata should get loaded.
* {@inheritdoc}
*/
private function loadMetadata($className)
protected function newClassMetadataInstance($className)
{
if (!class_exists($className)) {
throw MappingException::classNotFound($className);
}

$this->loadedMetadata[$className] = new ClassMetadata($className);
$this->driver->loadMetadataForClass($className, $this->loadedMetadata[$className]);
return new ClassMetadata($className);
}

/**
* Checks whether the factory has the metadata for a class loaded already.
*
* @param string $className
* @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise.
* {@inheritdoc}
*/
public function hasMetadataFor($className)
protected function getFqcnFromAlias($namespaceAlias, $simpleClassName)
{
return isset($this->loadedMetadata[$className]);
return $this->dm->getConfiguration()->getDocumentNamespace($namespaceAlias)
. '\\' . $simpleClassName;
}

/**
* 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
* {@inheritdoc}
*
* @todo unclear usage of rootEntityFound
*/
public function setMetadataFor($className, $class)
protected function doLoadMetadata($class, $parent, $rootEntityFound)
{
$this->loadedMetadata[$className] = $class;
if ($parent) {
$this->getDriver()->loadMetadataForClass($parent->name, $parent);
}
$this->getDriver()->loadMetadataForClass($class->name, $class);
}

/**
* Creates a new ClassMetadata instance for the given class name.
*
* @param string $className
* @return Doctrine\ODM\PHPCR\Mapping\ClassMetadata
* {@inheritdoc}
*/
protected function newClassMetadataInstance($className)
protected function getDriver()
{
return new ClassMetadata($className);
return $this->driver;
}

/**
* 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 boolean
* {@inheritdoc}
*/
public function isTransient($className)
protected function initialize()
{
return $this->driver->isTransient($className);
$this->initialized = true;
}

}