1616use OCA \Circles \Model \Probes \CircleProbe ;
1717use OCP \App \IAppManager ;
1818use OCP \Server ;
19+ use Psr \Log \LoggerInterface ;
1920use Throwable ;
2021
2122/**
@@ -29,7 +30,7 @@ class CirclesService {
2930 /** @var array<string, string[]> */
3031 private array $ userCirclesCache = [];
3132
32- public function __construct (IAppManager $ appManager ) {
33+ public function __construct (IAppManager $ appManager, private ? LoggerInterface $ logger = null ) {
3334 $ this ->circlesEnabled = $ appManager ->isEnabledForUser ('circles ' );
3435 }
3536
@@ -43,12 +44,19 @@ public function getCircle(string $circleId): ?Circle {
4344 }
4445
4546 try {
46-
4747 // Enforce current user condition since we always want the full list of members
48- $ circlesManager = Server:: get (CirclesManager::class );
48+ $ circlesManager = $ this -> getCirclesManager ( );
4949 $ circlesManager ->startSuperSession ();
50- return $ circlesManager ->getCircle ($ circleId );
50+ try {
51+ return $ circlesManager ->getCircle ($ circleId );
52+ } finally {
53+ $ this ->stopSessionSafely ($ circlesManager , 'getCircle ' );
54+ }
5155 } catch (Throwable $ e ) {
56+ $ this ->logger ?->debug('CirclesService::getCircle failed ' , [
57+ 'circleId ' => $ circleId ,
58+ 'exception ' => $ e ,
59+ ]);
5260 }
5361 return null ;
5462 }
@@ -63,12 +71,16 @@ public function isUserInCircle(string $circleId, string $userId): bool {
6371 }
6472
6573 try {
66- $ circlesManager = Server:: get (CirclesManager::class );
74+ $ circlesManager = $ this -> getCirclesManager ( );
6775 $ federatedUser = $ circlesManager ->getFederatedUser ($ userId , Member::TYPE_USER );
6876 $ circlesManager ->startSession ($ federatedUser );
69- $ circle = $ circlesManager ->getCircle ($ circleId );
70- $ member = $ circle ->getInitiator ();
71- $ isUserInCircle = $ member ->getLevel () >= Member::LEVEL_MEMBER ;
77+ try {
78+ $ circle = $ circlesManager ->getCircle ($ circleId );
79+ $ member = $ circle ->getInitiator ();
80+ $ isUserInCircle = $ member ->getLevel () >= Member::LEVEL_MEMBER ;
81+ } finally {
82+ $ this ->stopSessionSafely ($ circlesManager , 'isUserInCircle ' );
83+ }
7284
7385 if (!isset ($ this ->userCircleCache [$ circleId ])) {
7486 $ this ->userCircleCache [$ circleId ] = [];
@@ -77,6 +89,11 @@ public function isUserInCircle(string $circleId, string $userId): bool {
7789
7890 return $ isUserInCircle ;
7991 } catch (Throwable $ e ) {
92+ $ this ->logger ?->debug('CirclesService::isUserInCircle failed ' , [
93+ 'circleId ' => $ circleId ,
94+ 'userId ' => $ userId ,
95+ 'exception ' => $ e ,
96+ ]);
8097 }
8198 return false ;
8299 }
@@ -95,18 +112,87 @@ public function getUserCircles(string $userId): array {
95112 }
96113
97114 try {
98- $ circlesManager = Server:: get (CirclesManager::class );
115+ $ circlesManager = $ this -> getCirclesManager ( );
99116 $ federatedUser = $ circlesManager ->getFederatedUser ($ userId , Member::TYPE_USER );
100117 $ circlesManager ->startSession ($ federatedUser );
101- $ probe = new CircleProbe ();
102- $ probe ->mustBeMember ();
103- $ circles = array_map (function (Circle $ circle ) {
104- return $ circle ->getSingleId ();
105- }, $ circlesManager ->getCircles ($ probe ));
118+ try {
119+ $ probe = new CircleProbe ();
120+ $ probe ->mustBeMember ();
121+ $ circles = array_map (function (Circle $ circle ) {
122+ return $ circle ->getSingleId ();
123+ }, $ circlesManager ->getCircles ($ probe ));
124+ } finally {
125+ $ this ->stopSessionSafely ($ circlesManager , 'getUserCircles ' );
126+ }
106127 $ this ->userCirclesCache [$ userId ] = $ circles ;
107128 return $ circles ;
108129 } catch (Throwable $ e ) {
130+ $ this ->logger ?->debug('CirclesService::getUserCircles failed ' , [
131+ 'userId ' => $ userId ,
132+ 'exception ' => $ e ,
133+ ]);
109134 }
110135 return [];
111136 }
137+
138+ public function clearUserCircleCache (?string $ circleId = null , ?string $ userId = null ): void {
139+ if ($ circleId === null && $ userId === null ) {
140+ $ this ->userCircleCache = [];
141+ return ;
142+ }
143+
144+ if ($ circleId !== null && $ userId === null ) {
145+ unset($ this ->userCircleCache [$ circleId ]);
146+ return ;
147+ }
148+
149+ if ($ circleId !== null && $ userId !== null ) {
150+ unset($ this ->userCircleCache [$ circleId ][$ userId ]);
151+ if (empty ($ this ->userCircleCache [$ circleId ])) {
152+ unset($ this ->userCircleCache [$ circleId ]);
153+ }
154+ return ;
155+ }
156+
157+ foreach ($ this ->userCircleCache as $ cachedCircleId => $ users ) {
158+ unset($ users [$ userId ]);
159+ if (empty ($ users )) {
160+ unset($ this ->userCircleCache [$ cachedCircleId ]);
161+ continue ;
162+ }
163+ $ this ->userCircleCache [$ cachedCircleId ] = $ users ;
164+ }
165+ }
166+
167+ public function clearUserCirclesCache (?string $ userId = null ): void {
168+ if ($ userId === null ) {
169+ $ this ->userCirclesCache = [];
170+ return ;
171+ }
172+
173+ unset($ this ->userCirclesCache [$ userId ]);
174+ }
175+
176+ public function clearAllCaches (): void {
177+ $ this ->clearUserCircleCache ();
178+ $ this ->clearUserCirclesCache ();
179+ }
180+
181+ protected function getCirclesManager (): CirclesManager {
182+ return Server::get (CirclesManager::class);
183+ }
184+
185+ private function stopSessionSafely (CirclesManager $ circlesManager , string $ method ): void {
186+ if (!method_exists ($ circlesManager , 'stopSession ' )) {
187+ return ;
188+ }
189+
190+ try {
191+ $ circlesManager ->stopSession ();
192+ } catch (Throwable $ e ) {
193+ $ this ->logger ?->debug('CirclesService:: ' . $ method . ' stopSession failed ' , [
194+ 'exception ' => $ e ,
195+ ]);
196+ }
197+ }
112198}
0 commit comments