Skip to content

Commit

Permalink
Changed implementation strategy to use a new mapping property -- doct…
Browse files Browse the repository at this point in the history
  • Loading branch information
sarcher committed Nov 1, 2015
1 parent 8b31a12 commit 88bae47
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 25 deletions.
5 changes: 5 additions & 0 deletions lib/Doctrine/ODM/PHPCR/Mapping/Annotations/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,9 @@ class Document
* @var boolean
*/
public $referenceable;

/**
* @var boolean
*/
public $uniqueNodeType;
}
29 changes: 29 additions & 0 deletions lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,13 @@ class ClassMetadata implements ClassMetadataInterface
*/
public $referenceable = false;

/**
* READ-ONLY: If true, consider this document's node type to be unique among all mappings.
*
* @var bool
*/
public $uniqueNodeType = false;

/**
* READ-ONLY: Strategy key to find field translations.
* This is the key used for DocumentManagerInterface::getTranslationStrategy
Expand Down Expand Up @@ -611,6 +618,24 @@ public function setReferenceable($referenceable)
$this->referenceable = $referenceable;
}

/**
* @param bool $uniqueNodeType
*/
public function setUniqueNodeType($uniqueNodeType)
{
$this->uniqueNodeType = $uniqueNodeType;
}

/**
* Return true if this document has a unique node type among all mappings.
*
* @return bool
*/
public function hasUniqueNodeType()
{
return $this->uniqueNodeType;
}

/**
* @param string $nodeType
*/
Expand Down Expand Up @@ -1481,6 +1506,10 @@ public function __sleep()
$serialized[] = 'referenceable';
}

if ($this->uniqueNodeType) {
$serialized[] = 'uniqueNodeType';
}

if ($this->lifecycleCallbacks) {
$serialized[] = 'lifecycleCallbacks';
}
Expand Down
4 changes: 4 additions & 0 deletions lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ public function loadMetadataForClass($className, ClassMetadata $metadata)
$metadata->setVersioned($documentAnnot->versionable);
}

if (null !== $documentAnnot->uniqueNodeType) {
$metadata->setUniqueNodeType($documentAnnot->uniqueNodeType);
}

if (null !== $documentAnnot->mixins) {
$metadata->setMixins($documentAnnot->mixins);
}
Expand Down
4 changes: 4 additions & 0 deletions lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ public function loadMetadataForClass($className, ClassMetadata $class)
$class->setReferenceable((bool) $xmlRoot['referenceable']);
}

if (isset($xmlRoot['uniqueNodeType']) && $xmlRoot['uniqueNodeType'] !== 'false') {
$class->setUniqueNodeType((bool) $xmlRoot['uniqueNodeType']);
}

if (isset($xmlRoot->mixins)) {
$mixins = array();
foreach ($xmlRoot->mixins->mixin as $mixin) {
Expand Down
4 changes: 4 additions & 0 deletions lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ public function loadMetadataForClass($className, ClassMetadata $class)
$class->setReferenceable($element['referenceable']);
}

if (isset($element['uniqueNodeType']) && $element['uniqueNodeType']) {
$class->setUniqueNodeType($element['uniqueNodeType']);
}

if (isset($element['mixins'])) {
$mixins = array();
foreach ($element['mixins'] as $mixin) {
Expand Down
14 changes: 7 additions & 7 deletions lib/Doctrine/ODM/PHPCR/Query/Builder/ConverterPhpcr.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,6 @@ protected function walkSourceDocument(SourceDocument $node)
$alias = $node->getAlias();
$documentFqn = $node->getDocumentFqn();

// make sure we add the phpcr:{class,classparents} constraints
// From is dispatched first, so these will always be the primary
// constraints.
if (!$node->getStronglyTyped()) {
$this->sourceDocumentNodes[$alias] = $node;
}

// cache the metadata for this document
/** @var $meta ClassMetadata */
$meta = $this->mdf->getMetadataFor($documentFqn);
Expand All @@ -292,6 +285,13 @@ protected function walkSourceDocument(SourceDocument $node)
}
$nodeType = $meta->getNodeType();

// make sure we add the phpcr:{class,classparents} constraints
// unless the document has a unique type; From is dispatched first,
// so these will always be the primary constraints.
if (!$meta->hasUniqueNodeType()) {
$this->sourceDocumentNodes[$alias] = $node;
}

// get the PHPCR Alias
$alias = $this->qomf->selector(
$alias,
Expand Down
9 changes: 1 addition & 8 deletions lib/Doctrine/ODM/PHPCR/Query/Builder/SourceDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ class SourceDocument extends AbstractLeafNode
{
protected $documentFqn;
protected $alias;
protected $stronglyTyped;

public function __construct(AbstractNode $parent, $documentFqn, $alias, $stronglyTyped = false)
public function __construct(AbstractNode $parent, $documentFqn, $alias)
{
if (!is_string($alias) || empty($alias)) {
throw new InvalidArgumentException(sprintf(
Expand All @@ -21,7 +20,6 @@ public function __construct(AbstractNode $parent, $documentFqn, $alias, $strongl

$this->documentFqn = $documentFqn;
$this->alias = $alias;
$this->stronglyTyped = $stronglyTyped;
parent::__construct($parent);
}

Expand All @@ -35,11 +33,6 @@ public function getAlias()
return $this->alias;
}

public function getStronglyTyped()
{
return $this->stronglyTyped;
}

public function getNodeType()
{
return self::NT_SOURCE;
Expand Down
4 changes: 2 additions & 2 deletions lib/Doctrine/ODM/PHPCR/Query/Builder/SourceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ public function getCardinalityMap()
* @factoryMethod SourceDocument
* @return SourceDocument
*/
public function document($documentFqn, $alias, $stronglyTyped = false)
public function document($documentFqn, $alias)
{
return $this->addChild(new SourceDocument($this, $documentFqn, $alias, $stronglyTyped));
return $this->addChild(new SourceDocument($this, $documentFqn, $alias));
}

/**
Expand Down
3 changes: 2 additions & 1 deletion tests/Doctrine/Tests/Models/CMS/CmsProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
* @PHPCRODM\Document(
* nodeType="phpcr:cms_profile",
* referenceable=true,
* repositoryClass="Doctrine\Tests\Models\CMS\CmsProfileRepository"
* repositoryClass="Doctrine\Tests\Models\CMS\CmsProfileRepository",
* uniqueNodeType=true
* )
*/
class CmsProfile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,21 +209,22 @@ public function testEquiJoinInner($joinType, $leftClass, $rightClass, $criteria
}

/**
* Verify that using an outer join on a document that is strongly typed
* Verify that using an outer join on a document that is uniquely typed
* results in the full expected result set.
*/
public function testStronglyTypedOuterJoin()
public function testUniqueNodeTypeOuterJoin()
{
$qb = $this->dm->createQueryBuilder();
$qb = $this->dm->createQueryBuilder()
->fromDocument('Doctrine\Tests\Models\CMS\CmsUser', 'u')
->addJoinLeftOuter()
->right()->document('Doctrine\Tests\Models\CMS\CmsProfile', 'p', true)->end()
->right()->document('Doctrine\Tests\Models\CMS\CmsProfile', 'p')->end()
->condition()->equi('u.profiles', 'p.uuid')
->end()->end()
->where()->orX()
->eq()->field('u.username')->literal('winstonsmith')->end()
->eq()->field('p.data')->literal('testdata')->end()
->end()->end()
->orderBy()->asc()->field('u.username');
->orderBy()->asc()->field('u.username')->end()->end();

$q = $qb->getQuery();
$phpcrQuery = $q->getPhpcrQuery();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,22 @@ public function testReferenceableMapping($class)
$this->assertTrue($class->referenceable);
}

public function testLoadUniqueNodeTypeMapping()
{
$className = 'Doctrine\Tests\ODM\PHPCR\Mapping\Model\UniqueNodeTypeMappingObject';

return $this->loadMetadataForClassname($className);
}

/**
* @depends testLoadUniqueNodeTypeMapping
* @param ClassMetadata $class
*/
public function testUniqueNodeTypeMapping($class)
{
$this->assertTrue($class->uniqueNodeType);
}

public function testLoadNodeTypeMapping()
{
$className = 'Doctrine\Tests\ODM\PHPCR\Mapping\Model\NodeTypeMappingObject';
Expand Down
6 changes: 4 additions & 2 deletions tests/Doctrine/Tests/ODM/PHPCR/Mapping/ClassMetadataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,24 +224,26 @@ public function testNewInstance(ClassMetadata $cm)
*/
public function testSerialize(ClassMetadata $cm)
{
$expected = 'O:40:"Doctrine\ODM\PHPCR\Mapping\ClassMetadata":19:{s:8:"nodeType";s:15:"nt:unstructured";s:10:"identifier";s:2:"id";s:4:"name";s:39:"Doctrine\Tests\ODM\PHPCR\Mapping\Person";s:11:"idGenerator";i:2;s:8:"mappings";a:5:{s:2:"id";a:7:{s:9:"fieldName";s:2:"id";s:2:"id";b:1;s:8:"strategy";s:8:"assigned";s:4:"type";s:6:"string";s:10:"multivalue";b:0;s:8:"nullable";b:0;s:8:"property";s:2:"id";}s:8:"username";a:5:{s:9:"fieldName";s:8:"username";s:8:"property";s:8:"username";s:4:"type";s:6:"string";s:10:"multivalue";b:0;s:8:"nullable";b:0;}s:7:"created";a:5:{s:9:"fieldName";s:7:"created";s:8:"property";s:7:"created";s:4:"type";s:8:"datetime";s:10:"multivalue";b:0;s:8:"nullable";b:0;}s:6:"locale";a:3:{s:9:"fieldName";s:6:"locale";s:4:"type";s:6:"locale";s:8:"property";s:6:"locale";}s:15:"translatedField";a:7:{s:9:"fieldName";s:15:"translatedField";s:10:"translated";b:1;s:8:"property";s:15:"translatedField";s:4:"type";s:6:"string";s:10:"multivalue";b:0;s:5:"assoc";N;s:8:"nullable";b:0;}}s:13:"fieldMappings";a:4:{i:0;s:2:"id";i:1;s:8:"username";i:2;s:7:"created";i:3;s:15:"translatedField";}s:17:"referenceMappings";a:0:{}s:17:"referrersMappings";a:0:{}s:22:"mixedReferrersMappings";a:0:{}s:16:"childrenMappings";a:0:{}s:13:"childMappings";a:0:{}s:25:"customRepositoryClassName";s:51:"Doctrine\Tests\ODM\PHPCR\Mapping\DocumentRepository";s:18:"isMappedSuperclass";b:1;s:11:"versionable";b:1;s:18:"lifecycleCallbacks";a:1:{s:8:"postLoad";a:1:{i:0;s:8:"callback";}}s:13:"inheritMixins";b:1;s:13:"localeMapping";s:6:"locale";s:10:"translator";s:9:"attribute";s:18:"translatableFields";a:1:{i:0;s:15:"translatedField";}}';
$expected = 'O:40:"Doctrine\ODM\PHPCR\Mapping\ClassMetadata":20:{s:8:"nodeType";s:15:"nt:unstructured";s:10:"identifier";s:2:"id";s:4:"name";s:39:"Doctrine\Tests\ODM\PHPCR\Mapping\Person";s:11:"idGenerator";i:2;s:8:"mappings";a:5:{s:2:"id";a:7:{s:9:"fieldName";s:2:"id";s:2:"id";b:1;s:8:"strategy";s:8:"assigned";s:4:"type";s:6:"string";s:10:"multivalue";b:0;s:8:"nullable";b:0;s:8:"property";s:2:"id";}s:8:"username";a:5:{s:9:"fieldName";s:8:"username";s:8:"property";s:8:"username";s:4:"type";s:6:"string";s:10:"multivalue";b:0;s:8:"nullable";b:0;}s:7:"created";a:5:{s:9:"fieldName";s:7:"created";s:8:"property";s:7:"created";s:4:"type";s:8:"datetime";s:10:"multivalue";b:0;s:8:"nullable";b:0;}s:6:"locale";a:3:{s:9:"fieldName";s:6:"locale";s:4:"type";s:6:"locale";s:8:"property";s:6:"locale";}s:15:"translatedField";a:7:{s:9:"fieldName";s:15:"translatedField";s:10:"translated";b:1;s:8:"property";s:15:"translatedField";s:4:"type";s:6:"string";s:10:"multivalue";b:0;s:5:"assoc";N;s:8:"nullable";b:0;}}s:13:"fieldMappings";a:4:{i:0;s:2:"id";i:1;s:8:"username";i:2;s:7:"created";i:3;s:15:"translatedField";}s:17:"referenceMappings";a:0:{}s:17:"referrersMappings";a:0:{}s:22:"mixedReferrersMappings";a:0:{}s:16:"childrenMappings";a:0:{}s:13:"childMappings";a:0:{}s:25:"customRepositoryClassName";s:51:"Doctrine\Tests\ODM\PHPCR\Mapping\DocumentRepository";s:18:"isMappedSuperclass";b:1;s:11:"versionable";b:1;s:14:"uniqueNodeType";b:1;s:18:"lifecycleCallbacks";a:1:{s:8:"postLoad";a:1:{i:0;s:8:"callback";}}s:13:"inheritMixins";b:1;s:13:"localeMapping";s:6:"locale";s:10:"translator";s:9:"attribute";s:18:"translatableFields";a:1:{i:0;s:15:"translatedField";}}';

$cm->setCustomRepositoryClassName('DocumentRepository');
$cm->setVersioned(true);
$cm->setUniqueNodeType(true);
$cm->addLifecycleCallback('callback', 'postLoad');
$cm->isMappedSuperclass = true;
$this->assertEquals($expected, serialize($cm));
}

public function testUnserialize()
{
$cm = unserialize('O:40:"Doctrine\ODM\PHPCR\Mapping\ClassMetadata":15:{s:8:"nodeType";s:15:"nt:unstructured";s:10:"identifier";s:2:"id";s:4:"name";s:39:"Doctrine\Tests\ODM\PHPCR\Mapping\Person";s:11:"idGenerator";i:1;s:8:"mappings";a:5:{s:2:"id";a:7:{s:9:"fieldName";s:2:"id";s:2:"id";b:1;s:8:"strategy";s:10:"repository";s:4:"type";s:6:"string";s:10:"multivalue";b:0;s:8:"nullable";b:0;s:8:"property";s:2:"id";}s:8:"username";a:5:{s:9:"fieldName";s:8:"username";s:8:"property";s:8:"username";s:4:"type";s:6:"string";s:10:"multivalue";b:0;s:8:"nullable";b:0;}s:7:"created";a:5:{s:9:"fieldName";s:7:"created";s:8:"property";s:7:"created";s:4:"type";s:8:"datetime";s:10:"multivalue";b:0;s:8:"nullable";b:0;}s:6:"locale";a:3:{s:9:"fieldName";s:6:"locale";s:4:"type";s:6:"locale";s:8:"property";s:6:"locale";}s:15:"translatedField";a:7:{s:9:"fieldName";s:15:"translatedField";s:4:"type";s:6:"string";s:10:"translated";b:1;s:8:"property";s:15:"translatedField";s:10:"multivalue";b:0;s:5:"assoc";N;s:8:"nullable";b:0;}}s:13:"fieldMappings";a:4:{i:0;s:2:"id";i:1;s:8:"username";i:2;s:7:"created";i:3;s:15:"translatedField";}s:17:"referenceMappings";a:0:{}s:17:"referrersMappings";a:0:{}s:22:"mixedReferrersMappings";a:0:{}s:16:"childrenMappings";a:0:{}s:13:"childMappings";a:0:{}s:25:"customRepositoryClassName";s:51:"Doctrine\Tests\ODM\PHPCR\Mapping\DocumentRepository";s:18:"isMappedSuperclass";b:1;s:11:"versionable";b:1;s:18:"lifecycleCallbacks";a:1:{s:8:"postLoad";a:1:{i:0;s:8:"callback";}}}');
$cm = unserialize('O:40:"Doctrine\ODM\PHPCR\Mapping\ClassMetadata":16:{s:8:"nodeType";s:15:"nt:unstructured";s:10:"identifier";s:2:"id";s:4:"name";s:39:"Doctrine\Tests\ODM\PHPCR\Mapping\Person";s:11:"idGenerator";i:1;s:8:"mappings";a:5:{s:2:"id";a:7:{s:9:"fieldName";s:2:"id";s:2:"id";b:1;s:8:"strategy";s:10:"repository";s:4:"type";s:6:"string";s:10:"multivalue";b:0;s:8:"nullable";b:0;s:8:"property";s:2:"id";}s:8:"username";a:5:{s:9:"fieldName";s:8:"username";s:8:"property";s:8:"username";s:4:"type";s:6:"string";s:10:"multivalue";b:0;s:8:"nullable";b:0;}s:7:"created";a:5:{s:9:"fieldName";s:7:"created";s:8:"property";s:7:"created";s:4:"type";s:8:"datetime";s:10:"multivalue";b:0;s:8:"nullable";b:0;}s:6:"locale";a:3:{s:9:"fieldName";s:6:"locale";s:4:"type";s:6:"locale";s:8:"property";s:6:"locale";}s:15:"translatedField";a:7:{s:9:"fieldName";s:15:"translatedField";s:4:"type";s:6:"string";s:10:"translated";b:1;s:8:"property";s:15:"translatedField";s:10:"multivalue";b:0;s:5:"assoc";N;s:8:"nullable";b:0;}}s:13:"fieldMappings";a:4:{i:0;s:2:"id";i:1;s:8:"username";i:2;s:7:"created";i:3;s:15:"translatedField";}s:17:"referenceMappings";a:0:{}s:17:"referrersMappings";a:0:{}s:22:"mixedReferrersMappings";a:0:{}s:16:"childrenMappings";a:0:{}s:13:"childMappings";a:0:{}s:25:"customRepositoryClassName";s:51:"Doctrine\Tests\ODM\PHPCR\Mapping\DocumentRepository";s:18:"isMappedSuperclass";b:1;s:11:"versionable";b:1;s:14:"uniqueNodeType";b:1;s:18:"lifecycleCallbacks";a:1:{s:8:"postLoad";a:1:{i:0;s:8:"callback";}}}');

$this->assertInstanceOf('Doctrine\ODM\PHPCR\Mapping\ClassMetadata', $cm);

$this->assertEquals(array('callback'), $cm->getLifecycleCallbacks('postLoad'));
$this->assertTrue($cm->isMappedSuperclass);
$this->assertTrue($cm->versionable);
$this->assertTrue($cm->uniqueNodeType);
$this->assertTrue($cm->inheritMixins);
$this->assertEquals('Doctrine\Tests\ODM\PHPCR\Mapping\DocumentRepository', $cm->customRepositoryClassName);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Doctrine\Tests\ODM\PHPCR\Mapping\Model;

use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCRODM;

/**
* A class that has a unique node type among other mapped documents.
*
* @PHPCRODM\Document(uniqueNodeType=true)
*/
class UniqueNodeTypeMappingObject
{
/** @PHPCRODM\Id */
public $id;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping
https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd">
<document name="Doctrine\Tests\ODM\PHPCR\Mapping\Model\UniqueNodeTypeMappingObject" uniqueNodeType="true">
<id name="id" />
</document>
</doctrine-mapping>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Doctrine\Tests\ODM\PHPCR\Mapping\Model\UniqueNodeTypeMappingObject:
uniqueNodeType: true
id: id

0 comments on commit 88bae47

Please sign in to comment.