Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 53 additions & 4 deletions src/ChatifyMessenger.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Models\ChMessage as Message;
use App\Models\ChFavorite as Favorite;
use App\Models\User;
use Illuminate\Support\Facades\Storage;
use Pusher\Pusher;
use Illuminate\Support\Facades\Auth;
Expand All @@ -23,6 +24,7 @@ public function getMaxUploadSize()
return config('chatify.attachments.max_upload_size') * 1048576;
}


public function __construct()
{
$this->pusher = new Pusher(
Expand Down Expand Up @@ -149,8 +151,15 @@ public function parseMessage($prefetchedMessage = null, $id = null)
$attachmentOBJ = json_decode($msg->attachment);
$attachment = $attachmentOBJ->new_name;
$attachment_title = htmlentities(trim($attachmentOBJ->old_name), ENT_QUOTES, 'UTF-8');
$ext = pathinfo($attachment, PATHINFO_EXTENSION);
$attachment_type = in_array($ext, $this->getAllowedImages()) ? 'image' : 'file';
$ext = strtolower(pathinfo($attachment, PATHINFO_EXTENSION));

if (in_array($ext, $this->getAllowedImages())) {
$attachment_type = 'image';
} else if (in_array($ext, $this->getAllowedVoiceMessages())) {
$attachment_type = 'audio';
} else {
$attachment_type = 'file';
}
}
return [
'id' => $msg->id,
Expand Down Expand Up @@ -254,6 +263,33 @@ public function countUnseenMessages($user_id)
return Message::where('from_id', $user_id)->where('to_id', Auth::user()->id)->where('seen', 0)->count();
}

/**
* Get contacts ordered by the latest message with each contact.
*
* @param int $authId
* @return \Illuminate\Database\Eloquent\Builder
*/
public function getContactsQuery(int $authId)
{
$contactUserId = 'CASE WHEN from_id = ? THEN to_id ELSE from_id END';

$latestMessages = Message::query()
->selectRaw("$contactUserId as user_id", [$authId])
->selectRaw('MAX(created_at) as max_created_at')
->where(function ($q) use ($authId) {
$q->where('from_id', $authId)
->orWhere('to_id', $authId);
})
->groupBy('user_id');

return User::joinSub($latestMessages, 'latest_messages', function ($join) {
$join->on('users.id', '=', 'latest_messages.user_id');
})
->where('users.id', '!=', $authId)
->select('users.*', 'latest_messages.max_created_at')
->orderBy('latest_messages.max_created_at', 'desc');
}

/**
* Get user list's item data [Contact Itme]
* (e.g. User data, Last message, Unseen Counter...)
Expand All @@ -270,8 +306,9 @@ public function getContactItem($user)
// Get Unseen messages counter
$unseenCounter = $this->countUnseenMessages($user->id);
if ($lastMessage) {
$lastMessage->created_at = $lastMessage->created_at->toIso8601String();
$lastMessage->timeAgo = $lastMessage->created_at->diffForHumans();
$lastMessageCreatedAt = $lastMessage->created_at;
$lastMessage->timeAgo = $lastMessageCreatedAt->diffForHumans();
$lastMessage->created_at = $lastMessageCreatedAt->toIso8601String();
}
return view('Chatify::layouts.listItem', [
'get' => 'users',
Expand Down Expand Up @@ -442,4 +479,16 @@ public function getAttachmentUrl($attachment_name)
{
return self::storage()->url(config('chatify.attachments.folder') . '/' . $attachment_name);
}


/**
* This method returns the allowed voice messages extensions
*
* @return array
*/
public function getAllowedVoiceMessages()
{
return config('chatify.attachments.allowed_voice_messages');
}

}
18 changes: 2 additions & 16 deletions src/Http/Controllers/Api/MessagesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Response;
use App\Models\ChMessage as Message;
use App\Models\ChFavorite as Favorite;
use Chatify\Facades\ChatifyMessenger as Chatify;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

Expand Down Expand Up @@ -207,20 +205,8 @@ public function seen(Request $request)
*/
public function getContacts(Request $request)
{
// get all users that received/sent message from/to [Auth user]
$users = Message::join('users', function ($join) {
$join->on('ch_messages.from_id', '=', 'users.id')
->orOn('ch_messages.to_id', '=', 'users.id');
})
->where(function ($q) {
$q->where('ch_messages.from_id', Auth::user()->id)
->orWhere('ch_messages.to_id', Auth::user()->id);
})
->where('users.id','!=',Auth::user()->id)
->select('users.*',DB::raw('MAX(ch_messages.created_at) max_created_at'))
->orderBy('max_created_at', 'desc')
->groupBy('users.id')
->paginate($request->per_page ?? $this->perPage);
$authId = (int) Auth::user()->id;
$users = Chatify::getContactsQuery($authId)->paginate($request->per_page ?? $this->perPage);

return response()->json([
'contacts' => $users->items(),
Expand Down
208 changes: 146 additions & 62 deletions src/Http/Controllers/MessagesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Response;
use App\Models\User;
use App\Models\ChMessage as Message;
use App\Models\ChFavorite as Favorite;
use Chatify\Facades\ChatifyMessenger as Chatify;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Request as FacadesRequest;
use Illuminate\Support\Str;

class MessagesController extends Controller
{
protected $perPage = 30;
Expand Down Expand Up @@ -89,76 +88,173 @@ public function download($fileName)
}

/**
* Send a message to database
* Send a message to database.
*
* @param Request $request
* @return JsonResponse
*/
public function send(Request $request)
{
// default variables
$error = (object)[
$error = (object) [
'status' => 0,
'message' => null
'message' => null,
];

$attachment = null;
$attachment_title = null;
$messageData = null;
$isVoiceMessage = $request->hasFile('audio');

// if there is attachment [file]
if ($request->hasFile('file')) {
// allowed extensions
$allowed_images = Chatify::getAllowedImages();
$allowed_files = Chatify::getAllowedFiles();
$allowed = array_merge($allowed_images, $allowed_files);

$file = $request->file('file');
// check file size
if ($file->getSize() < Chatify::getMaxUploadSize()) {
if (in_array(strtolower($file->extension()), $allowed)) {
// get attachment name
$attachment_title = $file->getClientOriginalName();
// upload attachment and store the new name
$attachment = Str::uuid() . "." . $file->extension();
$file->storeAs(config('chatify.attachments.folder'), $attachment, config('chatify.storage_disk_name'));
} else {
$error->status = 1;
$error->message = "File extension not allowed!";
}
} else {
$error->status = 1;
$error->message = "File size you are trying to upload is too large!";
}
if ($isVoiceMessage) {
$this->handleVoiceMessage($request, $error, $attachment, $attachment_title);
} else {
$this->handleTextOrFileMessage($request, $error, $attachment, $attachment_title);
}

if (!$error->status) {
$message = Chatify::newMessage([
'from_id' => Auth::user()->id,
'to_id' => $request['id'],
'body' => htmlentities(trim($request['message']), ENT_QUOTES, 'UTF-8'),
'attachment' => ($attachment) ? json_encode((object)[
'new_name' => $attachment,
'old_name' => htmlentities(trim($attachment_title), ENT_QUOTES, 'UTF-8'),
]) : null,
]);
$message = $this->createMessage($request, $isVoiceMessage, $attachment, $attachment_title);
$messageData = Chatify::parseMessage($message);
if (Auth::user()->id != $request['id']) {
Chatify::push("private-chatify.".$request['id'], 'messaging', [
'from_id' => Auth::user()->id,
'to_id' => $request['id'],
'message' => Chatify::messageCard($messageData, true)
]);
}
$this->pushNotification($request, $messageData);
}

// send the response
return Response::json([
'status' => '200',
'error' => $error,
'message' => Chatify::messageCard(@$messageData),
'message' => Chatify::messageCard($messageData),
'tempID' => $request['temporaryMsgId'],
]);
}

/**
* Handle a recorded voice message upload.
*
* @param Request $request
* @param object $error
* @param string|null $attachment
* @param string|null $attachment_title
* @return void
*/
private function handleVoiceMessage(Request $request, &$error, &$attachment, &$attachment_title)
{
if (!$request->hasFile('audio')) {
return;
}

$this->storeUploadedAttachment(
$request->file('audio'),
Chatify::getAllowedVoiceMessages(),
$error,
$attachment,
$attachment_title
);
}

/**
* Handle a regular text message with an optional file attachment.
*
* @param Request $request
* @param object $error
* @param string|null $attachment
* @param string|null $attachment_title
* @return void
*/
private function handleTextOrFileMessage(Request $request, &$error, &$attachment, &$attachment_title)
{
if (!$request->hasFile('file')) {
return;
}

$this->storeUploadedAttachment(
$request->file('file'),
array_merge(Chatify::getAllowedImages(), Chatify::getAllowedFiles()),
$error,
$attachment,
$attachment_title
);
}

/**
* Validate and store a message attachment.
*
* @param mixed $file
* @param array $allowedExtensions
* @param object $error
* @param string|null $attachment
* @param string|null $attachment_title
* @return void
*/
private function storeUploadedAttachment($file, $allowedExtensions, &$error, &$attachment, &$attachment_title)
{
if ($file->getSize() >= Chatify::getMaxUploadSize()) {
$this->setError($error, "File size you are trying to upload is too large!");
return;
}

$extension = strtolower($file->extension());

if (!in_array($extension, $allowedExtensions)) {
$this->setError($error, "File extension not allowed!");
return;
}

$attachment = Str::uuid() . "." . $extension;
$attachment_title = $file->getClientOriginalName();
$file->storeAs(config('chatify.attachments.folder'), $attachment, config('chatify.storage_disk_name'));
}

/**
* Set a send-message error.
*
* @param object $error
* @param string $message
* @return void
*/
private function setError(&$error, $message)
{
$error->status = 1;
$error->message = $message;
}

/**
* Create the chat message record.
*
* @param Request $request
* @param bool $isVoiceMessage
* @param string|null $attachment
* @param string|null $attachment_title
* @return mixed
*/
private function createMessage(Request $request, $isVoiceMessage, $attachment, $attachment_title)
{
return Chatify::newMessage([
'from_id' => Auth::user()->id,
'to_id' => $request->input('id'),
'body' => $isVoiceMessage ? '' : htmlentities(trim($request['message']), ENT_QUOTES, 'UTF-8'),
'attachment' => ($attachment) ? json_encode((object) [
'new_name' => $attachment,
'old_name' => htmlentities(trim($attachment_title), ENT_QUOTES, 'UTF-8'),
]) : null,
]);
}

/**
* Push a message notification to the receiver.
*
* @param Request $request
* @param array $messageData
* @return void
*/
private function pushNotification(Request $request, $messageData)
{
if (Auth::user()->id != $request->input('id')) {
Chatify::push("private-chatify." . $request->input('id'), 'messaging', [
'from_id' => Auth::user()->id,
'to_id' => $request->input('id'),
'message' => Chatify::messageCard($messageData, true),
]);
}
}

/**
* fetch [user/group] messages from database
*
Expand Down Expand Up @@ -221,20 +317,8 @@ public function seen(Request $request)
*/
public function getContacts(Request $request)
{
// get all users that received/sent message from/to [Auth user]
$users = Message::join('users', function ($join) {
$join->on('ch_messages.from_id', '=', 'users.id')
->orOn('ch_messages.to_id', '=', 'users.id');
})
->where(function ($q) {
$q->where('ch_messages.from_id', Auth::user()->id)
->orWhere('ch_messages.to_id', Auth::user()->id);
})
->where('users.id','!=',Auth::user()->id)
->select('users.*',DB::raw('MAX(ch_messages.created_at) max_created_at'))
->orderBy('max_created_at', 'desc')
->groupBy('users.id')
->paginate($request->per_page ?? $this->perPage);
$authId = (int) Auth::user()->id;
$users = Chatify::getContactsQuery($authId)->paginate($request->per_page ?? $this->perPage);

$usersList = $users->items();

Expand Down
Loading