@@ -980,11 +980,22 @@ public function updateDocument(Document $collection, string $id, Document $docum
980980 $ attributes ['_createdAt ' ] = $ document ->getCreatedAt ();
981981 $ attributes ['_updatedAt ' ] = $ document ->getUpdatedAt ();
982982 $ attributes ['_permissions ' ] = json_encode ($ document ->getPermissions ());
983+ $ attributes ['_uid ' ] = $ document ->getId ();
983984
984985 $ name = $ this ->filter ($ collection );
985986 $ columns = '' ;
986987
987988 if (!$ skipPermissions ) {
989+ /**
990+ * Permission rows in the _perms table are keyed by the document's
991+ * UID (the _document column). When the UID changes, the existing
992+ * rows must be re-pointed to the new UID before the diff below is
993+ * applied, otherwise the old rows are orphaned and unchanged
994+ * permissions are lost for the new UID.
995+ */
996+ $ newUid = $ document ->offsetExists ('$id ' ) ? $ document ->getId () : $ id ;
997+ $ uidChanged = $ newUid !== $ id ;
998+
988999 $ sql = "
9891000 SELECT _type, _permission
9901001 FROM {$ this ->getSQLTable ($ name . '_perms ' )}
@@ -998,7 +1009,8 @@ public function updateDocument(Document $collection, string $id, Document $docum
9981009 * Get current permissions from the database
9991010 */
10001011 $ sqlPermissions = $ this ->getPDO ()->prepare ($ sql );
1001- $ sqlPermissions ->bindValue (':_uid ' , $ document ->getId ());
1012+
1013+ $ sqlPermissions ->bindValue (':_uid ' , $ id );
10021014
10031015 if ($ this ->sharedTables ) {
10041016 $ sqlPermissions ->bindValue (':_tenant ' , $ this ->tenant );
@@ -1041,6 +1053,26 @@ public function updateDocument(Document $collection, string $id, Document $docum
10411053 }
10421054 }
10431055
1056+ /**
1057+ * Query to re-point existing permissions to the new UID
1058+ */
1059+ if ($ uidChanged ) {
1060+ $ sql = "
1061+ UPDATE {$ this ->getSQLTable ($ name . '_perms ' )}
1062+ SET _document = :_newUid
1063+ WHERE _document = :_uid
1064+ {$ this ->getTenantQuery ($ collection )}
1065+ " ;
1066+
1067+ $ stmtRepointPermissions = $ this ->getPDO ()->prepare ($ sql );
1068+ $ stmtRepointPermissions ->bindValue (':_uid ' , $ id );
1069+ $ stmtRepointPermissions ->bindValue (':_newUid ' , $ newUid );
1070+
1071+ if ($ this ->sharedTables ) {
1072+ $ stmtRepointPermissions ->bindValue (':_tenant ' , $ this ->tenant );
1073+ }
1074+ }
1075+
10441076 /**
10451077 * Query to remove permissions
10461078 */
@@ -1071,7 +1103,7 @@ public function updateDocument(Document $collection, string $id, Document $docum
10711103 $ removeQuery = $ this ->trigger (Database::EVENT_PERMISSIONS_DELETE , $ removeQuery );
10721104
10731105 $ stmtRemovePermissions = $ this ->getPDO ()->prepare ($ removeQuery );
1074- $ stmtRemovePermissions ->bindValue (':_uid ' , $ document -> getId () );
1106+ $ stmtRemovePermissions ->bindValue (':_uid ' , $ newUid );
10751107
10761108 if ($ this ->sharedTables ) {
10771109 $ stmtRemovePermissions ->bindValue (':_tenant ' , $ this ->tenant );
@@ -1119,7 +1151,7 @@ public function updateDocument(Document $collection, string $id, Document $docum
11191151
11201152 $ stmtAddPermissions = $ this ->getPDO ()->prepare ($ sql );
11211153
1122- $ stmtAddPermissions ->bindValue (":_uid " , $ document -> getId () );
1154+ $ stmtAddPermissions ->bindValue (":_uid " , $ newUid );
11231155
11241156 if ($ this ->sharedTables ) {
11251157 $ stmtAddPermissions ->bindValue (":_tenant " , $ this ->tenant );
@@ -1168,7 +1200,7 @@ public function updateDocument(Document $collection, string $id, Document $docum
11681200
11691201 $ sql = "
11701202 UPDATE {$ this ->getSQLTable ($ name )}
1171- SET { $ columns} _uid = :_newUid
1203+ SET " . \rtrim ( $ columns, ' , ' ) . "
11721204 WHERE _id=:_sequence
11731205 {$ this ->getTenantQuery ($ collection )}
11741206 " ;
@@ -1178,7 +1210,6 @@ public function updateDocument(Document $collection, string $id, Document $docum
11781210 $ stmt = $ this ->getPDO ()->prepare ($ sql );
11791211
11801212 $ stmt ->bindValue (':_sequence ' , $ document ->getSequence ());
1181- $ stmt ->bindValue (':_newUid ' , $ document ->getId ());
11821213
11831214 if ($ this ->sharedTables ) {
11841215 $ stmt ->bindValue (':_tenant ' , $ this ->tenant );
@@ -1209,6 +1240,9 @@ public function updateDocument(Document $collection, string $id, Document $docum
12091240
12101241 $ stmt ->execute ();
12111242
1243+ if (isset ($ stmtRepointPermissions )) {
1244+ $ stmtRepointPermissions ->execute ();
1245+ }
12121246 if (isset ($ stmtRemovePermissions )) {
12131247 $ stmtRemovePermissions ->execute ();
12141248 }
0 commit comments