-
-
Notifications
You must be signed in to change notification settings - Fork 99
allow to add uuid as id to proxies #493
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
base: 2.0.x
Are you sure you want to change the base?
Changes from all commits
2a2497c
7b5ef44
d52bfd0
b9ccfa9
c9d6f80
71f4a58
ca55003
860eb22
d53fc67
9841f74
8fc96b8
f77edd6
6bc1450
8b5161d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -313,28 +313,33 @@ public function getClassMetadata($className) | |
*/ | ||
public function find($className, $id) | ||
{ | ||
try { | ||
if (UUIDHelper::isUUID($id)) { | ||
try { | ||
$id = $this->session->getNodeByIdentifier($id)->getPath(); | ||
} catch (ItemNotFoundException $e) { | ||
return null; | ||
} | ||
} elseif (strpos($id, '/') !== 0) { | ||
$id = '/'.$id; | ||
} | ||
// document still mapped -> return that when class name is valid | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why "still"? i would move that inside the if and say "// document already mapped -> check class" |
||
$document = $this->unitOfWork->getDocumentById($id); | ||
if ($document) { | ||
$document = $this->documentHasValidClassName($document, $className) ? $document : null; | ||
return $document; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cs: needs a blank line before the return statement. |
||
} | ||
|
||
$document = $this->unitOfWork->getDocumentById($id); | ||
if ($document) { | ||
try { | ||
$this->unitOfWork->validateClassName($document, $className); | ||
// id can either be an path or an uuid, so we can have a look if one of both does have an entry | ||
if (UUIDHelper::isUUID($id)) { | ||
try { | ||
$id = $this->session->getNodeByIdentifier($id)->getPath(); | ||
} catch (ItemNotFoundException $e) { | ||
return null; | ||
} | ||
} elseif (strpos($id, '/') !== 0) { | ||
$id = '/'.$id; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In what cases would the path not be absolute? Surely we want to throw an Exception here (or let the PHPCR\Session throw an exception for us) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same stuff as before, I just put the regquest for an existing document on top.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah now i understand your question. I just keep that ExceptionManagement cause i don't understand it at all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dantleech reading the above removed code, it seems we already did the same before. not sure why but i would not change that behaviour in this refactoring. it should not break any BC. |
||
} | ||
|
||
return $document; | ||
} catch (ClassMismatchException $e) { | ||
return null; | ||
} | ||
// document mapped by id = absolute Path -> return that when class name is valid | ||
$document = $this->unitOfWork->getDocumentById($id); | ||
if ($document) { | ||
$document = $this->documentHasValidClassName($document, $className) ? $document : null; | ||
return $document; | ||
} | ||
|
||
} | ||
// no document mapped, then try to fetch it from session and create a new one | ||
try { | ||
$node = $this->session->getNode($id); | ||
} catch (PathNotFoundException $e) { | ||
return null; | ||
|
@@ -349,6 +354,25 @@ public function find($className, $id) | |
} | ||
} | ||
|
||
/** | ||
* Just a little helper to validate the documents class name with a | ||
* boolean answer. | ||
* | ||
* @param object $document | ||
* @param string $className | ||
* @return bool | ||
*/ | ||
private function documentHasValidClassName($document, $className) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this is not the right way to solve things. i would take out the actual logic form validateClassName into isValidClassName (in the UoW) that just returns a boolean. then you can call that directly. and valdiateClassName just calls There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 i just didn't like that long try-catch sections. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i totally agree with you, just think the solution should be to not even There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here i recognized a problem, some tests and some situations are waiting for some exceptions and i have got no clue when catch an exception and just return null (or some equal) or doesn't catch it. So the |
||
{ | ||
try { | ||
$this->unitOfWork->validateClassName($document, $className); | ||
|
||
return true; | ||
} catch(ClassMismatchException $e) { | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* Finds many documents by id. | ||
* | ||
|
@@ -1190,23 +1214,40 @@ public function initializeObject($document) | |
} | ||
|
||
/** | ||
* Return the node of the given object | ||
* Return the node of the given object or its hash. | ||
* | ||
* @param object $document | ||
* This node is fetched by the objects uuid or its id means the absolute path. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't really get that. |
||
* | ||
* @param object|string $document | ||
* | ||
* @return \PHPCR\NodeInterface | ||
* | ||
* @throws InvalidArgumentException if $document is not an object. | ||
* @throws InvalidArgumentException if $document isn't mapped in UoW. | ||
* @throws PHPCRException if $document is not managed | ||
*/ | ||
public function getNodeForDocument($document) | ||
{ | ||
if (!is_object($document)) { | ||
throw new InvalidArgumentException('Parameter $document needs to be an object, '.gettype($document).' given'); | ||
if (!$identifier = $this->unitOfWork->getDocumentId($document)) { | ||
throw new InvalidArgumentException('Parameter document should have an entry in identityMap.'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets say: "This document is not managed by this manager" or something like this. |
||
} | ||
|
||
$path = $this->unitOfWork->getDocumentId($document); | ||
return $this->getNodeByPathOrUuid($identifier); | ||
} | ||
|
||
/** | ||
* Creates a node from a given path or an uuid | ||
* | ||
* @param $pathOrUuid | ||
* @return \PHPCR\NodeInterface | ||
*/ | ||
public function getNodeByPathOrUuid($pathOrUuid) | ||
{ | ||
if (UUIDHelper::isUUID($pathOrUuid)) { | ||
$node = $this->session->getNodeByIdentifier($pathOrUuid); | ||
} else { | ||
$node = $this->session->getNode($pathOrUuid); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this is wrong. its moving session dependency into the document manager, and duplicating getDocumentId. and it will only work if the document was already flushed, but not for new managed documents, as UoW::getDocumentId. we should move the logic to handle uuid into getDocumentId and make the uow look in the right places. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean put that code into the getDocumentId(), ok would make sense. |
||
} | ||
|
||
return $this->session->getNode($path); | ||
return $node; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -664,11 +664,17 @@ public function getOrCreateProxy($targetId, $className, $locale = null) | |
* Populate the proxy with actual data | ||
* | ||
* @param string $className | ||
* @param Proxy $document | ||
* @param Proxy $document | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no, the CS says to align the parameters so it was correct before. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't know why this hapend |
||
*/ | ||
public function refreshDocumentForProxy($className, Proxy $document) | ||
{ | ||
$node = $this->session->getNode($this->determineDocumentId($document)); | ||
$identifier = $this->determineDocumentId($document); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will need to check if this will work on my working project, cause as the proxy document is registered, the id don't need to be determined. A mapping should exist. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so needed to roll back that |
||
$node = $this->dm->getNodeByPathOrUuid($identifier); | ||
if (UUIDHelper::isUUID($identifier)) { | ||
// switch document registration to path as usual | ||
$this->unregisterDocument($document); | ||
$this->registerDocument($document, $node->getPath()); | ||
} | ||
|
||
$hints = array('refresh' => true, 'fallback' => true); | ||
|
||
|
@@ -1741,13 +1747,11 @@ private function doRefresh($document, &$visited) | |
throw new InvalidArgumentException('Document has to be managed to be refreshed '.self::objToStr($document, $this->dm)); | ||
} | ||
|
||
$node = $this->session->getNode($this->getDocumentId($document)); | ||
|
||
$class = $this->dm->getClassMetadata(get_class($document)); | ||
$this->cascadeRefresh($class, $document, $visited); | ||
|
||
$hints = array('refresh' => true); | ||
$this->getOrCreateDocument(ClassUtils::getClass($document), $node, $hints); | ||
$this->getOrCreateDocument(ClassUtils::getClass($document), $this->dm->getNodeForDocument($document), $hints); | ||
} | ||
|
||
public function merge($document) | ||
|
@@ -2402,7 +2406,7 @@ private function executeUpdates($documents, $dispatchEvents = true) | |
} | ||
|
||
$class = $this->dm->getClassMetadata(get_class($document)); | ||
$node = $this->session->getNode($this->getDocumentId($document)); | ||
$node = $this->dm->getNodeForDocument($document); | ||
|
||
if ($this->writeMetadata) { | ||
$this->documentClassMapper->writeMetadata($this->dm, $node, $class->name); | ||
|
@@ -2491,7 +2495,7 @@ private function executeUpdates($documents, $dispatchEvents = true) | |
continue; | ||
} | ||
|
||
$associatedNode = $this->session->getNode($this->getDocumentId($fv)); | ||
$associatedNode = $this->dm->getNodeForDocument($fv); | ||
if ($strategy === PropertyType::PATH) { | ||
$refNodesIds[] = $associatedNode->getPath(); | ||
} else { | ||
|
@@ -2509,7 +2513,7 @@ private function executeUpdates($documents, $dispatchEvents = true) | |
} | ||
} elseif ($mapping['type'] === $class::MANY_TO_ONE) { | ||
if (isset($fieldValue)) { | ||
$associatedNode = $this->session->getNode($this->getDocumentId($fieldValue)); | ||
$associatedNode = $this->dm->getNodeForDocument($fieldValue); | ||
|
||
if ($strategy === PropertyType::PATH) { | ||
$node->setProperty($fieldName, $associatedNode->getPath(), $strategy); | ||
|
@@ -2541,7 +2545,7 @@ private function executeUpdates($documents, $dispatchEvents = true) | |
throw new PHPCRException(sprintf("%s is not an instance of %s for document %s field %s", self::objToStr($fv, $this->dm), $mapping['referencedBy'], self::objToStr($document, $this->dm), $mapping['fieldName'])); | ||
} | ||
|
||
$referencingNode = $this->session->getNode($this->getDocumentId($fv)); | ||
$referencingNode = $this->dm->getNodeForDocument($fv); | ||
$referencingMeta = $this->dm->getClassMetadata($mapping['referringDocument']); | ||
$referencingField = $referencingMeta->getAssociation($mapping['referencedBy']); | ||
|
||
|
@@ -2724,7 +2728,7 @@ private function executeReorders($documents) | |
} | ||
foreach ($list as $value) { | ||
list($parent, $src, $target, $before) = $value; | ||
$parentNode = $this->session->getNode($this->getDocumentId($parent)); | ||
$parentNode = $this->dm->getNodeForDocument($parent); | ||
|
||
// check for src and target ... | ||
$dest = $target; | ||
|
@@ -2772,7 +2776,7 @@ private function executeRemovals($documents) | |
$id = $this->getDocumentId($document); | ||
|
||
try { | ||
$node = $this->session->getNode($id); | ||
$node = $this->dm->getNodeByPathOrUuid($id); | ||
$this->doRemoveAllTranslations($document, $class); | ||
$node->remove(); | ||
} catch (PathNotFoundException $e) { | ||
|
@@ -2953,7 +2957,7 @@ public function removeVersion($documentVersion) | |
* | ||
* @param object $document | ||
*/ | ||
private function unregisterDocument($document) | ||
public function unregisterDocument($document) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this can stay private There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you want to not manage a document anymore through the API, use $dm->detach($document) |
||
{ | ||
$oid = spl_object_hash($document); | ||
|
||
|
@@ -3138,7 +3142,7 @@ public function getLocalesFor($document) | |
$oid = spl_object_hash($document); | ||
if ($this->contains($oid)) { | ||
try { | ||
$node = $this->session->getNode($this->getDocumentId($document)); | ||
$node = $this->dm->getNodeForDocument($document); | ||
$locales = $this->dm->getTranslationStrategy($metadata->translator)->getLocalesFor($document, $node, $metadata); | ||
} catch (PathNotFoundException $e) { | ||
$locales = array(); | ||
|
@@ -3264,7 +3268,7 @@ protected function doLoadDatabaseTranslation($document, ClassMetadata $metadata, | |
|
||
$strategy = $this->dm->getTranslationStrategy($metadata->translator); | ||
try { | ||
$node = $this->session->getNode($this->getDocumentId($oid)); | ||
$node = $this->dm->getNodeForDocument($oid); | ||
if ($strategy->loadTranslation($document, $node, $metadata, $locale)) { | ||
return $locale; | ||
} | ||
|
@@ -3464,9 +3468,8 @@ private function doRemoveAllTranslations($document, ClassMetadata $metadata) | |
return; | ||
} | ||
|
||
$node = $this->session->getNode($this->getDocumentId($document)); | ||
$strategy = $this->dm->getTranslationStrategy($metadata->translator); | ||
$strategy->removeAllTranslations($document, $node, $metadata); | ||
$strategy->removeAllTranslations($document, $this->dm->getNodeForDocument($document), $metadata); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, lets keep the node assignment above. |
||
} | ||
|
||
private function setLocale($document, ClassMetadata $metadata, $locale) | ||
|
@@ -3573,28 +3576,16 @@ private static function objToStr($obj, DocumentManager $dm = null) | |
|
||
private function getVersionedNodePath($document) | ||
{ | ||
$path = $this->getDocumentId($document); | ||
$id = $this->getDocumentId($document); | ||
$metadata = $this->dm->getClassMetadata(get_class($document)); | ||
|
||
if (!$metadata->versionable) { | ||
throw new InvalidArgumentException(sprintf( | ||
"The document at path '%s' is not versionable", | ||
$path | ||
)); | ||
} | ||
|
||
$node = $this->session->getNode($path); | ||
|
||
$mixin = $metadata->versionable === 'simple' ? | ||
'mix:simpleVersionable' : | ||
'mix:versionable'; | ||
|
||
if (!$node->isNodeType($mixin)) { | ||
$node->addMixin($mixin); | ||
if ($metadata->versionable !== 'full') { | ||
throw new InvalidArgumentException(sprintf("The document at '%s' is not full versionable", $id)); | ||
} | ||
|
||
$node = $this->dm->getNodeByPathOrUuid($id); | ||
$node->addMixin('mix:versionable'); | ||
|
||
return $path; | ||
return $id; | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, the refacotring in this method is making things messier without really helping much. i would shove the whole code you have here below into a method cleanId($id), to prepare for further refactoring. but keep the order of things as before.