Skip to content

Commit

Permalink
Merge pull request #6 from coralsio/support-api
Browse files Browse the repository at this point in the history
support api and laravel reverb
  • Loading branch information
saeed-corals authored May 19, 2024
2 parents 7f827a4 + ed9faac commit e16bd94
Show file tree
Hide file tree
Showing 31 changed files with 910 additions and 55 deletions.
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,8 @@
]
}
},
"minimum-stability": "dev"
"minimum-stability": "dev",
"require": {
"laravel/reverb": "@beta"
}
}
38 changes: 36 additions & 2 deletions src/DataTables/DiscussionsDataTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
namespace Corals\Modules\Messaging\DataTables;

use Corals\Foundation\DataTables\BaseDataTable;
use Corals\Modules\Messaging\DataTables\Scopes\DiscussionSearchScope;
use Corals\Modules\Messaging\Models\Discussion;
use Corals\Modules\Messaging\Transformers\DiscussionTransformer;
use Illuminate\Database\Eloquent\Builder;
use Yajra\DataTables\EloquentDataTable;

class DiscussionsDataTable extends BaseDataTable
Expand All @@ -29,9 +31,24 @@ public function dataTable($query)
* @param Discussion $model
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function query(Discussion $model)
public function query(Discussion $model, string $lastMessageCreatedAt = null)
{
return $model->newQuery();
$subQueryLastMessage = \Corals\Modules\Messaging\Models\Message::query()
->select('messaging_messages.created_at')
->whereColumn('messaging_discussions.id', 'messaging_messages.discussion_id')
->limit(1)
->orderBy('created_at', 'desc');

return $model->newQuery()
->select('messaging_discussions.*')
->when($lastMessageCreatedAt, function (Builder $builder, $lastMessageCreatedAt) use ($subQueryLastMessage) {
$builder->selectSub($subQueryLastMessage, 'last_message')
->whereRaw("({$subQueryLastMessage->toSql()}) < ?", [$lastMessageCreatedAt]);
})->withCount(['messages' => function (Builder $builder) {
$builder->where('status', '<>', 'draft');
}])
->when(!isSuperUser(), fn(Builder $q) => $q->forUser(user()))
->orderBy($subQueryLastMessage, 'desc');
}

/**
Expand All @@ -50,4 +67,21 @@ protected function getColumns()
'updated_at' => ['title' => trans('Corals::attributes.updated_at')],
];
}

/**
* @return array[]
*/
public function getFilters()
{
return [
'search' => [
'title' => 'Search',
'class' => 'col-md-3',
'type' => 'text',
'condition' => 'like',
'active' => true,
'builder' => DiscussionSearchScope::class
]
];
}
}
21 changes: 21 additions & 0 deletions src/DataTables/Scopes/DiscussionSearchScope.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Corals\Modules\Messaging\DataTables\Scopes;

use Illuminate\Database\Eloquent\Builder as EloquentBuilder;

class DiscussionSearchScope
{
/**
* @param EloquentBuilder $query
* @param $column
* @param $value
*/
public function apply(EloquentBuilder $query, $column, $value): void
{
$query->whereHas('participations.participable', function (EloquentBuilder $q) use ($value) {
$q->when(user(), fn(EloquentBuilder $q) => $q->where('users.id', '<>', user()->id))
->whereAny(['users.name', 'users.last_name', 'email'], 'like', "%$value%");
});
}
}
73 changes: 73 additions & 0 deletions src/Events/MessageReceived.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

namespace Corals\Modules\Messaging\Events;

use Corals\Modules\Messaging\Models\Message;
use Corals\Modules\Messaging\Transformers\API\MessagePresenter;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class MessageReceived implements ShouldBroadcast
{

use Dispatchable, InteractsWithSockets, SerializesModels;

/**
* @var string
*/
public $queue = 'messaging-queue';

/**
* Create a new event instance.
*/
public function __construct(protected Message $message)
{
}

/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn(): array
{
$channels = [];

foreach ($this->message->recipients as $participation) {
$channels[] = new PrivateChannel(sprintf(
'messages.%s',
$participation->participable->id
));
}

return $channels;
}

/**
* @return array
* @throws \Exception
*/
public function broadcastWith(): array
{
return (new MessagePresenter)->present($this->message)['data'];
}

/**
* @return string
*/
public function broadcastAs(): string
{
return 'message.received';
}

/**
* @return bool
*/
public function broadcastWhen(): bool
{
return $this->message->status <> 'draft';
}
}
70 changes: 70 additions & 0 deletions src/Http/Controllers/API/DiscussionsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace Corals\Modules\Messaging\Http\Controllers\API;

use Corals\Foundation\Http\Controllers\APIBaseController;
use Corals\Foundation\Models\BaseModel;
use Corals\Foundation\Search\Search;
use Corals\Modules\Messaging\DataTables\DiscussionsDataTable;
use Corals\Modules\Messaging\Http\Requests\DiscussionRequest;
use Corals\Modules\Messaging\Models\Discussion;
use Corals\Modules\Messaging\Models\Message;
use Corals\Modules\Messaging\Services\DiscussionService;
use Corals\Modules\Messaging\Transformers\API\DiscussionPresenter;
use Corals\User\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;

class DiscussionsController extends APIBaseController
{
/**
* DiscussionsController constructor.
* @param DiscussionService $discussionService
*/
public function __construct(protected DiscussionService $discussionService)
{
$this->discussionService->setPresenter(new DiscussionPresenter);
parent::__construct();
}

/**
* @param DiscussionRequest $request
* @param DiscussionsDataTable $dataTable
* @return mixed
*/
public function index(DiscussionRequest $request, DiscussionsDataTable $dataTable)
{

$query = $dataTable->query(new Discussion, $request->get('last_msg_created_at'));

return $this->discussionService->index($query, $dataTable);
}

/**
* @param DiscussionRequest $request
* @param Discussion $discussion
* @return \Illuminate\Http\JsonResponse
*/
public function show(DiscussionRequest $request, Discussion $discussion)
{
try {
return apiResponse($this->discussionService->getModelDetails($discussion));
} catch (\Exception $e) {
return apiExceptionResponse($e);
}
}

/**
* @param Request $request
* @param Discussion $discussion
* @return \Illuminate\Http\JsonResponse
*/
public function markAsRead(Request $request, Discussion $discussion)
{
try {
return apiResponse($this->discussionService->markAsRead($discussion));
} catch (\Exception $e) {
return apiExceptionResponse($e);
}
}
}
71 changes: 71 additions & 0 deletions src/Http/Controllers/API/MessageController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php


namespace Corals\Modules\Messaging\Http\Controllers\API;

use Corals\Foundation\Http\Controllers\APIBaseController;
use Corals\Modules\Messaging\Http\Requests\MessageRequest;
use Corals\Modules\Messaging\Models\Message;
use Corals\Modules\Messaging\Services\MessageService;
use Corals\Modules\Messaging\Transformers\API\MessagePresenter;
use Illuminate\Http\Request;

class MessageController extends APIBaseController
{
/**
* MessageController constructor.
* @param MessageService $messageService
*/
public function __construct(protected MessageService $messageService)
{
$this->messageService->setPresenter(new MessagePresenter);
parent::__construct();
}

/**
* @param MessageRequest $request
* @param Message $message
* @return \Illuminate\Http\JsonResponse|mixed
*/
public function fetchMoreMessages(MessageRequest $request, Message $message)
{
try {
return $this->messageService->fetchMoreMessages($message);
} catch (\Exception $e) {
return apiExceptionResponse($e);
}
}

/**
* @param MessageRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function store(MessageRequest $request)
{
try {

$message = $this->messageService->store($request, Message::class);

return apiResponse($this->messageService->getModelDetails(), trans('Corals::messages.success.created', [
'item' => 'message'
]));

} catch (\Exception $exception) {
return apiExceptionResponse($exception);
}
}

/**
* @param Request $request
* @param Message $message
* @return \Illuminate\Http\JsonResponse
*/
public function broadcastMessage(Request $request, Message $message)
{
try {
return apiResponse($this->messageService->broadcastMessage($message));
} catch (\Exception $e) {
return apiExceptionResponse($e);
}
}
}
21 changes: 20 additions & 1 deletion src/Http/Requests/MessageRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Corals\Foundation\Http\Requests\BaseRequest;
use Corals\Modules\Messaging\Models\Message;
use Illuminate\Support\Arr;

class MessageRequest extends BaseRequest
{
Expand Down Expand Up @@ -31,12 +32,30 @@ public function rules()

if ($this->isUpdate() || $this->isStore()) {
$rules = array_merge($rules, [
'body' => 'required',
'body' => 'nullable|max:500',
'files.*' => 'required|mimes:jpg,jpeg,png,rar,zip,txt,pdf,docs,xls,xlsx,doc|max:' . maxUploadFileSize(),
]);

if (is_api_request()) {
$rules['second_participation_id'] = 'required|exists:users,id';
}
}


return $rules;
}

protected function getValidatorInstance()
{
if ($this->isUpdate() || $this->isStore()) {
$data = $this->all();

$this->getInputSource()->replace(array_merge($data, [
'participable_type' => getMorphAlias(user()),
'participable_id' => user()->id,
]));
}

return parent::getValidatorInstance(); // TODO: Change the autogenerated stub
}
}
Loading

0 comments on commit e16bd94

Please sign in to comment.