/** * TODO: we should move that into the common Jackalope BaseTransport or as new method of NodeType * it will be helpful for other implementations. * * Validate this node with the nodetype and generate not yet existing * autogenerated properties as necessary. * * @param Node $node * @param NodeType $def */ private function validateNodeWithType(Node $node, NodeType $def) { foreach ($def->getDeclaredChildNodeDefinitions() as $childDef) { /* @var $childDef NodeDefinitionInterface */ if (!$node->hasNode($childDef->getName())) { if ('*' === $childDef->getName()) { continue; } if ($childDef->isMandatory() && !$childDef->isAutoCreated()) { throw new RepositoryException( "Child " . $childDef->getName() . " is mandatory, but is not present while ". "saving " . $def->getName() . " at " . $node->getPath() ); } if ($childDef->isAutoCreated()) { $requiredPrimaryTypeNames = $childDef->getRequiredPrimaryTypeNames(); $primaryType = count($requiredPrimaryTypeNames) ? current($requiredPrimaryTypeNames) : null; $newNode = $node->addNode($childDef->getName(), $primaryType); $absPath = $node->getPath() . '/' . $childDef->getName(); $operation = new AddNodeOperation($absPath, $newNode); $this->additionalNodeAddOperations[] = $operation; } } } foreach ($def->getDeclaredPropertyDefinitions() as $propertyDef) { /* @var $propertyDef PropertyDefinitionInterface */ if ('*' == $propertyDef->getName()) { continue; } if (!$node->hasProperty($propertyDef->getName())) { if ($propertyDef->isMandatory() && !$propertyDef->isAutoCreated()) { throw new RepositoryException( "Property " . $propertyDef->getName() . " is mandatory, but is not present while ". "saving " . $def->getName() . " at " . $node->getPath() ); } if ($propertyDef->isAutoCreated()) { switch ($propertyDef->getName()) { case 'jcr:uuid': $value = $this->generateUuid(); break; case 'jcr:createdBy': case 'jcr:lastModifiedBy': $value = $this->credentials->getUserID(); break; case 'jcr:created': case 'jcr:lastModified': $value = new \DateTime(); break; case 'jcr:etag': // TODO: http://www.day.com/specs/jcr/2.0/3_Repository_Model.html#3.7.12.1%20mix:etag $value = 'TODO: generate from binary properties of this node'; break; default: $defaultValues = $propertyDef->getDefaultValues(); if ($propertyDef->isMultiple()) { $value = $defaultValues; } elseif (isset($defaultValues[0])) { $value = $defaultValues[0]; } else { // When implementing versionable or activity, we need to handle more properties explicitly throw new RepositoryException('No default value for autocreated property '. $propertyDef->getName(). ' at '.$node->getPath()); } } $node->setProperty( $propertyDef->getName(), $value, $propertyDef->getRequiredType() ); } } elseif ($propertyDef->isAutoCreated()) { $prop = $node->getProperty($propertyDef->getName()); if (!$prop->isModified() && !$prop->isNew()) { switch($propertyDef->getName()) { case 'jcr:lastModified': if ($this->getAutoLastModified()) { $prop->setValue(new \DateTime()); } break; case 'jcr:lastModifiedBy': if ($this->getAutoLastModified()) { $prop->setValue($this->credentials->getUserID()); } break; case 'jcr:etag': // TODO: update etag if needed break; } } } } foreach ($def->getDeclaredSupertypes() as $superType) { $this->validateNodeWithType($node, $superType); } foreach ($node->getProperties() as $property) { $this->assertValidProperty($property); } }
/** * TODO: we should move that into the common Jackalope BaseTransport or as new method of NodeType * it will be helpful for other implementations * * Validate this node with the nodetype and generate not yet existing * autogenerated properties as necessary * * @param Node $node * @param NodeType $def */ private function validateNode(Node $node, NodeType $def) { foreach ($def->getDeclaredChildNodeDefinitions() as $childDef) { /* @var $childDef \PHPCR\NodeType\NodeDefinitionInterface */ if (!$node->hasNode($childDef->getName())) { if ('*' === $childDef->getName()) { continue; } if ($childDef->isMandatory() && !$childDef->isAutoCreated()) { throw new RepositoryException("Child " . $childDef->getName() . " is mandatory, but is not present while " . "saving " . $def->getName() . " at " . $node->getPath()); } if ($childDef->isAutoCreated()) { throw new NotImplementedException("Auto-creation of child node '" . $def->getName() . "#" . $childDef->getName() . "' is not yet supported in DoctrineDBAL transport."); } } } foreach ($def->getDeclaredPropertyDefinitions() as $propertyDef) { /* @var $propertyDef \PHPCR\NodeType\PropertyDefinitionInterface */ if ('*' == $propertyDef->getName()) { continue; } if (!$node->hasProperty($propertyDef->getName())) { if ($propertyDef->isMandatory() && !$propertyDef->isAutoCreated()) { throw new RepositoryException("Property " . $propertyDef->getName() . " is mandatory, but is not present while " . "saving " . $def->getName() . " at " . $node->getPath()); } if ($propertyDef->isAutoCreated()) { switch ($propertyDef->getName()) { case 'jcr:uuid': $value = UUIDHelper::generateUUID(); break; case 'jcr:createdBy': case 'jcr:lastModifiedBy': $value = $this->credentials->getUserID(); break; case 'jcr:created': case 'jcr:lastModified': $value = new \DateTime(); break; case 'jcr:etag': // TODO: http://www.day.com/specs/jcr/2.0/3_Repository_Model.html#3.7.12.1%20mix:etag $value = 'TODO: generate from binary properties of this node'; break; default: $defaultValues = $propertyDef->getDefaultValues(); if ($propertyDef->isMultiple()) { $value = $defaultValues; } elseif (isset($defaultValues[0])) { $value = $defaultValues[0]; } else { // When implementing versionable or activity, we need to handle more properties explicitly throw new RepositoryException('No default value for autocreated property ' . $propertyDef->getName() . ' at ' . $node->getPath()); } } $node->setProperty($propertyDef->getName(), $value, $propertyDef->getRequiredType()); } } } foreach ($node->getProperties() as $property) { $this->assertValidProperty($property); } }