Skip to content

Commit 2fd85a3

Browse files
authored
Merge pull request #48 from topcoder-platform/issues-318
Issues-318: Added API to get\patch a group member
2 parents ea1ea67 + e5a2703 commit 2fd85a3

File tree

3 files changed

+249
-84
lines changed

3 files changed

+249
-84
lines changed

controllers/api/GroupsApiController.php

Lines changed: 113 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@ class GroupsApiController extends AbstractApiController {
2121
/** @var CategoryModel */
2222
private $categoryModel;
2323

24-
/** @var Schema */
2524
private $groupSchema;
2625

27-
/** @var Schema */
2826
private $groupPostSchema;
2927

30-
/** @var Schema */
3128
private $groupMemberPostSchema;
29+
30+
private $groupMemberDetailsSchema;
3231
/**
3332
* GroupsApiController constructor.
3433
*
@@ -206,8 +205,10 @@ public function post_members($id, array $body) {
206205
* Get all members of a group.
207206
*
208207
* @param int $id The ID of the group.
208+
* @param array $query
209+
* @return Data
210+
* @throws ClientException
209211
* @throws NotFoundException if the group could not be found.
210-
* @return array
211212
*/
212213
public function get_members($id, array $query) {
213214
$this->permission();
@@ -255,6 +256,7 @@ public function get_members($id, array $query) {
255256
* @return
256257
*/
257258
public function put_archive($id, array $body) {
259+
$this->permission('Groups.Group.Archive');
258260
$this->idParamSchema();
259261

260262
$group = $this->groupModel->getByGroupID($id);
@@ -277,8 +279,7 @@ public function put_archive($id, array $body) {
277279
* @param int $userid The Vanilla User ID of the user
278280
* @throws NotFoundException if the group or user could not be found.
279281
*/
280-
public function delete_members($id, $userid) {
281-
282+
public function delete_member($id, $userid) {
282283
$this->idUserIdParamSchema()->setDescription('Remove a member from a group.');
283284
$this->schema([], 'out');
284285

@@ -299,6 +300,78 @@ public function delete_members($id, $userid) {
299300
$this->groupModel->removeMember($group->GroupID, $user->UserID);
300301
}
301302

303+
/**
304+
* Update follow/watch status for a member
305+
*
306+
* @param int $id The groupID of the group
307+
* @param int $userid The Vanilla User ID of the user
308+
* @throws NotFoundException if the group or user could not be found.
309+
*/
310+
public function patch_member($id, $userid, array $body) {
311+
$this->permission('Groups.Group.Edit');
312+
$in = $this->groupMemberPatchSchema();
313+
$user = Gdn::userModel()->getID($userid);
314+
if(!$user) {
315+
throw new NotFoundException('User');
316+
}
317+
318+
$group = $this->groupModel->getByGroupID($id);
319+
if(!$group) {
320+
throw new NotFoundException('Group');
321+
}
322+
323+
$isMember = $this->groupModel->isMemberOfGroup($user->UserID, $group->GroupID);
324+
if(!$isMember) {
325+
throw new ClientException('User is not a member of this group');
326+
}
327+
328+
$body = $in->validate($body);
329+
if(!array_key_exists('follow', $body) && !array_key_exists('watch', $body)) {
330+
throw new ClientException('At least one parameter must be set');
331+
}
332+
333+
if(array_key_exists('follow', $body)) {
334+
$follow = $body['follow'];
335+
$this->groupModel->followGroup($group, $user->UserID, $follow);
336+
}
337+
if(array_key_exists('watch', $body)) {
338+
$watch = $body['watch'];
339+
$this->groupModel->watchGroup($group, $user->UserID, $watch);
340+
}
341+
}
342+
343+
/**
344+
* Get Member details
345+
*
346+
* @param int $id The groupID of the group
347+
* @param int $userid The Vanilla User ID of the user
348+
* @throws NotFoundException if the group or user could not be found.
349+
*/
350+
public function get_member($id, $userid) {
351+
$this->permission();
352+
$user = Gdn::userModel()->getID($userid);
353+
if(!$user) {
354+
throw new NotFoundException('User');
355+
}
356+
357+
$group = $this->groupModel->getByGroupID($id);
358+
if(!$group) {
359+
throw new NotFoundException('Group');
360+
}
361+
362+
$isMember = $this->groupModel->isMemberOfGroup($user->UserID, $group->GroupID);
363+
if(!$isMember) {
364+
throw new ClientException('User is not a member of this group');
365+
}
366+
367+
$hasFollowed = $this->groupModel->hasFollowedGroup($group, $user->UserID);
368+
$hasWatched = $this->groupModel->hasWatchedGroup($group, $user->UserID);
369+
$record = ['userID' => $user->UserID, 'follow' => $hasFollowed, 'watch' => $hasWatched];
370+
$out = $this->schema($this->groupMemberDetailsSchema('out'));
371+
$result = $out->validate($record);
372+
return $result;
373+
}
374+
302375
/**
303376
* Get a post schema with minimal add/edit fields.
304377
*
@@ -320,7 +393,40 @@ public function groupMemberPostSchema($type) {
320393
}
321394

322395
/**
323-
* Get a GroupID/UserID -only conversation record schema.
396+
* Get a Member Details schema.
397+
*
398+
* @param string $type The type of schema.
399+
* @return Schema Returns a schema object.
400+
*/
401+
public function groupMemberDetailsSchema($type) {
402+
if ($this->groupMemberDetailsSchema === null) {
403+
$this->groupMemberDetailsSchema = $this->schema(
404+
Schema::parse([
405+
'userID:i' => 'The userID.',
406+
'watch:b' => 'Watch status',
407+
'follow:b' => 'Follow status',
408+
]),
409+
'GroupMemberDetails'
410+
);
411+
}
412+
return $this->schema($this->groupMemberDetailsSchema, $type);
413+
}
414+
415+
/**
416+
* Get Group Member Patch schema.
417+
*
418+
* @param string $type The type of schema.
419+
* @return Schema Returns a schema object.
420+
*/
421+
public function groupMemberPatchSchema() {
422+
return $this->schema(
423+
['watch:b?' => 'Watch status',
424+
'follow:b?' => 'Follow status',
425+
], 'in');
426+
}
427+
428+
/**
429+
* Get a GroupID/UserID - only conversation record schema.
324430
*
325431
* @return Schema Returns a schema object.
326432
*/

models/class.groupmodel.php

Lines changed: 59 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,9 @@ public function accept($groupID, $userID){
861861

862862
/**
863863
* Return true if user is a member of the group
864-
*
864+
* @param $userID
865+
* @param $groupID
866+
* @return bool
865867
*/
866868
public function isMemberOfGroup($userID, $groupID) {
867869
$groups = $this->memberOf($userID);
@@ -1188,32 +1190,22 @@ public function canFollowGroup($group) {
11881190
}
11891191

11901192
/**
1191-
* Check if the current user has followed at least one group category
1192-
*
1193+
* Check if a user has followed at least one group category
1194+
* @param $group
1195+
* @param null $userID if userID is not set, the current user is used
1196+
* @return bool
11931197
*/
1194-
public function hasFollowedGroup($group) {
1195-
if($group->ChallengeID) {
1196-
$categoryModel = new CategoryModel();
1197-
$groupCategory = $categoryModel->getByCode($group->ChallengeID);
1198-
1199-
if($groupCategory->DisplayAs !== 'Discussions') {
1200-
$categories = CategoryModel::getSubtree($groupCategory->CategoryID, false);
1201-
$categoryIDs = array_column($categories, 'CategoryID');
1202-
} else {
1203-
$categoryIDs = [$groupCategory->CategoryID];
1204-
}
1205-
1206-
$where['Followed'] = true;
1207-
$where['CategoryID'] = $categoryIDs;
1208-
1209-
$result = $categoryModel
1210-
->getWhere($where)
1211-
->resultArray();
1212-
1213-
return count($result) > 0;
1198+
public function hasFollowedGroup($group, $userID = null) {
1199+
if(!$userID) {
1200+
$userID = Gdn::session()->UserID;
12141201
}
12151202

1216-
return false;
1203+
$categories = Gdn::sql()->getWhere('Category', ['GroupID' => $group->GroupID, 'DisplayAs' => 'Discussions'])->resultArray();
1204+
$categoryIDs = array_column($categories, 'CategoryID');
1205+
$result = Gdn::sql()->getWhere('UserCategory', ['UserID' => $userID, 'Followed' => 1, 'CategoryID' => $categoryIDs])
1206+
->resultArray();
1207+
1208+
return count($result) > 0;
12171209
}
12181210

12191211
/**
@@ -1230,26 +1222,19 @@ public function canWatchGroup($group) {
12301222
}
12311223

12321224
/**
1233-
* Check if the current user has watched at least one group category
1225+
* Check if an user has watched at least one group category
12341226
* @param $group
1227+
* @param null $userID if userID is not set then the current user is used
12351228
* @return bool User has watched at least one group category
12361229
*/
1237-
public function hasWatchedGroup($group) {
1238-
if($group->ChallengeID) {
1239-
$categoryModel = new CategoryModel();
1240-
$groupCategory = $categoryModel->getByCode($group->ChallengeID);
1241-
1242-
if($groupCategory->DisplayAs !== 'Discussions') {
1243-
$categories = CategoryModel::getSubtree($groupCategory->CategoryID, false);
1244-
$categoryIDs = array_column($categories, 'CategoryID');
1245-
} else {
1246-
$categoryIDs = [$groupCategory->CategoryID];
1247-
}
1248-
1249-
return $categoryModel->hasWatched($categoryIDs,Gdn::session()->UserID);
1230+
public function hasWatchedGroup($group, $userID = null) {
1231+
if(!$userID) {
1232+
$userID = Gdn::session()->UserID;
12501233
}
1251-
1252-
return false;
1234+
$categoryModel = new CategoryModel();
1235+
$categories = Gdn::sql()->getWhere('Category', ['GroupID' => $group->GroupID, 'DisplayAs' => 'Discussions'])->resultArray();
1236+
$categoryIDs = array_column($categories, 'CategoryID');
1237+
return $categoryModel->hasWatched($categoryIDs,$userID);
12531238
}
12541239

12551240
/**
@@ -1262,20 +1247,19 @@ public function followGroup($group, $userID, $followed = true ) {
12621247
if(is_numeric($group) && $group > 0) {
12631248
$group = $this->getByGroupID($group);
12641249
}
1265-
if($group->ChallengeID) {
1266-
$categories = Gdn::sql()->getWhere('Category', ['GroupID' => $group->GroupID, 'DisplayAs' => 'Discussions'])->resultArray();
1267-
$categoryIDs = array_column($categories, 'CategoryID');
12681250

1269-
foreach($categoryIDs as $categoryID) {
1270-
$this->SQL->replace(
1271-
'UserCategory',
1272-
['Followed' => (int)$followed],
1273-
['UserID' => $userID, 'CategoryID' => $categoryID]
1274-
);
1275-
}
1276-
CategoryModel::clearUserCache($userID);
1277-
Gdn::cache()->remove("Follow_{$userID}");
1251+
$categories = Gdn::sql()->getWhere('Category', ['GroupID' => $group->GroupID, 'DisplayAs' => 'Discussions'])->resultArray();
1252+
$categoryIDs = array_column($categories, 'CategoryID');
1253+
1254+
foreach($categoryIDs as $categoryID) {
1255+
$this->SQL->replace(
1256+
'UserCategory',
1257+
['Followed' => (int)$followed],
1258+
['UserID' => $userID, 'CategoryID' => $categoryID]
1259+
);
12781260
}
1261+
CategoryModel::clearUserCache($userID);
1262+
Gdn::cache()->remove("Follow_{$userID}");
12791263
}
12801264

12811265
/**
@@ -1298,33 +1282,32 @@ public function watchGroup($group, $userID, $watched = true) {
12981282
$group = $this->getByGroupID($group);
12991283
}
13001284

1301-
if($group->ChallengeID) {
1302-
$categories = Gdn::sql()->getWhere('Category', ['GroupID' => $group->GroupID, 'DisplayAs' => 'Discussions'])->resultArray();
1303-
$categoryIDs = array_column($categories, 'CategoryID');
1304-
// Don't use setCategoryMetaData due to cache
1305-
$metaKeys = ['Preferences.Email.NewComment.',
1306-
'Preferences.Email.NewDiscussion.',
1307-
'Preferences.Popup.NewComment.',
1308-
'Preferences.Popup.NewDiscussion.'];
1309-
foreach($categoryIDs as $categoryID) {
1310-
foreach ($metaKeys as $metaKey) {
1311-
if($watched) {
1312-
$this->SQL->replace(
1313-
'UserMeta',
1314-
[ 'Value' => (int)$watched],
1315-
[ 'UserID' => $userID, 'Name' => $metaKey . $categoryID,]
1316-
);
1317-
} else {
1318-
Gdn::sql()->delete('UserMeta', [
1319-
'UserID' => $userID,
1320-
'Name' => $metaKey . $categoryID
1321-
]);
1322-
}
1285+
$categories = Gdn::sql()->getWhere('Category', ['GroupID' => $group->GroupID, 'DisplayAs' => 'Discussions'])->resultArray();
1286+
$categoryIDs = array_column($categories, 'CategoryID');
1287+
// Don't use setCategoryMetaData due to cache
1288+
$metaKeys = ['Preferences.Email.NewComment.',
1289+
'Preferences.Email.NewDiscussion.',
1290+
'Preferences.Popup.NewComment.',
1291+
'Preferences.Popup.NewDiscussion.'];
1292+
foreach($categoryIDs as $categoryID) {
1293+
foreach ($metaKeys as $metaKey) {
1294+
if($watched) {
1295+
$this->SQL->replace(
1296+
'UserMeta',
1297+
[ 'Value' => (int)$watched],
1298+
[ 'UserID' => $userID, 'Name' => $metaKey . $categoryID,]
1299+
);
1300+
} else {
1301+
Gdn::sql()->delete('UserMeta', [
1302+
'UserID' => $userID,
1303+
'Name' => $metaKey . $categoryID
1304+
]);
13231305
}
13241306
}
1325-
CategoryModel::clearUserCache($userID);
1326-
Gdn::cache()->remove("UserMeta_{$userID}");
13271307
}
1308+
CategoryModel::clearUserCache($userID);
1309+
Gdn::cache()->remove("UserMeta_{$userID}");
1310+
13281311
}
13291312

13301313
/**

0 commit comments

Comments
 (0)