1111
1212namespace OCA \Circles \Listeners \Files ;
1313
14+ use OCA \Circles \Db \MemberRequest ;
15+ use OCA \Circles \Db \MountRequest ;
1416use OCA \Circles \Events \RemovingCircleMemberEvent ;
1517use OCA \Circles \Exceptions \MembershipNotFoundException ;
1618use OCA \Circles \Model \Member ;
@@ -31,17 +33,23 @@ class RemovingMember implements IEventListener {
3133 private MemberService $ memberService ;
3234 private ShareTokenService $ shareTokenService ;
3335 private ShareWrapperService $ shareWrapperService ;
36+ private MemberRequest $ memberRequest ;
37+ private MountRequest $ mountRequest ;
3438
3539 public function __construct (
3640 LoggerInterface $ logger ,
3741 MemberService $ memberService ,
3842 ShareTokenService $ shareTokenService ,
3943 ShareWrapperService $ shareWrapperService ,
44+ MemberRequest $ memberRequest ,
45+ MountRequest $ mountRequest ,
4046 ) {
4147 $ this ->logger = $ logger ;
4248 $ this ->memberService = $ memberService ;
4349 $ this ->shareTokenService = $ shareTokenService ;
4450 $ this ->shareWrapperService = $ shareWrapperService ;
51+ $ this ->memberRequest = $ memberRequest ;
52+ $ this ->mountRequest = $ mountRequest ;
4553 }
4654
4755 public function handle (Event $ event ): void {
@@ -78,11 +86,50 @@ function (Membership $membership) {
7886
7987 if ($ member ->getUserType () === Member::TYPE_USER ) {
8088 $ this ->removingSharesInternalMember ($ member , $ singleIds );
89+ $ this ->removingMountsIfLastLocalMember ($ member , $ singleIds );
8190 }
8291 }
8392 }
8493
8594
95+ /**
96+ * A circle mount is created on the local instance when a file or folder is
97+ * shared on the remote instance with a circle that lives there but also has
98+ * members on the local instance. This mount is used by every member of the
99+ * local instance who belongs to that remote circle.
100+ *
101+ * Removing a share on a remote circle only propagates to instances that still
102+ * have a member in that circle. Once the last local member leaves, the local
103+ * instance stops receiving that propagation, so we have to remove the mount
104+ * at this point.
105+ *
106+ * We have to iterate through every parent circle this member's circle belongs
107+ * to, checking for circles where this member leaving would be the last local
108+ * member leaving that circle, and thus where the mount must be removed.
109+ *
110+ * @param Member $member the member being removed
111+ * @param string[] $singleIds parent circles this member's circle belongs to
112+ */
113+ private function removingMountsIfLastLocalMember (Member $ member , array $ singleIds ): void {
114+ if (!$ member ->isLocal ()) {
115+ return ;
116+ }
117+
118+ foreach ($ singleIds as $ singleId ) {
119+ if (!$ this ->mountRequest ->hasMountForCircleId ($ singleId )) {
120+ continue ;
121+ }
122+
123+ foreach ($ this ->memberRequest ->getInheritedMembers ($ singleId ) as $ remainingMember ) {
124+ if ($ remainingMember ->getUserType () === Member::TYPE_USER && $ remainingMember ->isLocal ()) {
125+ continue 2 ;
126+ }
127+ }
128+
129+ $ this ->mountRequest ->deleteByCircleId ($ singleId );
130+ }
131+ }
132+
86133 /**
87134 * @param Member $member
88135 * @param string[] $singleIds
0 commit comments