diff --git a/CHANGELOG.md b/CHANGELOG.md index f5728308..22ba5d7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,13 @@ dev-master ### Bug fixes - [config] Do not override CLI options with profile options +- [node:remove] Cannot `node:remove` by UUID +- [node:edit] Serialization of single value references doesn't work ### Features +- [node:remove] Immediately fail when trying to delete a node which has a + (hard) referrer - [cli] Specify workspace with first argument - [global] Refactored to use DI container and various general improvements - [node:property:set] Allow setting reference property type by path diff --git a/features/all/phpcr_node_edit.feature b/features/all/phpcr_node_edit.feature index 3c1fa40f..aaae6311 100644 --- a/features/all/phpcr_node_edit.feature +++ b/features/all/phpcr_node_edit.feature @@ -28,6 +28,9 @@ Feature: Edit a node articles: type: Reference value: [ 66666fc6-1abf-4708-bfcc-e49511754b40, 77777777-1abf-4708-bfcc-e49511754b40 ] + article-weak: + type: WeakReference + value: 99999999-1abf-4708-bfcc-e49511754b40 'jcr:primaryType': type: Name value: 'nt:unstructured' diff --git a/features/all/phpcr_node_remove.feature b/features/all/phpcr_node_remove.feature index 8636bc94..6165b8c4 100644 --- a/features/all/phpcr_node_remove.feature +++ b/features/all/phpcr_node_remove.feature @@ -5,23 +5,23 @@ Feature: Remove a node Background: Given that I am logged in as "testuser" - And the "session_data.xml" fixtures are loaded + And the "cms.xml" fixtures are loaded Scenario: Remove the current node - Given the current node is "/tests_general_base" + Given the current node is "/cms/test" And I execute the "node:remove ." command Then the command should not fail And I save the session - And there should not exist a node at "/tests_general_base" - And the current node should be "/" + And there should not exist a node at "/cms/test" + And the current node should be "/cms" Scenario: Remove a non-current node - Given the current node is "/tests_general_base" - And I execute the "node:remove daniel" command + Given the current node is "/cms" + And I execute the "node:remove /cms/users/daniel" command Then the command should not fail And I save the session - And there should not exist a node at "/tests_general_base/daniel" - And the current node should be "/tests_general_base" + And there should not exist a node at "/cms/users/daniel" + And the current node should be "/cms" Scenario: Delete root node Given the current node is "/" @@ -37,3 +37,20 @@ Feature: Remove a node Then the command should not fail And I save the session And there should not exist a node at "/tests_general_base/daniel" + + Scenario: Delete node by UUID + Given the current node is "/" + And I execute the "node:remove 88888888-1abf-4708-bfcc-e49511754b40" command + Then the command should not fail + + Scenario: Delete referenced node + Given I execute the "node:remove /cms/articles/article1" command + Then the command should fail + And I should see the following: + """ + The node "/cms/articles/article1" is referenced by the following properties + """ + + Scenario: Delete weak referenced node + Given I execute the "node:remove /cms/articles/article3" command + Then the command should not fail diff --git a/features/fixtures/cms.xml b/features/fixtures/cms.xml index ad65624a..51de2d96 100644 --- a/features/fixtures/cms.xml +++ b/features/fixtures/cms.xml @@ -54,6 +54,26 @@ <sv:value>66666fc6-1abf-4708-bfcc-e49511754b40</sv:value> <sv:value>77777777-1abf-4708-bfcc-e49511754b40</sv:value> </sv:property> + <sv:property sv:name="article-weak" sv:type="WeakReference"> + <sv:value>99999999-1abf-4708-bfcc-e49511754b40</sv:value> + </sv:property> + </sv:node> + </sv:node> + + <sv:node sv:name="users"> + <sv:property sv:name="jcr:primaryType" sv:type="Name"> + <sv:value>nt:unstructured</sv:value> + </sv:property> + <sv:node sv:name="daniel"> + <sv:property sv:name="jcr:primaryType" sv:type="Name"> + <sv:value>nt:unstructured</sv:value> + </sv:property> + <sv:property sv:name="jcr:mixinTypes" sv:type="Name"> + <sv:value>mix:referenceable</sv:value> + </sv:property> + <sv:property sv:name="jcr:uuid" sv:type="String"> + <sv:value>88888888-1abf-4708-bfcc-e49511754b40</sv:value> + </sv:property> </sv:node> </sv:node> @@ -113,6 +133,20 @@ <sv:value>Planes</sv:value> </sv:property> </sv:node> + <sv:node sv:name="article3"> + <sv:property sv:name="jcr:primaryType" sv:type="Name"> + <sv:value>nt:unstructured</sv:value> + </sv:property> + <sv:property sv:name="jcr:mixinTypes" sv:type="Name"> + <sv:value>mix:referenceable</sv:value> + </sv:property> + <sv:property sv:name="jcr:uuid" sv:type="String"> + <sv:value>99999999-1abf-4708-bfcc-e49511754b40</sv:value> + </sv:property> + <sv:property sv:name="title" sv:type="String"> + <sv:value>Article 3</sv:value> + </sv:property> + </sv:node> </sv:node> </sv:node> diff --git a/src/PHPCR/Shell/Console/Application/.ShellApplication.php.swl b/src/PHPCR/Shell/Console/Application/.ShellApplication.php.swl new file mode 100755 index 00000000..77849e0d Binary files /dev/null and b/src/PHPCR/Shell/Console/Application/.ShellApplication.php.swl differ diff --git a/src/PHPCR/Shell/Console/Command/Phpcr/NodeRemoveCommand.php b/src/PHPCR/Shell/Console/Command/Phpcr/NodeRemoveCommand.php index 1eb34005..1b142a5d 100644 --- a/src/PHPCR/Shell/Console/Command/Phpcr/NodeRemoveCommand.php +++ b/src/PHPCR/Shell/Console/Command/Phpcr/NodeRemoveCommand.php @@ -25,6 +25,7 @@ public function execute(InputInterface $input, OutputInterface $output) $session = $this->get('phpcr.session'); $path = $input->getArgument('path'); $currentPath = $session->getCwd(); + $nodePaths = array(); // verify that node exists by trying to get it.. $nodes = $session->findNodes($path); @@ -36,11 +37,27 @@ public function execute(InputInterface $input, OutputInterface $output) ); } + $references = $node->getReferences(); + + if (count($references) > 0) { + $paths = array(); + foreach ($references as $reference) { + $paths[] = $reference->getPath(); + } + + throw new \InvalidArgumentException(sprintf( + 'The node "%s" is referenced by the following properties: "%s"', + $node->getPath(), + implode('", "', $paths) + )); + } + + $nodePaths[] = $node->getPath(); $node->remove(); } // if we deleted the current path, switch back to the parent node - if ($currentPath == $session->getAbsPath($path)) { + if (in_array($currentPath, $nodePaths)) { $session->chdir('..'); } } diff --git a/src/PHPCR/Shell/Serializer/NodeNormalizer.php b/src/PHPCR/Shell/Serializer/NodeNormalizer.php index 01b63fb0..c6028adb 100644 --- a/src/PHPCR/Shell/Serializer/NodeNormalizer.php +++ b/src/PHPCR/Shell/Serializer/NodeNormalizer.php @@ -48,7 +48,12 @@ public function normalize($node, $format = null, array $context = array()) if (in_array($property->getType(), array(PropertyType::REFERENCE, PropertyType::WEAKREFERENCE))) { $nodesUuids = array(); - foreach ((array) $propertyValue as $node) { + + if (false === is_array($propertyValue)) { + $propertyValue = array($propertyValue); + } + + foreach ($propertyValue as $node) { $nodeUuids[] = $node->getIdentifier(); } $propertyValue = $nodeUuids;