From ed9b95b806b2949ae2f879c456249aa8ff83bd69 Mon Sep 17 00:00:00 2001 From: dantleech Date: Thu, 30 Oct 2014 22:36:43 +0100 Subject: [PATCH] Always check for references when running node:remove - Help prevent transaction failure when calling save - Also allow the removal of node by UUID --- CHANGELOG.md | 4 +++ features/all/phpcr_node_edit.feature | 3 ++ features/all/phpcr_node_remove.feature | 33 ++++++++++++----- features/fixtures/cms.xml | 34 ++++++++++++++++++ .../Application/.ShellApplication.php.swl | Bin 0 -> 32768 bytes .../Command/Phpcr/NodeRemoveCommand.php | 19 +++++++++- src/PHPCR/Shell/Serializer/NodeNormalizer.php | 7 +++- 7 files changed, 90 insertions(+), 10 deletions(-) create mode 100755 src/PHPCR/Shell/Console/Application/.ShellApplication.php.swl 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 @@ 66666fc6-1abf-4708-bfcc-e49511754b40 77777777-1abf-4708-bfcc-e49511754b40 + + 99999999-1abf-4708-bfcc-e49511754b40 + + + + + + + nt:unstructured + + + + nt:unstructured + + + mix:referenceable + + + 88888888-1abf-4708-bfcc-e49511754b40 + @@ -113,6 +133,20 @@ Planes + + + nt:unstructured + + + mix:referenceable + + + 99999999-1abf-4708-bfcc-e49511754b40 + + + Article 3 + + 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 0000000000000000000000000000000000000000..77849e0d671c342ab885f056faf4c5860aa007a4 GIT binary patch literal 32768 zcmeI4dyE}deSn7)0(m;vBy9vqPmIxCTVAgnpv7x@@v>gWTkYEGeIyVzxU=`3yLa&2 zncJDUUa!|lN|T5`pnyn~N1ag7K&412QPS{IP(mpo5u$CNP2#p`E264WqgGI&AX?I< z-#K$;?%dbz-U)v+Vy^so_Rh?C{mx^~?=g3N=e1)K;x~7^$KrE|WnFFEK6A^aKd{am zwycuvI&yB96PV69?HH*z}$R&_VpdOa{-*=Jq?yIAT`p(T)iA@`4 zbGhUa$R&_VAeTTcfm{N)1ab-F638X+OC*7?cCK|Z?LEh|xnz!SXgR*we1EGs%9iVI zG~f4_uZ}uAghZm(B6fmg~P_zF%gJ!c;J>r#YP;atY)T$R&_VAeTTc zfm{N)1ab-F638WxOCXm(E`bgbuu=FOl>bYW0+0Vc*8l%|gJt~}{1yBq{4oSD2(O^T ze-G}0d9Yy{ymXOeeFyFa7e-(sJb$5OJp{MGt*{8ga5?NwJj?nI_&z)hPr)Pb0Ne_noou7?l7Q8*udhSB0b;RoRoFv8&E0lI;_rUzga?xU4_so{|&P?66poe*aMXcR|-q z$IFbKkZu?Z4h~OFj*pED&x{>8d~EFS*vxjZMXF2bzR@QrNOf&0nr4hz=xka_ZW6_G z$Uv~Go+}$dY3uf;6zTh{IO~Q8)EQrfb>D4dC54skB12A=c3ArCHnBhSO5UKDp%3kO?}QXVQM$J8c)|&U>j|2>Abs62 z+r^Sp{VQxS>3d~{+zv7AiA8&vtesF4ZP(-)XU-YMLfpZ6OxTT>rlbz@vP_-yWi!LZ z+*&;p6*~~~Qo16L;SOEJrpt@q zoMVTFCq}o6Zdb1zotkDnGI@9I+jJ=n$+UIr%6`XX33S2(UeT-}+v3sAlOU?5=Zk*f z+KWt5wQ~k&O z_gI~it=gNzOH7k7mz@Gn6*@^}p{p{d*HG2%WoKc|JS)aMo33xaYbIWY=90gnorS;L zesgn{9j~j%Sv4Nju5B*bwl%g2=6rj?>H56dkIi?gp_WyYRcgP{o=0?FYJpG>34OB5 zz3g;4$V@ljkgV3E9~Bz?-JXY<^s2Gu-Who^T<5J*GN@O>gPy-=hjib%Q^lLtbtag! z!^%2uJ?xd_I&U20m#7tTzIxgku&SLnwqhHD zTBFcrYd~w(Ee3|9s8(4uq=v0k#3pd%2gM4k&1oqM`Hezim^IEQb-(&F=b+B4k&C)T zIlN-qf3t@}oIb5Q1-j_|At#uQeI~eDQzh#R%x%V-Qe*Ter)8Fu-2w&Hs_(c{mc`{_wQHoox-&TFRjb)#Hs+SSENwpG<9_&n zb`xhwKH;2n-0b5-Cm$}AG8NrrQmrNIDIEEWna0Po3<)Y(wEg9ovO3rex18IqpKH41AekUS1pdYDX%vc--l^;_1{i z&vAQ}o5>*C2u~6RD!8OqnVHmw2s$D#Dr0IbH#SkdCRfibHOQ5FGIQDt5nOS(vu+$Q zl(lr_56hZ1%Y*AW&p)m`Ewe$-U7e&o9J_0>x4%8F$ZstDUZv5VQ`QG$*1j0=YCR8p zHG)P`(P&K@uGO9mNprKbGD&rbTj!B8k=V+)0nXx8-cBRZAw<^!|uS zayaBwGj1N6vdGdAO&Mg^SsblP6@{9m6Lr#TyHA~Tno^5BuUR^2uT$H^Wlh_i^^(=5 ziAl;Ho$WxS*MimTOg2Fo)q^;Fwqb7SpRBYQwqmVWWErO>k1X5vIH}$UesE&E*FI>Z zXK&@XEt@js|NkxY_s@aS|55Mt=PC65&%i8P4$pHz`T2`*1I)oY;R^U6X}@6dxPjv) zcoG}HC*TCsz=H))asRvFWo!aJg8N|wPQlgi3buit!`I5udx~233tFOY=(Eh+d;+g|1Y}zPvHUh6ZkZI3g$q-ufvbg^?w8pfr{PV3wz*Q z@H94n@4yrARk#^$fWO1ea2CD=UxTm0y>KVo0VKd>_66 zkH8Al;q7oKybUgdN3mJl3wOZBU>T0U7^wLEv)C}=Pi(DF$1TO!d_-Jn!%k?XePX3c z8MeAvlaj>EQE#y!sV{a-napJXw@A z^&}p8SFm@W@vToq-N)Co^>YG4r@bKAo~&x!q>U)(qjAzgBbSDCRM#^V2fA8FEZQ&m zArFyMM}#U4T)nKI1LwN6+SeiZqA#fMX6W|UCa^@Kc-jQkCF@jc zeR*aR?62!kif)bjW{tWa47JHGrC*L{bd%s?D!mIUrurIx%t((-$7{SnF>+*LV)*cZ zW1}A&8J$$`QEYESO2;vkNe^iYINe0|I4Y{F(M_r8bR%yC@aBdn%q8g|Ut)>;5N5PX#V;Vvs*|1Z4YzIn8_z8-|0t=Umqdu(wi7i(2E ztZ{#5E4pt!8YCGDS7QIg6})b7XD_y0)Qv*byfO<3?@J=u#%puQ5|vERLd%p*&BnI< z+eo}Hrj|3cx<#?|mMXW?ni4H@kz-2T(|DYlg*m#^@&;;RKS_*l8PX;yVXN`&wdB=o ze0wc9X)Sa885k{Z+*{yLl5D-wYjIlCE%Iz6ZnwF|qh<9MWIMeT8m;2%>(Ozqczo8a z@_(;&S1D(_<1(XLDoLJ2t4|VVuso@>8LcWRX%lj z&i^!g7w&_Pf{OkBIr{$Na2rg(<**4h!ujwo=>F;*fV<$cFb-G374Qst{~y8UU=B9J zRq#Xf{s-YpP=uW@0578N{~4(F|9u#Q-S9K?{U_jYcnrP*pNG5Q2#mqiunS&A_x}s{ z7TgY>g&BAw{4+ZLKfzNFfCCj!@A+>A3r?f^uYiOP!}YKq24Od-ScDDmW_TWZz_aiO zd@AH@oOetf-4 zKrQa^CpXdX23~9i2yzomZlYN=Mlm7d8tCK_#|&Zfmi>SS)B(UApK z^1x1X+q5+-H_>DpW4Vdu^<0Qb0q|z@5_A=%Q9p;!TfkK#-AKjecbL-ZYcd@> zS~sGUk!fm5R(lF=OQ%&Y8T4E#KW5ZJ3|3U!aMiJcZk7n#2w1~Jpd51jK}{B&GCzA& zjC{N6{53OOjA@GcH8UOmUqLs23Y7jI|GxiObp7Yxi=f{9pN5^V4YtBn@Dud?7vWL( zGMs^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;