С версии: 1.0
Автор: Benjamin Eberlei (kontakt@beberlei.de)
Автор: Lukas Kahwe Smith (smith@pooteeweet.org)
Наследование: extends Doctrine\ODM\CouchDB\Mapping\ClassMetadataInfo, implements Doctrine\Common\Persistence\Mapping\ClassMetadata
Пример #1
0
 public function getClassMetadata($class)
 {
     $metadata = new \Doctrine\ODM\CouchDB\Mapping\ClassMetadata($class);
     $metadata->initializeReflection(new RuntimeReflectionService());
     $metadata->wakeupReflection(new RuntimeReflectionService());
     return $metadata;
 }
Пример #2
0
 /**
  * @param object $document
  * @param ClassMetadata $cm
  * @param DocumentManager $dm
  * @return array
  */
 public function generate($document, ClassMetadata $cm, DocumentManager $dm)
 {
     $id = $cm->getIdentifierValue($document);
     if (!$id) {
         throw new \Exception("no id");
     }
     return $id;
 }
Пример #3
0
 /**
  * @param object $document
  * @param ClassMetadata $cm
  * @param DocumentManager $dm
  * @return array
  */
 public function generate($document, ClassMetadata $cm, DocumentManager $dm)
 {
     $id = $cm->getIdentifierValue($document);
     if (!$id) {
         throw CouchDBException::assignedIdGeneratorNoIdFound($cm->name);
     }
     return $id;
 }
Пример #4
0
 public function setUp()
 {
     $this->type = 'Doctrine\\Tests\\ODM\\CouchDB\\UoWUser';
     $this->dm = \Doctrine\ODM\CouchDB\DocumentManager::create(array('dbname' => 'test'));
     $this->uow = new UnitOfWork($this->dm);
     $metadata = new \Doctrine\ODM\CouchDB\Mapping\ClassMetadata($this->type);
     $metadata->mapField(array('fieldName' => 'id', 'id' => true));
     $metadata->mapField(array('fieldName' => 'username', 'type' => 'string'));
     $metadata->idGenerator = \Doctrine\ODM\CouchDB\Mapping\ClassMetadata::IDGENERATOR_ASSIGNED;
     $cmf = $this->dm->getClassMetadataFactory();
     $cmf->setMetadataFor($this->type, $metadata);
 }
Пример #5
0
 public function setUp()
 {
     if (!class_exists('Doctrine\\ODM\\CouchDB\\Version')) {
         $this->markTestSkipped('Doctrine CouchDB has to be installed for this test to run.');
     }
     $c = $this->getMock('FOS\\UserBundle\\Util\\CanonicalizerInterface');
     $ef = $this->getMock('Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface');
     $class = new ClassMetadata(self::USERTYPE);
     $class->mapField(array('fieldName' => 'username'));
     $this->dm = $this->getMock('Doctrine\\ODM\\CouchDB\\DocumentManager', array('getRepository', 'persist', 'remove', 'flush', 'getClassMetadata'), array(), '', false);
     $this->repository = $this->getMock('Doctrine\\ODM\\CouchDB\\DocumentRepository', array('findBy', 'findAll'), array(), '', false);
     $this->dm->expects($this->any())->method('getRepository')->with($this->equalTo(self::USERTYPE))->will($this->returnValue($this->repository));
     $this->dm->expects($this->any())->method('getClassMetadata')->with($this->equalTo(self::USERTYPE))->will($this->returnValue($class));
     $this->userManager = new UserManager($ef, $c, $c, $this->dm, self::USERTYPE);
 }
Пример #6
0
 /**
  * {@inheritdoc}
  */
 public function loadMetadataForClass($className, ClassMetadata $class)
 {
     /* @var $xmlRoot SimpleXMLElement */
     $xmlRoot = $this->getElement($className);
     if ($xmlRoot->getName() == "document") {
         $class->setCustomRepositoryClass(isset($xmlRoot['repository-class']) ? (string) $xmlRoot['repository-class'] : null);
         if (isset($xmlRoot['indexed']) && $xmlRoot['indexed'] == true) {
             $class->indexed = true;
         }
     } else {
         if ($xmlRoot->getName() == "embedded-document") {
             $class->isEmbeddedDocument = true;
         } else {
             if ($xmlRoot->getName() == "mapped-superclass") {
                 $class->isMappedSuperclass = true;
             } else {
                 throw MappingException::classIsNotAValidDocument($className);
             }
         }
     }
     // Evaluate <field ...> mappings
     if (isset($xmlRoot->field)) {
         foreach ($xmlRoot->field as $fieldMapping) {
             $class->mapField(array('fieldName' => (string) $fieldMapping['name'], 'jsonName' => isset($fieldMapping['json-name']) ? (string) $fieldMapping['json-name'] : null, 'indexed' => isset($fieldMapping['index']) ? (bool) $fieldMapping['index'] : false, 'type' => isset($fieldMapping['type']) ? (string) $fieldMapping['type'] : null, 'isVersionField' => isset($fieldMapping['version']) ? true : null));
         }
     }
     // Evaluate <id ..> mappings
     foreach ($xmlRoot->id as $idElement) {
         $class->mapField(array('fieldName' => (string) $idElement['name'], 'indexed' => isset($idElement['index']) ? (bool) $idElement['index'] : false, 'type' => isset($idElement['type']) ? (string) $idElement['type'] : null, 'id' => true, 'strategy' => isset($idElement['strategy']) ? (string) $idElement['strategy'] : null));
     }
     // Evaluate <many-to-one ..> mappings
     if (isset($xmlRoot->{"reference-one"})) {
         foreach ($xmlRoot->{"reference-one"} as $referenceOneElement) {
             $class->mapManyToOne(array('cascade' => isset($referenceManyElement->cascade) ? $this->getCascadeMode($referenceManyElement->cascade) : 0, 'targetDocument' => (string) $referenceOneElement['target-document'], 'fieldName' => (string) $referenceOneElement['field'], 'jsonName' => isset($referenceOneElement['json-name']) ? (string) $referenceOneElement['json-name'] : null));
         }
     }
     // Evaluate <many-to-one ..> mappings
     if (isset($xmlRoot->{"reference-many"})) {
         foreach ($xmlRoot->{"reference-many"} as $referenceManyElement) {
             $class->mapManyToMany(array('cascade' => isset($referenceManyElement->cascade) ? $this->getCascadeMode($referenceManyElement->cascade) : 0, 'targetDocument' => (string) $referenceManyElement['target-document'], 'fieldName' => (string) $referenceManyElement['field'], 'jsonName' => isset($referenceManyElement['json-name']) ? (string) $referenceManyElement['json-name'] : null, 'mappedBy' => isset($referenceManyElement['mapped-by']) ? (string) $referenceManyElement['mapped-by'] : null));
         }
     }
     // Evaluate <attachments ..> mapping
     if (isset($xmlRoot->{"attachments"})) {
         $class->mapAttachments((string) $xmlRoot->{"attachments"}[0]['field']);
     }
     // Evaluate <embed-one />
     if (isset($xmlRoot->{'embed-one'})) {
         foreach ($xmlRoot->{'embed-one'} as $embedOneElement) {
             $class->mapEmbedded(array('targetDocument' => (string) $embedOneElement['target-document'], 'fieldName' => (string) $embedOneElement['field'], 'jsonName' => isset($embedOneElement['json-name']) ? (string) $embedOneElement['json-name'] : null, 'embedded' => 'one'));
         }
     }
     // Evaluate <embed-many />
     if (isset($xmlRoot->{'embed-many'})) {
         foreach ($xmlRoot->{'embed-many'} as $embedManyElement) {
             $class->mapEmbedded(array('targetDocument' => (string) $embedManyElement['target-document'], 'fieldName' => (string) $embedManyElement['field'], 'jsonName' => isset($embedManyElement['json-name']) ? (string) $embedManyElement['json-name'] : null, 'embedded' => 'many'));
         }
     }
 }
Пример #7
0
 /**
  * {@inheritdoc}
  */
 public function loadMetadataForClass($className, ClassMetadata $class)
 {
     $element = $this->getElement($className);
     if ($element['type'] == 'document') {
         $class->setCustomRepositoryClass(isset($element['repositoryClass']) ? $element['repositoryClass'] : null);
         if (isset($element['indexed']) && $element['indexed'] == true) {
             $class->indexed = true;
         }
     } else {
         if ($element['type'] == 'embedded') {
             $class->isEmbeddedDocument = true;
         } else {
             if (strtolower($element['type']) == "mappedsuperclass") {
                 $class->isMappedSuperclass = true;
             } else {
                 throw MappingException::classIsNotAValidDocument($className);
             }
         }
     }
     if (isset($element['id'])) {
         foreach ($element['id'] as $fieldName => $idElement) {
             $class->mapField(array('fieldName' => $fieldName, 'indexed' => isset($idElement['indexed']) ? (bool) $idElement['indexed'] : false, 'type' => isset($idElement['type']) ? $idElement['type'] : null, 'id' => true, 'strategy' => isset($idElement['strategy']) ? $idElement['strategy'] : null));
         }
     }
     if (isset($element['fields'])) {
         foreach ($element['fields'] as $fieldName => $fieldElement) {
             $class->mapField(array('fieldName' => $fieldName, 'jsonName' => isset($fieldElement['jsonName']) ? $fieldElement['jsonName'] : null, 'indexed' => isset($fieldElement['indexed']) ? (bool) $fieldElement['indexed'] : false, 'type' => isset($fieldElement['type']) ? $fieldElement['type'] : null, 'isVersionField' => isset($fieldElement['version']) ? true : null));
         }
     }
     if (isset($element['referenceOne'])) {
         foreach ($element['referenceOne'] as $field => $referenceOneElement) {
             $class->mapManyToOne(array('cascade' => isset($referenceManyElement->cascade) ? $this->getCascadeMode($referenceManyElement->cascade) : 0, 'targetDocument' => (string) $referenceOneElement['targetDocument'], 'fieldName' => $field, 'jsonName' => isset($referenceOneElement['jsonName']) ? (string) $referenceOneElement['jsonName'] : null));
         }
     }
     if (isset($element['referenceMany'])) {
         foreach ($element['referenceMany'] as $field => $referenceManyElement) {
             $class->mapManyToMany(array('cascade' => isset($referenceManyElement->cascade) ? $this->getCascadeMode($referenceManyElement->cascade) : 0, 'targetDocument' => (string) $referenceManyElement['targetDocument'], 'fieldName' => $field, 'jsonName' => isset($referenceManyElement['jsonName']) ? (string) $referenceManyElement['jsonName'] : null, 'mappedBy' => isset($referenceManyElement['mappedBy']) ? (string) $referenceManyElement['mappedBy'] : null));
         }
     }
     if (isset($element['attachments'])) {
         $class->mapAttachments($element['attachments']);
     }
     if (isset($element['embedOne'])) {
         foreach ($element['embedOne'] as $field => $embedOneElement) {
             $class->mapEmbedded(array('targetDocument' => (string) $embedOneElement['targetDocument'], 'fieldName' => $field, 'jsonName' => isset($embedOneElement['jsonName']) ? (string) $embedOneElement['jsonName'] : null, 'embedded' => 'one'));
         }
     }
     if (isset($element['embedMany'])) {
         foreach ($element['embedMany'] as $field => $embedManyElement) {
             $class->mapEmbedded(array('targetDocument' => (string) $embedManyElement['targetDocument'], 'fieldName' => $field, 'jsonName' => isset($embedManyElement['jsonName']) ? (string) $embedManyElement['jsonName'] : null, 'embedded' => 'many'));
         }
     }
 }
Пример #8
0
 /**
  * {@inheritdoc}
  */
 public function loadMetadataForClass($className, ClassMetadata $class)
 {
     $reflClass = $class->getReflectionClass();
     $classAnnotations = $this->reader->getClassAnnotations($reflClass);
     if (isset($classAnnotations['Doctrine\\ODM\\CouchDB\\Mapping\\Document'])) {
         $documentAnnot = $classAnnotations['Doctrine\\ODM\\CouchDB\\Mapping\\Document'];
         if ($documentAnnot->indexed) {
             $class->indexed = true;
         }
         $class->setCustomRepositoryClass($documentAnnot->repositoryClass);
     } elseif (isset($classAnnotations['Doctrine\\ODM\\CouchDB\\Mapping\\EmbeddedDocument'])) {
         $documentAnnot = $classAnnotations['Doctrine\\ODM\\CouchDB\\Mapping\\EmbeddedDocument'];
         $class->isEmbeddedDocument = true;
     } else {
         if (isset($classAnnotations['Doctrine\\ODM\\CouchDB\\Mapping\\MappedSuperclass'])) {
             $class->isMappedSuperclass = true;
         } else {
             throw MappingException::classIsNotAValidDocument($className);
         }
     }
     foreach ($reflClass->getProperties() as $property) {
         $mapping = array();
         $mapping['fieldName'] = $property->getName();
         foreach ($this->reader->getPropertyAnnotations($property) as $fieldAnnot) {
             if ($fieldAnnot instanceof \Doctrine\ODM\CouchDB\Mapping\Field) {
                 if ($fieldAnnot instanceof \Doctrine\ODM\CouchDB\Mapping\Version) {
                     $mapping['isVersionField'] = true;
                 }
                 $mapping = array_merge($mapping, (array) $fieldAnnot);
                 unset($mapping['value']);
                 $class->mapField($mapping);
             } else {
                 if ($fieldAnnot instanceof \Doctrine\ODM\CouchDB\Mapping\ReferenceOne) {
                     $cascade = 0;
                     foreach ($fieldAnnot->cascade as $cascadeMode) {
                         $cascade += constant('Doctrine\\ODM\\CouchDB\\Mapping\\ClassMetadata::CASCADE_' . strtoupper($cascadeMode));
                     }
                     $fieldAnnot->cascade = $cascade;
                     $mapping = array_merge($mapping, (array) $fieldAnnot);
                     unset($mapping['value']);
                     $class->mapManyToOne($mapping);
                 } else {
                     if ($fieldAnnot instanceof \Doctrine\ODM\CouchDB\Mapping\ReferenceMany) {
                         $cascade = 0;
                         foreach ($fieldAnnot->cascade as $cascadeMode) {
                             $cascade += constant('Doctrine\\ODM\\CouchDB\\Mapping\\ClassMetadata::CASCADE_' . strtoupper($cascadeMode));
                         }
                         $fieldAnnot->cascade = $cascade;
                         $mapping = array_merge($mapping, (array) $fieldAnnot);
                         unset($mapping['value']);
                         $class->mapManyToMany($mapping);
                     } else {
                         if ($fieldAnnot instanceof \Doctrine\ODM\CouchDB\Mapping\Attachments) {
                             $class->mapAttachments($mapping['fieldName']);
                         } else {
                             if ($fieldAnnot instanceof \Doctrine\ODM\CouchDB\Mapping\EmbedOne || $fieldAnnot instanceof \Doctrine\ODM\CouchDB\Mapping\EmbedMany) {
                                 $mapping = array_merge($mapping, (array) $fieldAnnot);
                                 unset($mapping['value']);
                                 $class->mapEmbedded($mapping);
                             }
                         }
                     }
                 }
             }
         }
     }
 }
Пример #9
0
 /**
  * @param ClassMetadata $class
  * @param object $document
  * @return void
  */
 public function computeChangeSet(ClassMetadata $class, $document)
 {
     if ($document instanceof Proxy\Proxy && !$document->__isInitialized__) {
         return;
     }
     $oid = \spl_object_hash($document);
     $actualData = array();
     $embeddedActualData = array();
     // 1. compute the actual values of the current document
     foreach ($class->reflFields as $fieldName => $reflProperty) {
         $value = $reflProperty->getValue($document);
         if ($class->isCollectionValuedAssociation($fieldName) && $value !== null && !$value instanceof PersistentCollection) {
             if (!$value instanceof Collection) {
                 $value = new ArrayCollection($value);
             }
             if ($class->associationsMappings[$fieldName]['isOwning']) {
                 $coll = new PersistentIdsCollection($value, $class->associationsMappings[$fieldName]['targetDocument'], $this->dm, array());
             } else {
                 $coll = new PersistentViewCollection($value, $this->dm, $this->documentIdentifiers[$oid], $class->associationsMappings[$fieldName]);
             }
             $class->reflFields[$fieldName]->setValue($document, $coll);
             $actualData[$fieldName] = $coll;
         } else {
             $actualData[$fieldName] = $value;
             if (isset($class->fieldMappings[$fieldName]['embedded']) && $value !== null) {
                 // serializing embedded value right here, to be able to detect changes for later invocations
                 $embeddedActualData[$fieldName] = $this->embeddedSerializer->serializeEmbeddedDocument($value, $class->fieldMappings[$fieldName]);
             }
         }
         // TODO: ORM transforms arrays and collections into persistent collections
     }
     // unset the revision field if necessary, it is not to be managed by the user in write scenarios.
     if ($class->isVersioned) {
         unset($actualData[$class->versionField]);
     }
     // 2. Compare to the original, or find out that this document is new.
     if (!isset($this->originalData[$oid])) {
         // document is New and should be inserted
         $this->originalData[$oid] = $actualData;
         $this->scheduledUpdates[$oid] = $document;
         $this->originalEmbeddedData[$oid] = $embeddedActualData;
     } else {
         // document is "fully" MANAGED: it was already fully persisted before
         // and we have a copy of the original data
         $changed = false;
         foreach ($actualData as $fieldName => $fieldValue) {
             // Important to not check embeded values here, because those are objects, equality check isn't enough
             //
             if (isset($class->fieldMappings[$fieldName]) && !isset($class->fieldMappings[$fieldName]['embedded']) && $this->originalData[$oid][$fieldName] !== $fieldValue) {
                 $changed = true;
                 break;
             } else {
                 if (isset($class->associationsMappings[$fieldName])) {
                     if (!$class->associationsMappings[$fieldName]['isOwning']) {
                         continue;
                     }
                     if ($class->associationsMappings[$fieldName]['type'] & ClassMetadata::TO_ONE && $this->originalData[$oid][$fieldName] !== $fieldValue) {
                         $changed = true;
                         break;
                     } else {
                         if ($class->associationsMappings[$fieldName]['type'] & ClassMetadata::TO_MANY) {
                             if (!$fieldValue instanceof PersistentCollection) {
                                 // if its not a persistent collection and the original value changed. otherwise it could just be null
                                 $changed = true;
                                 break;
                             } else {
                                 if ($fieldValue->changed()) {
                                     $this->visitedCollections[] = $fieldValue;
                                     $changed = true;
                                     break;
                                 }
                             }
                         }
                     }
                 } else {
                     if ($class->hasAttachments && $fieldName == $class->attachmentField) {
                         // array of value objects, can compare that stricly
                         if ($this->originalData[$oid][$fieldName] !== $fieldValue) {
                             $changed = true;
                             break;
                         }
                     }
                 }
             }
         }
         // Check embedded documents here, only if there is no change yet
         if (!$changed) {
             foreach ($embeddedActualData as $fieldName => $fieldValue) {
                 if (!isset($this->originalEmbeddedData[$oid][$fieldName]) || $this->embeddedSerializer->isChanged($actualData[$fieldName], $this->originalEmbeddedData[$oid][$fieldName], $class->fieldMappings[$fieldName])) {
                     $changed = true;
                     break;
                 }
             }
         }
         if ($changed) {
             $this->originalData[$oid] = $actualData;
             $this->scheduledUpdates[$oid] = $document;
             $this->originalEmbeddedData[$oid] = $embeddedActualData;
         }
     }
     // 3. check if any cascading needs to happen
     foreach ($class->associationsMappings as $name => $assoc) {
         if ($this->originalData[$oid][$name]) {
             $this->computeAssociationChanges($assoc, $this->originalData[$oid][$name]);
         }
     }
 }
Пример #10
0
 public function testDeriveChildMetadata()
 {
     $cm = new ClassMetadata("Doctrine\\Tests\\ODM\\CouchDB\\Mapping\\Person");
     $cm->mapField(array('fieldName' => 'id', 'id' => true));
     $cm->mapField(array('fieldName' => 'username', 'type' => 'string'));
     $cm->mapAttachments('attachments');
     $cm->mapManyToOne(array('targetDocument' => 'Address', 'fieldName' => 'address'));
     $child = new ClassMetadata('Doctrine\\Tests\\ODM\\CouchDB\\Mapping\\Employee');
     $cm->deriveChildMetadata($child);
     $child->mapField(array('fieldName' => 'status', 'type' => 'string'));
     $this->assertFalse(isset($child->fieldMappings['status']['declared']));
     $this->assertEquals("Doctrine\\Tests\\ODM\\CouchDB\\Mapping\\Employee", $child->name);
     $this->assertTrue(isset($child->fieldMappings['id']), "id field has to be on child metadata");
     $this->assertEquals("Doctrine\\Tests\\ODM\\CouchDB\\Mapping\\Person", $child->fieldMappings['id']['declared']);
     $this->assertTrue(isset($child->fieldMappings['username']), "Username field has to be on child metadata");
     $this->assertEquals("Doctrine\\Tests\\ODM\\CouchDB\\Mapping\\Person", $child->fieldMappings['username']['declared']);
     $this->assertTrue(isset($child->associationsMappings['address']), "address association has to be on child metadata");
     $this->assertEquals("Doctrine\\Tests\\ODM\\CouchDB\\Mapping\\Person", $child->associationsMappings['address']['declared']);
     $this->assertEquals("attachments", $child->attachmentField);
     $this->assertEquals("Doctrine\\Tests\\ODM\\CouchDB\\Mapping\\Person", $child->attachmentDeclaredClass);
     return $child;
 }