X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModel%2FGroup.php;h=fa41d26467fc704034b706306a7ee81975b69467;hb=72a3ab6382551811f22391b7e82e7398628b235b;hp=c38e78000b6a25247625d5afacee96ca3aee87ab;hpb=ab8997f9db910ba70c592bf106a7f5fc41a55b2d;p=friendica.git diff --git a/src/Model/Group.php b/src/Model/Group.php index c38e78000b..fa41d26467 100644 --- a/src/Model/Group.php +++ b/src/Model/Group.php @@ -1,6 +1,22 @@ . + * */ namespace Friendica\Model; @@ -9,8 +25,11 @@ use Friendica\BaseModule; use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; +use Friendica\Database\Database; use Friendica\Database\DBA; use Friendica\DI; +use Friendica\Network\HTTPException; +use Friendica\Protocol\ActivityPub; /** * functions for interacting with the group database table @@ -22,7 +41,7 @@ class Group public static function getByUserId($uid, $includesDeleted = false) { - $conditions = ['uid' => $uid]; + $conditions = ['uid' => $uid, 'cid' => null]; if (!$includesDeleted) { $conditions['deleted'] = false; @@ -73,7 +92,7 @@ class Group $group = DBA::selectFirst('group', ['deleted'], ['id' => $gid]); if (DBA::isResult($group) && $group['deleted']) { DBA::update('group', ['deleted' => 0], ['id' => $gid]); - notice(DI::l10n()->t('A deleted group with this name was revived. Existing item permissions may apply to this group and any future members. If this is not what you intended, please create another group with a different name.') . EOL); + notice(DI::l10n()->t('A deleted group with this name was revived. Existing item permissions may apply to this group and any future members. If this is not what you intended, please create another group with a different name.')); } return true; } @@ -117,6 +136,16 @@ class Group } DBA::close($stmt); + // Meta-groups + $contact = Contact::getById($cid, ['rel']); + if ($contact['rel'] == Contact::FOLLOWER || $contact['rel'] == Contact::FRIEND) { + $return[] = self::FOLLOWERS; + } + + if ($contact['rel'] == Contact::FRIEND) { + $return[] = self::MUTUALS; + } + return $return; } @@ -134,7 +163,7 @@ class Group public static function countUnseen() { $stmt = DBA::p("SELECT `group`.`id`, `group`.`name`, - (SELECT COUNT(*) FROM `item` FORCE INDEX (`uid_unseen_contactid`) + (SELECT COUNT(*) FROM `post-user` WHERE `uid` = ? AND `unseen` AND `contact-id` IN @@ -226,89 +255,121 @@ class Group } /** - * Mark a group as deleted based on its name + * Adds a contact to a group * - * @param int $uid - * @param string $name - * @return bool + * @param int $gid + * @param int $cid + * @return boolean * @throws \Exception - * @deprecated Use Group::remove instead - * */ - public static function removeByName($uid, $name) + public static function addMember(int $gid, int $cid): bool { - $return = false; - if (!empty($uid) && !empty($name)) { - $gid = self::getIdByName($uid, $name); + if (!$gid || !$cid) { + return false; + } - $return = self::remove($gid); + // @TODO Backward compatibility with user contacts, remove by version 2022.03 + $group = DBA::selectFirst('group', ['uid'], ['id' => $gid]); + if (empty($group)) { + throw new HTTPException\NotFoundException('Group not found.'); } - return $return; + $cdata = Contact::getPublicAndUserContactID($cid, $group['uid']); + if (empty($cdata['user'])) { + throw new HTTPException\NotFoundException('Invalid contact.'); + } + + return DBA::insert('group_member', ['gid' => $gid, 'contact-id' => $cdata['user']], Database::INSERT_IGNORE); } /** - * Adds a contact to a group + * Removes a contact from a group * * @param int $gid * @param int $cid * @return boolean * @throws \Exception */ - public static function addMember($gid, $cid) + public static function removeMember(int $gid, int $cid): bool { if (!$gid || !$cid) { return false; } - $row_exists = DBA::exists('group_member', ['gid' => $gid, 'contact-id' => $cid]); - if ($row_exists) { - // Row already existing, nothing to do - $return = true; - } else { - $return = DBA::insert('group_member', ['gid' => $gid, 'contact-id' => $cid]); + // @TODO Backward compatibility with user contacts, remove by version 2022.03 + $group = DBA::selectFirst('group', ['uid'], ['id' => $gid]); + if (empty($group)) { + throw new HTTPException\NotFoundException('Group not found.'); } - return $return; + $cdata = Contact::getPublicAndUserContactID($cid, $group['uid']); + if (empty($cdata['user'])) { + throw new HTTPException\NotFoundException('Invalid contact.'); + } + + return DBA::delete('group_member', ['gid' => $gid, 'contact-id' => $cid]); } /** - * Removes a contact from a group + * Adds contacts to a group * * @param int $gid - * @param int $cid - * @return boolean + * @param array $contacts * @throws \Exception */ - public static function removeMember($gid, $cid) + public static function addMembers(int $gid, array $contacts) { - if (!$gid || !$cid) { + if (!$gid || !$contacts) { return false; } - $return = DBA::delete('group_member', ['gid' => $gid, 'contact-id' => $cid]); + // @TODO Backward compatibility with user contacts, remove by version 2022.03 + $group = DBA::selectFirst('group', ['uid'], ['id' => $gid]); + if (empty($group)) { + throw new HTTPException\NotFoundException('Group not found.'); + } + + foreach ($contacts as $cid) { + $cdata = Contact::getPublicAndUserContactID($cid, $group['uid']); + if (empty($cdata['user'])) { + throw new HTTPException\NotFoundException('Invalid contact.'); + } - return $return; + DBA::insert('group_member', ['gid' => $gid, 'contact-id' => $cdata['user']], Database::INSERT_IGNORE); + } } /** - * Removes a contact from a group based on its name + * Removes contacts from a group * - * @param int $uid - * @param string $name - * @param int $cid - * @return boolean + * @param int $gid + * @param array $contacts * @throws \Exception - * @deprecated Use Group::removeMember instead - * */ - public static function removeMemberByName($uid, $name, $cid) + public static function removeMembers(int $gid, array $contacts) { - $gid = self::getIdByName($uid, $name); + if (!$gid || !$contacts) { + return false; + } + + // @TODO Backward compatibility with user contacts, remove by version 2022.03 + $group = DBA::selectFirst('group', ['uid'], ['id' => $gid]); + if (empty($group)) { + throw new HTTPException\NotFoundException('Group not found.'); + } - $return = self::removeMember($gid, $cid); + $contactIds = []; - return $return; + foreach ($contacts as $cid) { + $cdata = Contact::getPublicAndUserContactID($cid, $group['uid']); + if (empty($cdata['user'])) { + throw new HTTPException\NotFoundException('Invalid contact.'); + } + + $contactIds[] = $cdata['user']; + } + + DBA::delete('group_member', ['gid' => $gid, 'contact-id' => $contactIds]); } /** @@ -409,7 +470,7 @@ class Group ] ]; - $stmt = DBA::select('group', [], ['deleted' => 0, 'uid' => $uid], ['order' => ['name']]); + $stmt = DBA::select('group', [], ['deleted' => false, 'uid' => $uid, 'cid' => null], ['order' => ['name']]); while ($group = DBA::fetch($stmt)) { $display_groups[] = [ 'name' => $group['name'], @@ -466,7 +527,7 @@ class Group $member_of = self::getIdsByContactId($cid); } - $stmt = DBA::select('group', [], ['deleted' => 0, 'uid' => local_user()], ['order' => ['name']]); + $stmt = DBA::select('group', [], ['deleted' => false, 'uid' => local_user(), 'cid' => null], ['order' => ['name']]); while ($group = DBA::fetch($stmt)) { $selected = (($group_id == $group['id']) ? ' group-selected' : ''); @@ -479,10 +540,17 @@ class Group $groupedit = null; } + if ($each == 'group') { + $count = DBA::count('group_member', ['gid' => $group['id']]); + $group_name = sprintf('%s (%d)', $group['name'], $count); + } else { + $group_name = $group['name']; + } + $display_groups[] = [ 'id' => $group['id'], 'cid' => $cid, - 'text' => $group['name'], + 'text' => $group_name, 'href' => $each . '/' . $group['id'], 'edit' => $groupedit, 'selected' => $selected, @@ -514,4 +582,79 @@ class Group return $o; } + + /** + * Fetch the group id for the given contact id + * + * @param integer $id Contact ID + * @return integer Group IO + */ + public static function getIdForForum(int $id) + { + Logger::info('Get id for forum id', ['id' => $id]); + $contact = Contact::getById($id, ['uid', 'name', 'contact-type', 'manually-approve']); + if (empty($contact) || ($contact['contact-type'] != Contact::TYPE_COMMUNITY) || !$contact['manually-approve']) { + return 0; + } + + $group = DBA::selectFirst('group', ['id'], ['uid' => $contact['uid'], 'cid' => $id]); + if (empty($group)) { + $fields = [ + 'uid' => $contact['uid'], + 'name' => $contact['name'], + 'cid' => $id, + ]; + DBA::insert('group', $fields); + $gid = DBA::lastInsertId(); + } else { + $gid = $group['id']; + } + + return $gid; + } + + /** + * Fetch the followers of a given contact id and store them as group members + * + * @param integer $id Contact ID + */ + public static function updateMembersForForum(int $id) + { + Logger::info('Update forum members', ['id' => $id]); + + $contact = Contact::getById($id, ['uid', 'url']); + if (empty($contact)) { + return; + } + + $apcontact = APContact::getByURL($contact['url']); + if (empty($apcontact['followers'])) { + return; + } + + $gid = self::getIdForForum($id); + if (empty($gid)) { + return; + } + + $group_members = DBA::selectToArray('group_member', ['contact-id'], ['gid' => $gid]); + if (!empty($group_members)) { + $current = array_unique(array_column($group_members, 'contact-id')); + } else { + $current = []; + } + + foreach (ActivityPub::fetchItems($apcontact['followers'], $contact['uid']) as $follower) { + $id = Contact::getIdForURL($follower); + if (!in_array($id, $current)) { + DBA::insert('group_member', ['gid' => $gid, 'contact-id' => $id]); + } else { + $key = array_search($id, $current); + unset($current[$key]); + } + } + + DBA::delete('group_member', ['gid' => $gid, 'contact-id' => $current]); + Logger::info('Updated forum members', ['id' => $id, 'count' => DBA::count('group_member', ['gid' => $gid])]); + } }