public function setUp() { if (!class_exists('Jackalope\\Factory', true)) { $this->markTestSkipped('The Node needs to be properly mocked/stubbed. Remove dependency to Jackalope'); } $this->factory = new Factory(); $this->session = $this->getMock('Jackalope\\Session', array(), array($this->factory), '', false); $this->objectManager = $this->getMock('Jackalope\\ObjectManager', array(), array($this->factory), '', false); $this->type = 'Doctrine\\Tests\\ODM\\PHPCR\\UoWUser'; $this->dm = DocumentManager::create($this->session); $this->uow = new UnitOfWork($this->dm); $cmf = $this->dm->getMetadataFactory(); $metadata = new ClassMetadata($this->type); $metadata->initializeReflection($cmf->getReflectionService()); $metadata->mapId(array('fieldName' => 'id', 'id' => true)); $metadata->idGenerator = ClassMetadata::GENERATOR_TYPE_ASSIGNED; $metadata->mapField(array('fieldName' => 'username', 'type' => 'string')); $cmf->setMetadataFor($this->type, $metadata); }
/** * Returns true is the model has some metadata. * * @param string $class * * @return boolean */ public function hasMetadata($class) { return $this->dm->getMetadataFactory()->hasMetadataFor($class); }
/** * Create a document given class, data and the doc-id and revision * * Supported hints are * - refresh: reload the fields from the database * - locale: use this locale instead of the one from the annotation or the default * - fallback: whether to try other languages or throw a not found * exception if the desired locale is not found. defaults to true if * not set and locale is not given either. * * @param null|string $className * @param \PHPCR\NodeInterface $node * @param array $hints * @return object */ public function createDocument($className, $node, array &$hints = array()) { $requestedClassName = $className; $className = $this->documentClassMapper->getClassName($this->dm, $node, $className); $class = $this->dm->getClassMetadata($className); $documentState = array(); $nonMappedData = array(); $id = $node->getPath(); // second param is false to get uuid rather than dereference reference properties to node instances $properties = $node->getPropertiesValues(null, false); foreach ($class->fieldMappings as $fieldName => $mapping) { if (isset($properties[$mapping['name']])) { if ($mapping['multivalue']) { $collection = $properties[$mapping['name']] instanceof Collection ? $properties[$mapping['name']] : new ArrayCollection((array) $properties[$mapping['name']]); $documentState[$fieldName] = new MultivaluePropertyCollection($collection); $this->multivaluePropertyCollections[] = $documentState[$fieldName]; } else { $documentState[$fieldName] = $properties[$mapping['name']]; } } } if ($class->node) { $documentState[$class->node] = $node; } if ($class->nodename) { $documentState[$class->nodename] = $node->getName(); } if ($class->identifier) { $documentState[$class->identifier] = $node->getPath(); } // collect uuids of all referenced nodes and get them all within one single call // they will get cached so you have more performance when they are accessed later $refNodeUUIDs = array(); foreach ($class->associationsMappings as $assocOptions) { if (!$node->hasProperty($assocOptions['fieldName'])) { continue; } if ($assocOptions['type'] & ClassMetadata::MANY_TO_ONE) { $refNodeUUIDs[] = $node->getProperty($assocOptions['fieldName'])->getString(); } elseif ($assocOptions['type'] & ClassMetadata::MANY_TO_MANY) { foreach ($node->getProperty($assocOptions['fieldName'])->getString() as $uuid) { $refNodeUUIDs[] = $uuid; } } } if (count($refNodeUUIDs) > 0) { // ensure that the given nodes are in the in memory cache $this->session->getNodesByIdentifier($refNodeUUIDs); } // initialize inverse side collections foreach ($class->associationsMappings as $assocName => $assocOptions) { if ($assocOptions['type'] & ClassMetadata::MANY_TO_ONE) { // TODO figure this one out which collection should be used if (!$node->hasProperty($assocOptions['fieldName'])) { continue; } // get the already cached referenced node $referencedNode = $node->getPropertyValue($assocOptions['fieldName']); $referencedClass = isset($assocOptions['targetDocument']) ? $this->dm->getMetadataFactory()->getMetadataFor(ltrim($assocOptions['targetDocument'], '\\'))->name : null; $proxy = $referencedClass ? $this->createProxy($referencedNode->getPath(), $referencedClass) : $this->createProxyFromNode($referencedNode); $documentState[$class->associationsMappings[$assocName]['fieldName']] = $proxy; } elseif ($assocOptions['type'] & ClassMetadata::MANY_TO_MANY) { if (!$node->hasProperty($assocOptions['fieldName'])) { continue; } // get the already cached referenced nodes $proxyNodes = $node->getPropertyValue($assocOptions['fieldName']); if (!is_array($proxyNodes)) { throw new PHPCRException('Expected referenced nodes passed as array.'); } $referencedDocs = array(); foreach ($proxyNodes as $referencedNode) { $referencedClass = isset($assocOptions['targetDocument']) ? $this->dm->getMetadataFactory()->getMetadataFor(ltrim($assocOptions['targetDocument'], '\\'))->name : null; $proxy = $referencedClass ? $this->createProxy($referencedNode->getPath(), $referencedClass) : $this->createProxyFromNode($referencedNode); $referencedDocs[] = $proxy; } if (count($referencedDocs) > 0) { $collection = new ReferenceManyCollection(new ArrayCollection($referencedDocs), true); $documentState[$class->associationsMappings[$assocName]['fieldName']] = $collection; } } } if ($class->parentMapping && $node->getDepth() > 0) { // do not map parent to self if we are at root $documentState[$class->parentMapping] = $this->createProxyFromNode($node->getParent()); } foreach ($class->childMappings as $childName => $mapping) { $documentState[$class->childMappings[$childName]['fieldName']] = $node->hasNode($mapping['name']) ? $this->createProxyFromNode($node->getNode($mapping['name'])) : null; } $document = $this->getDocumentById($id); if ($document) { $overrideLocalValuesOid = empty($hints['refresh']) ? false : spl_object_hash($document); } else { $document = $class->newInstance(); $overrideLocalValuesOid = $this->registerDocument($document, $id); } if (isset($requestedClassName) && $this->validateDocumentName && !$document instanceof $requestedClassName) { $msg = "Doctrine metadata mismatch! Requested type '{$requestedClassName}' type does not match type '" . get_class($document) . "' stored in the metadata"; throw new \InvalidArgumentException($msg); } foreach ($class->childrenMappings as $mapping) { $documentState[$mapping['fieldName']] = new ChildrenCollection($this->dm, $document, $mapping['filter']); } foreach ($class->referrersMappings as $mapping) { $documentState[$mapping['fieldName']] = new ReferrersCollection($this->dm, $document, $mapping['referenceType'], $mapping['filter']); } if ($overrideLocalValuesOid) { $this->nonMappedData[$overrideLocalValuesOid] = $nonMappedData; foreach ($class->reflFields as $prop => $reflFields) { $value = isset($documentState[$prop]) ? $documentState[$prop] : null; $reflFields->setValue($document, $value); $this->originalData[$overrideLocalValuesOid][$prop] = $value; } } // Load translations $locale = isset($hints['locale']) ? $hints['locale'] : null; $fallback = isset($hints['fallback']) ? $hints['fallback'] : is_null($locale); $this->doLoadTranslation($document, $class, $locale, $fallback); // Invoke the postLoad lifecycle callbacks and listeners if (isset($class->lifecycleCallbacks[Event::postLoad])) { $class->invokeLifecycleCallbacks(Event::postLoad, $document); } if ($this->evm->hasListeners(Event::postLoad)) { $this->evm->dispatchEvent(Event::postLoad, new Event\LifecycleEventArgs($document, $this->dm)); } return $document; }
/** * Initializes a new instance of the <tt>ProxyFactory</tt> class that is * connected to the given <tt>DocumentManager</tt>. * * @param DocumentManager $documentManager The DocumentManager the new factory works for. * @param string $proxyDir The directory to use for the proxy classes. It must exist. * @param string $proxyNamespace The namespace to use for the proxy classes. * @param boolean $autoGenerate Whether to automatically generate proxy classes. */ public function __construct(DocumentManager $documentManager, $proxyDir, $proxyNamespace, $autoGenerate = false) { parent::__construct(new ProxyGenerator($proxyDir, $proxyNamespace), $documentManager->getMetadataFactory(), $autoGenerate); $this->documentManager = $documentManager; $this->proxyNamespace = $proxyNamespace; }
public function __construct(DocumentManager $dm, QueryObjectModelFactoryInterface $qomf) { $this->qomf = $qomf; $this->mdf = $dm->getMetadataFactory(); $this->dm = $dm; }