public function addNode($relPath, $primaryNodeTypeName = null)
{
$relPath = (string) $relPath;
$this->checkState();
$ntm = $this->session->getWorkspace()->getNodeTypeManager();
// are we not the immediate parent?
if (strpos($relPath, '/') !== false) {
// forward to real parent
$relPath = PathHelper::absolutizePath($relPath, $this->getPath(), true);
$parentPath = PathHelper::getParentPath($relPath);
$newName = PathHelper::getNodeName($relPath);
try {
$parentNode = $this->objectManager->getNodeByPath($parentPath);
} catch (ItemNotFoundException $e) {
//we have to throw a different exception if there is a property
// with that name than if there is nothing at the path at all.
// lets see if the property exists
if ($this->session->propertyExists($parentPath)) {
throw new ConstraintViolationException("Node '{$this->path}': Not allowed to add a node below property at {$parentPath}");
}
throw new PathNotFoundException($e->getMessage(), $e->getCode(), $e);
}
return $parentNode->addNode($newName, $primaryNodeTypeName);
}
if (null === $primaryNodeTypeName) {
if ($this->primaryType === 'rep:root') {
$primaryNodeTypeName = 'nt:unstructured';
} else {
$type = $ntm->getNodeType($this->primaryType);
$nodeDefinitions = $type->getChildNodeDefinitions();
foreach ($nodeDefinitions as $def) {
if (!is_null($def->getDefaultPrimaryType())) {
$primaryNodeTypeName = $def->getDefaultPrimaryTypeName();
break;
}
}
}
if (is_null($primaryNodeTypeName)) {
throw new ConstraintViolationException("No matching child node definition found for `{$relPath}' in type `{$this->primaryType}' for node '{$this->path}'. Please specify the type explicitly.");
}
}
// create child node
//sanity check: no index allowed. TODO: we should verify this is a valid node name
if (false !== strpos($relPath, ']')) {
throw new RepositoryException("The node '{$this->path}' does not allow an index in name of newly created node: {$relPath}");
}
if (in_array($relPath, $this->nodes, true)) {
throw new ItemExistsException("The node '{$this->path}' already has a child named '{$relPath}''.");
//TODO: same-name siblings if nodetype allows for them
}
$data = array('jcr:primaryType' => $primaryNodeTypeName);
$path = $this->getChildPath($relPath);
$node = $this->factory->get('Node', array($data, $path, $this->session, $this->objectManager, true));
$this->addChildNode($node, false);
// no need to check the state, we just checked when entering this method
$this->objectManager->addNode($path, $node);
if (is_array($this->originalNodesOrder)) {
// new nodes are added at the end
$this->originalNodesOrder[] = $relPath;
}
//by definition, adding a node sets the parent to modified
$this->setModified();
return $node;
}