mirror of
https://github.com/Bigherollc/wticreatorstudio.git
synced 2026-07-14 18:02:01 -04:00
558 lines
17 KiB
PHP
558 lines
17 KiB
PHP
<?php
|
|
|
|
namespace Modules\Chat\Repositories;
|
|
|
|
use App\Events\AddedToGroupEvent;
|
|
use App\Events\GroupCreated;
|
|
use App\Events\GroupEvent;
|
|
use App\Events\UserEvent;
|
|
use Modules\Chat\Entities\Conversation;
|
|
use Modules\Chat\Entities\Group;
|
|
use Modules\Chat\Entities\GroupMessageRecipient;
|
|
use Modules\Chat\Entities\GroupUser;
|
|
use Modules\Chat\Entities\LastConversation;
|
|
use Modules\Chat\Entities\User;
|
|
use App\Traits\ImageTrait;
|
|
use Arr;
|
|
use Auth;
|
|
use Carbon\Carbon;
|
|
use Exception;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Collection;
|
|
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
|
|
|
class GroupRepository extends BaseRepository
|
|
{
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $fieldSearchable = [
|
|
'name', 'description', 'photo', 'group_type', 'privacy',
|
|
];
|
|
|
|
/**
|
|
* Return searchable fields.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getFieldsSearchable()
|
|
{
|
|
return $this->fieldSearchable;
|
|
}
|
|
|
|
/**
|
|
* Configure the Model.
|
|
**/
|
|
public function model()
|
|
{
|
|
return Group::class;
|
|
}
|
|
|
|
/**
|
|
* @param array $search
|
|
* @param int|null $skip
|
|
* @param int|null $limit
|
|
* @param array $columns
|
|
*
|
|
* @return Group[]|Collection
|
|
*/
|
|
public function all($search = [], $skip = null, $limit = null, $columns = ['*'])
|
|
{
|
|
$query = Group::with('users')->whereHas('users', function (Builder $query) {
|
|
$query->where('user_id', getLoggedInUserId());
|
|
});
|
|
|
|
return $query->orderBy('name')->get();
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
*
|
|
* @return Group
|
|
*/
|
|
public function store($input)
|
|
{
|
|
try {
|
|
if (! empty($input['photo'])) {
|
|
$input['photo'] = ImageTrait::makeImage($input['photo'], Group::$PATH);
|
|
}
|
|
|
|
/** @var Group $group */
|
|
$group = Group::create($input);
|
|
|
|
$users = $input['users'];
|
|
$users[] = getLoggedInUserId();
|
|
$this->addMembersToGroup($group, $users, false);
|
|
|
|
$userIds = $group->fresh()->users->pluck('id')->toArray();
|
|
$broadcastData = $this->prepareDataForMemberAddedToGroup($group);
|
|
broadcast(new UserEvent($broadcastData, $userIds))->toOthers();
|
|
|
|
$msgInput = [
|
|
'to_id' => $group->id,
|
|
'message' => Auth::user()->name.' created group "'.$group->name.'"',
|
|
'is_group' => true,
|
|
'message_type' => Conversation::MESSAGE_TYPE_BADGES,
|
|
];
|
|
$this->sendMessage($msgInput);
|
|
|
|
return $group;
|
|
} catch (Exception $e) {
|
|
throw new UnprocessableEntityHttpException($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @param int $id
|
|
*
|
|
* @return array
|
|
*/
|
|
public function update($input, $id)
|
|
{
|
|
$conversation = null;
|
|
/** @var Group $group */
|
|
$group = Group::findOrFail($id);
|
|
|
|
try {
|
|
if (! empty($input['photo'])) {
|
|
$input['photo'] = ImageTrait::makeImage($input['photo'], Group::$PATH);
|
|
}
|
|
|
|
unset($input['created_by']);
|
|
$group->update($input);
|
|
$changes = $group->getChanges();
|
|
if (! empty($changes)) {
|
|
$msgInput = [
|
|
'to_id' => $group->id,
|
|
'message' => 'Group details updated by '.Auth::user()->name,
|
|
'is_group' => true,
|
|
'message_type' => Conversation::MESSAGE_TYPE_BADGES,
|
|
];
|
|
$conversation = $this->sendMessage($msgInput);
|
|
}
|
|
|
|
if (! empty($input['users'])) {
|
|
$this->addMembersToGroup($group, $input['users']);
|
|
}
|
|
|
|
$broadcastData = $this->prepareDataBroadcastWhenGroupUpdated(['group' => $group]);
|
|
broadcast(new GroupEvent($broadcastData))->toOthers();
|
|
|
|
return [$group, $conversation];
|
|
} catch (Exception $e) {
|
|
throw new UnprocessableEntityHttpException($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param Group $group
|
|
* @param array $users
|
|
* @param bool $fireEvent
|
|
*
|
|
* @throws Exception
|
|
*
|
|
* @return array|void
|
|
*/
|
|
public function addMembersToGroup($group, $users, $fireEvent = true)
|
|
{
|
|
$groupUsers = $group->users->pluck('id')->toArray();
|
|
$newAddedUsers = [];
|
|
$newUserNames = '';
|
|
$users = array_unique($users);
|
|
|
|
$userRecords = User::whereIn('id', $users)->get()->keyBy('id');
|
|
GroupUser::withTrashed()->whereIn('user_id', $users)->where('group_id', $group->id)->forceDelete();
|
|
LastConversation::whereIn('user_id', $users)->where('group_id', $group->id)->delete();
|
|
|
|
foreach ($users as $userId) {
|
|
if (in_array($userId, $groupUsers)) { // if already in group
|
|
continue;
|
|
}
|
|
|
|
if (! isset($userRecords[$userId])) {
|
|
continue;
|
|
}
|
|
|
|
/** @var User $user */
|
|
$user = $userRecords[$userId];
|
|
$newAddedUsers[] = $user->toArray();
|
|
$newUserNames .= $user->name.', ';
|
|
|
|
GroupUser::create([
|
|
'user_id' => $user->id,
|
|
'group_id' => $group->id,
|
|
'added_by' => getLoggedInUserId(),
|
|
'role' => $group->created_by == $user->id ? GroupUser::ROLE_ADMIN : GroupUser::ROLE_MEMBER,
|
|
]);
|
|
|
|
if ($fireEvent) {
|
|
$broadCastData = $this->prepareDataForMemberAddedToGroup($group);
|
|
broadcast(new UserEvent($broadCastData, $user->id))->toOthers();
|
|
}
|
|
}
|
|
|
|
if (! $fireEvent) {
|
|
return;
|
|
}
|
|
|
|
$newUserNames = substr($newUserNames, 0, strlen($newUserNames) - 2);
|
|
$msgInput = [
|
|
'to_id' => $group->id,
|
|
'message' => Auth::user()->name." added : $newUserNames",
|
|
'is_group' => true,
|
|
'message_type' => Conversation::MESSAGE_TYPE_BADGES,
|
|
'add_members' => true,
|
|
];
|
|
$conversation = $this->sendMessage($msgInput);
|
|
|
|
$broadcastData = $this->prepareDataBroadcastWhenGroupUpdated(
|
|
['group' => $group, 'users' => $newAddedUsers], Group::GROUP_NEW_MEMBERS_ADDED
|
|
);
|
|
broadcast(new GroupEvent($broadcastData))->toOthers();
|
|
|
|
return [$newAddedUsers, $conversation];
|
|
}
|
|
|
|
/**
|
|
* @param Group $group
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function prepareDataForMemberAddedToGroup($group)
|
|
{
|
|
$groupArr = $group->toArray();
|
|
$groupArr['group_created_by'] = $group->group_created_by;
|
|
$groupArr['type'] = User::ADDED_TO_GROUP;
|
|
unset($groupArr['users']);
|
|
unset($groupArr['created_by_user']);
|
|
unset($groupArr['users_with_trashed']);
|
|
|
|
return $groupArr;
|
|
}
|
|
|
|
/**
|
|
* @param Group $group
|
|
* @param User $user
|
|
*
|
|
* @throws Exception
|
|
*
|
|
* @return Conversation
|
|
*/
|
|
public function removeMemberFromGroup($group, $user)
|
|
{
|
|
/** @var User $authUser */
|
|
$authUser = Auth::user();
|
|
$groupUser = GroupUser::whereGroupId($group->id)->whereUserId($user->id);
|
|
|
|
if (getLoggedInUserId() != $group->created_by && $user->id == $group->created_by) {
|
|
throw new UnprocessableEntityHttpException('You can not remove group owner.');
|
|
}
|
|
|
|
$message = $authUser->name." removed $user->name.";
|
|
|
|
$msgInput = [
|
|
'to_id' => $group->id,
|
|
'message' => $message,
|
|
'is_group' => true,
|
|
'message_type' => Conversation::MESSAGE_TYPE_BADGES,
|
|
];
|
|
$conversation = $this->sendMessage($msgInput);
|
|
|
|
$broadcastData = $this->prepareDataBroadcastWhenGroupUpdated(
|
|
['group' => $group, 'user_id' => $user->id], Group::GROUP_MEMBER_REMOVED
|
|
);
|
|
broadcast(new GroupEvent($broadcastData))->toOthers();
|
|
|
|
$groupUser->update(['removed_by' => getLoggedInUserId(), 'deleted_at' => Carbon::now()]);
|
|
|
|
// Store last group details info when user leave the group
|
|
$groupDetails = $group->toArray();
|
|
$groupDetails['removed_from_group'] = true;
|
|
$groupDetails['users'] = $group->fresh()->users->toArray();
|
|
LastConversation::create([
|
|
'conversation_id' => $conversation->id, 'group_id' => $group->id, 'user_id' => $user->id,
|
|
'group_details' => $groupDetails,
|
|
]);
|
|
|
|
return $conversation;
|
|
}
|
|
|
|
/**
|
|
* @param array $groupUsers
|
|
* @param int $messageId
|
|
* @param int $groupId
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function addRecordsToGroupMessageRecipients($groupUsers, $messageId, $groupId)
|
|
{
|
|
$users = Arr::except($groupUsers, getLoggedInUserId());
|
|
|
|
$inputs = [];
|
|
foreach ($users as $userId) {
|
|
$inputs[] = [
|
|
'user_id' => $userId,
|
|
'conversation_id' => $messageId,
|
|
'group_id' => $groupId,
|
|
];
|
|
}
|
|
|
|
GroupMessageRecipient::insert($inputs);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param Group $group
|
|
* @param int $userId
|
|
*
|
|
* @throws Exception
|
|
*
|
|
* @return Conversation
|
|
*/
|
|
public function leaveGroup($group, $userId)
|
|
{
|
|
$msgInput = [
|
|
'to_id' => $group->id,
|
|
'message' => Auth::user()->name.' left the group',
|
|
'is_group' => true,
|
|
'message_type' => Conversation::MESSAGE_TYPE_BADGES,
|
|
];
|
|
|
|
$conversation = $this->sendMessage($msgInput);
|
|
GroupUser::whereGroupId($group->id)->whereUserId($userId)->delete();
|
|
|
|
// Store last group details info when user leave the group
|
|
$group->append('group_created_by');
|
|
$groupDetails = $group->toArray();
|
|
$groupDetails['removed_from_group'] = true;
|
|
$groupDetails['users'] = $group->fresh()->users->toArray();
|
|
LastConversation::create([
|
|
'conversation_id' => $conversation->id, 'group_id' => $group->id, 'user_id' => $userId,
|
|
'group_details' => $groupDetails,
|
|
]);
|
|
|
|
$broadcastData = $this->prepareDataBroadcastWhenGroupUpdated(
|
|
['group' => $group, 'user_id' => $userId], Group::GROUP_MEMBER_REMOVED
|
|
);
|
|
broadcast(new GroupEvent($broadcastData))->toOthers();
|
|
|
|
return $conversation;
|
|
}
|
|
|
|
/**
|
|
* @param Group $group
|
|
* @param int $userId
|
|
*
|
|
* @throws Exception
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function removeGroup($group, $userId)
|
|
{
|
|
if ($group->created_by != $userId) {
|
|
GroupUser::whereGroupId($group->id)->whereUserId($userId)->forceDelete();
|
|
|
|
return true;
|
|
}
|
|
|
|
$msgInput = [
|
|
'to_id' => $group->id,
|
|
'message' => Auth::user()->name.' deleted this group',
|
|
'is_group' => true,
|
|
'message_type' => Conversation::MESSAGE_TYPE_BADGES,
|
|
];
|
|
$conversation = $this->sendMessage($msgInput);
|
|
|
|
// broadcast event for all group members
|
|
$broadcastData = $this->prepareDataBroadcastWhenGroupUpdated(
|
|
['group' => $group], Group::GROUP_DELETED_BY_OWNER
|
|
);
|
|
broadcast(new GroupEvent($broadcastData))->toOthers();
|
|
|
|
$userIds = $group->users->pluck('id', 'id')->except($group->created_by)->toArray();
|
|
// All members of group should leaved the group
|
|
GroupUser::whereGroupId($group->id)->whereIn('user_id', $userIds)->delete();
|
|
// Group deleted for owner of group
|
|
GroupUser::whereGroupId($group->id)->where('user_id', $group->created_by)->forceDelete();
|
|
|
|
// Store last group details info when user leave the group
|
|
$group->append('');
|
|
$groupDetails = $group->toArray();
|
|
$groupDetails['group_created_by'] = $group->group_created_by;
|
|
$groupDetails['removed_from_group'] = true;
|
|
$groupDetails['group_deleted_by_owner'] = true;
|
|
$groupDetails['users'] = $group->fresh()->users->toArray();
|
|
foreach ($group->users as $user) {
|
|
LastConversation::create([
|
|
'conversation_id' => $conversation->id, 'group_id' => $group->id, 'user_id' => $user->id,
|
|
'group_details' => $groupDetails,
|
|
]);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param Group $group
|
|
* @param User $member
|
|
*
|
|
* @return Conversation
|
|
*/
|
|
public function makeMemberToGroupAdmin($group, $member)
|
|
{
|
|
$memberIds = $group->users->pluck('id', 'id')->except($group->created_by)->toArray();
|
|
|
|
$this->assignRole($group->id, $member->id, GroupUser::ROLE_ADMIN);
|
|
|
|
$broadcastData = $this->prepareDataBroadcastWhenGroupUpdated(
|
|
[
|
|
'group' => $group, 'user_id' => $member->id, 'is_admin' => true, 'userIds' => $memberIds,
|
|
], Group::GROUP_MEMBER_ROLE_UPDATED
|
|
);
|
|
broadcast(new GroupEvent($broadcastData))->toOthers();
|
|
|
|
$msgInput = [
|
|
'to_id' => $group->id,
|
|
'message' => Auth::user()->name.' assigned admin role to '.$member->name,
|
|
'is_group' => true,
|
|
'message_type' => Conversation::MESSAGE_TYPE_BADGES,
|
|
];
|
|
|
|
return $this->sendMessage($msgInput);
|
|
}
|
|
|
|
/**
|
|
* @param Group $group
|
|
* @param User $member
|
|
*
|
|
* @return Conversation
|
|
*/
|
|
public function dismissAsAdmin($group, $member)
|
|
{
|
|
if ($group->created_by == $member->id) {
|
|
throw new UnprocessableEntityHttpException('You can not change group owner role.');
|
|
}
|
|
|
|
$memberIds = $group->users->pluck('id', 'id')->except($group->created_by)->toArray();
|
|
$this->assignRole($group->id, $member->id, GroupUser::ROLE_MEMBER);
|
|
|
|
$broadcastData = $this->prepareDataBroadcastWhenGroupUpdated(
|
|
[
|
|
'group' => $group, 'user_id' => $member->id, 'is_admin' => false, 'userIds' => $memberIds,
|
|
], Group::GROUP_MEMBER_ROLE_UPDATED
|
|
);
|
|
broadcast(new GroupEvent($broadcastData))->toOthers();
|
|
|
|
$msgInput = [
|
|
'to_id' => $group->id,
|
|
'message' => Auth::user()->name." dismissed $member->name from admin",
|
|
'is_group' => true,
|
|
'message_type' => Conversation::MESSAGE_TYPE_BADGES,
|
|
];
|
|
|
|
return $this->sendMessage($msgInput);
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
*
|
|
* @return Conversation
|
|
*/
|
|
public function sendMessage($input)
|
|
{
|
|
/** @var ChatRepository $chatRepo */
|
|
$chatRepo = app(ChatRepository::class);
|
|
$conversation = $chatRepo->sendGroupMessage($input);
|
|
|
|
return $conversation;
|
|
}
|
|
|
|
/**
|
|
* @param int $groupId
|
|
* @param int $memberId
|
|
* @param int $role
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function assignRole($groupId, $memberId, $role)
|
|
{
|
|
GroupUser::whereGroupId($groupId)->whereUserId($memberId)->update(['role' => $role]);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param string $groupId
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isAuthUserGroupAdmin($groupId)
|
|
{
|
|
/** @var GroupUser $groupUser */
|
|
$groupUser = GroupUser::whereGroupId($groupId)->whereUserId(getLoggedInUserId())->first();
|
|
|
|
return ($groupUser->role === GroupUser::ROLE_ADMIN) ? true : false;
|
|
}
|
|
|
|
/**
|
|
* @param array $data
|
|
* @param int $type
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function prepareDataBroadcastWhenGroupUpdated($data, $type = Group::GROUP_DETAILS_UPDATED)
|
|
{
|
|
$result['group'] = $data['group']->toArray();
|
|
unset($result['group']['users_with_trashed']);
|
|
$result['type'] = $type;
|
|
|
|
if (isset($data['user_id'])) {
|
|
$result['user_id'] = $data['user_id'];
|
|
}
|
|
|
|
if (isset($data['is_admin'])) {
|
|
$result['is_admin'] = $data['is_admin'];
|
|
}
|
|
|
|
if (isset($data['userIds'])) {
|
|
$result['userIds'] = $data['userIds'];
|
|
}
|
|
|
|
$users = [];
|
|
if (isset($data['users'])) {
|
|
$users = $this->prepareUsersData($data['users']);
|
|
}
|
|
|
|
$result['group']['users'] = $users;
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function getGroupMembersIds($group)
|
|
{
|
|
return $group->users->pluck('id')->toArray();
|
|
}
|
|
|
|
/**
|
|
* @param array $users
|
|
*
|
|
* @return array
|
|
*/
|
|
public function prepareUsersData($users)
|
|
{
|
|
$result = [];
|
|
foreach ($users as $user) {
|
|
$data['id'] = $user['id'];
|
|
$data['name'] = $user['name'];
|
|
$data['email'] = $user['email'];
|
|
$data['photo'] = $user['photo'];
|
|
|
|
$result[] = $data;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
}
|