Skip to content

Commit 486ef98

Browse files
committed
Add functionality to parse a message and img src cids into media that is accessible
1 parent 3bd6cdf commit 486ef98

File tree

16 files changed

+993
-83
lines changed

16 files changed

+993
-83
lines changed

src/Contracts/Models/IHasInbox.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public function setAttachments($attachments) : IHasInbox;
2020

2121
public function clearAttachments() : IHasInbox;
2222

23+
public function setContentIdsMap(?array $cidMap) : IHasInbox;
24+
2325
/**
2426
* Send the message
2527
* @param mixed $sendingUser

src/Contracts/Models/IMessage.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,6 @@ public function from();
4646
* @return \Illuminate\Database\Eloquent\Relations\HasMany
4747
*/
4848
public function participants();
49+
50+
public function getAttachmentsAttribute();
4951
}

src/Http/Controllers/InboxController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Exception;
66
use Illuminate\Support\Arr;
77
use Illuminate\Http\Request;
8+
use Andaletech\Inbox\Libs\Utils;
89
use Illuminate\Routing\Controller;
910
use Psr\Container\NotFoundExceptionInterface;
1011
use Psr\Container\ContainerExceptionInterface;
@@ -96,7 +97,7 @@ public function getSluggedThreadMessages(Request $request, $slug, $id, $threadId
9697
if (empty($owner)) {
9798
return response()->json(['message' => 'Model not found'], 404);
9899
}
99-
$messageClassName = config('andale-inbox.eloquent.models.message');
100+
$messageClassName = Utils::getMessageClassName();
100101
$query = $messageClassName::forThread($threadId)->for($owner)->withParticipants()->latest();
101102
$total = $query->count();
102103
$query = $this->applySkipAndTake($query);
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
namespace Andaletech\Inbox\Http\Controllers;
4+
5+
use Illuminate\Http\Request;
6+
use Andaletech\Inbox\Libs\Utils;
7+
use Illuminate\Support\Facades\Auth;
8+
use Illuminate\Support\Facades\Storage;
9+
use Symfony\Component\HttpFoundation\HeaderUtils;
10+
use Andaletech\Inbox\Libs\Security\PolicyActionsConstants;
11+
12+
class MediaController
13+
{
14+
protected $contentMediaPolicy;
15+
16+
public function __construct()
17+
{
18+
}
19+
#region content media
20+
21+
/**
22+
* Handle request fo single content media
23+
*
24+
* @param Request $request
25+
* @param \Spatie\MediaLibrary\MediaCollections\Models\Media $contentMedia
26+
* @return Response
27+
*/
28+
public function getContentMedia(Request $request, $contentMedia = null)
29+
{
30+
if (empty($contentMedia)) {
31+
return response(null, 404);
32+
}
33+
if (!$this->authorizeContentMediaOperation(PolicyActionsConstants::VIEW, $contentMedia)) {
34+
return response(null, 403);
35+
}
36+
37+
if (0 == strcasecmp($request->get('disposition'), 'download')) {
38+
return $contentMedia;
39+
}
40+
41+
return response()->stream(
42+
function () use ($contentMedia) {
43+
echo Storage::disk($contentMedia->disk)->get(Utils::getMediaRelativePath($contentMedia, true));
44+
// echo Storage::disk($contentMedia->disk)->get($contentMedia->getPath());
45+
},
46+
200,
47+
[
48+
'Content-Type' => $contentMedia->mime_type,
49+
'Content-Length' => $contentMedia->size,
50+
'Last-Modified' => $contentMedia->updated_at->format('D, d M Y H:i:s T'),
51+
'Content-Disposition' => HeaderUtils::DISPOSITION_INLINE,
52+
]
53+
);
54+
}
55+
56+
public function authorizeContentMediaOperation($operation = PolicyActionsConstants::VIEW, $contentMedia = null)
57+
{
58+
$contentMediaPolicy = Utils::getContentMediaPolicy();
59+
if ($contentMediaPolicy) {
60+
try {
61+
return $contentMediaPolicy->{$operation}(Auth::user(), $contentMedia);
62+
} catch (\Exception $ex) {
63+
return false;
64+
}
65+
}
66+
67+
return true;
68+
}
69+
70+
#endregion content media
71+
72+
#region attachment
73+
74+
/**
75+
* Handle request fo single content media
76+
*
77+
* @param Request $request
78+
* @param \Spatie\MediaLibrary\MediaCollections\Models\Media $contentMedia
79+
* @return Response
80+
*/
81+
public function getAttachment(Request $request, $attachment = null)
82+
{
83+
if (empty($attachment)) {
84+
return response(null, 404);
85+
}
86+
if (!$this->authorizeAttachmentOperation(PolicyActionsConstants::VIEW, $attachment)) {
87+
return response(null, 403);
88+
}
89+
90+
if (0 == strcasecmp($request->get('disposition'), 'inline')) {
91+
return response()->stream(
92+
function () use ($attachment) {
93+
echo Storage::disk($attachment->disk)->get(Utils::getMediaRelativePath($attachment, true));
94+
},
95+
200,
96+
[
97+
'Content-Type' => $attachment->mime_type,
98+
'Content-Length' => $attachment->size,
99+
'Last-Modified' => $attachment->updated_at->format('D, d M Y H:i:s T'),
100+
'Content-Disposition' => HeaderUtils::DISPOSITION_INLINE,
101+
]
102+
);
103+
}
104+
105+
return $attachment;
106+
}
107+
108+
public function authorizeAttachmentOperation($operation = PolicyActionsConstants::VIEW, $attachment = null)
109+
{
110+
$attachmentPolicy = Utils::getAttachmentPolicy();
111+
if ($attachmentPolicy) {
112+
try {
113+
return $attachmentPolicy->{$operation}(Auth::user(), $attachment);
114+
} catch (\Exception $ex) {
115+
return false;
116+
}
117+
}
118+
119+
return true;
120+
}
121+
122+
#endregion attachment
123+
}

src/InboxServiceProvider.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,32 @@
33
namespace Andaletech\Inbox;
44

55
use Hidehalo\Nanoid\Client;
6+
use Andaletech\Inbox\Libs\Utils;
67
use Illuminate\Support\Facades\Route;
78
use Illuminate\Support\ServiceProvider;
89

910
class InboxServiceProvider extends ServiceProvider
1011
{
1112
public function boot()
1213
{
14+
Route::bind(Utils::getContentMediaRouteParamName(), function ($value) {
15+
$model = Utils::getContentMediaModel();
16+
17+
if ($model) {
18+
return $model::find($value);
19+
}
20+
21+
return $value;
22+
});
23+
Route::bind(Utils::getAttachmentsRouteParamName(), function ($value) {
24+
$model = Utils::getAttachmentModel();
25+
26+
if ($model) {
27+
return $model::find($value);
28+
}
29+
30+
return $value;
31+
});
1332
$this->publishes([
1433
__DIR__ . '/config/andale-inbox.php' => config_path('andale-inbox.php'),
1534
__DIR__ . '/database/migrations' => database_path('migrations'),
@@ -42,7 +61,7 @@ protected function registerRoutes()
4261
'prefix' => config('andale-inbox.routing.prefix', 'andale-inbox'),
4362
'namespace' => 'Andaletech\Inbox\Http\Controllers',
4463
'middleware' => config('andale-inbox.routing.middleware', ['web', 'auth']),
45-
'name' => config('andale-inbox.routing.name', 'andaleInbox'),
64+
'as' => Utils::getTopRouteName() . '.',
4665
],
4766
function () {
4867
$this->loadRoutesFrom(__DIR__ . '/routes/web.php');

src/Libs/MessageWriter.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
* @method static \Andaletech\Inbox\Libs\MessageWriter recipients($recipients)
2525
* @method \Andaletech\Inbox\Libs\MessageWriter to($to)
2626
* @method static \Andaletech\Inbox\Libs\MessageWriter to($to)
27+
* @method \Andaletech\Inbox\Libs\MessageWriter from($from)
28+
* @method static \Andaletech\Inbox\Libs\MessageWriter from($from)
2729
* @method \Andaletech\Inbox\Libs\MessageWriter forTenant(?int $tenantId)
2830
* @method static \Andaletech\Inbox\Libs\MessageWriter forTenant(?int $tenantId)
2931
*
@@ -143,16 +145,16 @@ public function setForTenant(?int $tenantId)
143145

144146
public function attach($attachments)
145147
{
146-
$attachments = is_array($attachments) ? $attachments : [$attachments];
147-
foreach ($attachments as $anAttachment) {
148+
$attachments = is_array($attachments) ? $attachments : [Str::uuid()->toString() => $attachments];
149+
foreach ($attachments as $key => $anAttachment) {
148150
if (
149151
is_string($anAttachment) ||
150152
($anAttachment instanceof UploadedFile) ||
151153
is_subclass_of($anAttachment, UploadedFile::class) ||
152154
($anAttachment instanceof Media) ||
153155
is_subclass_of($anAttachment, Media::class)
154156
) {
155-
$this->attachments[] = $anAttachment;
157+
$this->attachments[$key] = $anAttachment;
156158
}
157159
}
158160

@@ -161,13 +163,9 @@ public function attach($attachments)
161163

162164
public function setAttachments($attachments)
163165
{
164-
$attachments = is_array($attachments) ? $attachments : [$attachments];
165-
$this->attachments = [];
166-
foreach ($attachments as $anAttachment) {
167-
if (($anAttachment instanceof UploadedFile) || (is_a($anAttachment, Media::class))) {
168-
$this->attachments[] = $anAttachment;
169-
}
170-
}
166+
$this->clearAttachments();
167+
168+
return $this->attach($attachments);
171169

172170
return $this;
173171
}
@@ -249,7 +247,7 @@ protected function createThread()
249247

250248
protected function createMessage(IThread $thread, Model|int|null $sendingUser = null)
251249
{
252-
$messageClassName = config('andale-inbox.eloquent.models.message');
250+
$messageClassName = Utils::getMessageClassName();
253251
$messageData = [
254252
'subject' => $this->subject,
255253
'body' => $this->body,
@@ -271,6 +269,8 @@ protected function createMessage(IThread $thread, Model|int|null $sendingUser =
271269
}
272270
$thread->messages()->save($message);
273271
$message->addParticipants([$this->from, ...$this->recipients]);
272+
$processedContentIds = Utils::processMessageBodyMedia($message, $this->attachments);
273+
Utils::addAttachmentsToMessage($message, $this->attachments, $processedContentIds);
274274
event(new MessageCreated($message));
275275

276276
return $message;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Andaletech\Inbox\Libs\Security;
4+
5+
class PolicyActionsConstants
6+
{
7+
const CREATE = 'create';
8+
9+
const UPDATE = 'update';
10+
11+
const DELETE = 'delete';
12+
13+
const VIEW = 'view';
14+
15+
const VIEW_ANY = 'viewAny';
16+
}

0 commit comments

Comments
 (0)