class AttachmentApiController extends ApiController
{
- protected $attachmentService;
-
- protected $rules = [
- 'create' => [
- 'name' => 'required|min:1|max:255|string',
- 'uploaded_to' => 'required|integer|exists:pages,id',
- 'file' => 'required_without:link|file',
- 'link' => 'required_without:file|min:1|max:255|safe_url'
- ],
- 'update' => [
- 'name' => 'min:1|max:255|string',
- 'uploaded_to' => 'integer|exists:pages,id',
- 'file' => 'file',
- 'link' => 'min:1|max:255|safe_url'
- ],
- ];
-
- public function __construct(AttachmentService $attachmentService)
- {
- $this->attachmentService = $attachmentService;
+ public function __construct(
+ protected AttachmentService $attachmentService
+ ) {
}
/**
public function create(Request $request)
{
$this->checkPermission('attachment-create-all');
- $requestData = $this->validate($request, $this->rules['create']);
+ $requestData = $this->validate($request, $this->rules()['create']);
$pageId = $request->get('uploaded_to');
$page = Page::visible()->findOrFail($pageId);
$attachment = $this->attachmentService->saveNewUpload($uploadedFile, $page->id);
} else {
$attachment = $this->attachmentService->saveNewFromLink(
- $requestData['name'], $requestData['link'], $page->id
+ $requestData['name'],
+ $requestData['link'],
+ $page->id
);
}
$this->attachmentService->updateFile($attachment, $requestData);
+
return response()->json($attachment);
}
'markdown' => $attachment->markdownLink(),
]);
- if (!$attachment->external) {
- $attachmentContents = $this->attachmentService->getAttachmentFromStorage($attachment);
- $attachment->setAttribute('content', base64_encode($attachmentContents));
- } else {
+ // Simply return a JSON response of the attachment for link-based attachments
+ if ($attachment->external) {
$attachment->setAttribute('content', $attachment->path);
+
+ return response()->json($attachment);
}
- return response()->json($attachment);
+ // Build and split our core JSON, at point of content.
+ $splitter = 'CONTENT_SPLIT_LOCATION_' . time() . '_' . rand(1, 40000);
+ $attachment->setAttribute('content', $splitter);
+ $json = $attachment->toJson();
+ $jsonParts = explode($splitter, $json);
+ // Get a stream for the file data from storage
+ $stream = $this->attachmentService->streamAttachmentFromStorage($attachment);
+
+ return response()->stream(function () use ($jsonParts, $stream) {
+ // Output the pre-content JSON data
+ echo $jsonParts[0];
+
+ // Stream out our attachment data as base64 content
+ stream_filter_append($stream, 'convert.base64-encode', STREAM_FILTER_READ);
+ fpassthru($stream);
+ fclose($stream);
+
+ // Output our post-content JSON data
+ echo $jsonParts[1];
+ }, 200, ['Content-Type' => 'application/json']);
}
/**
*/
public function update(Request $request, string $id)
{
- $requestData = $this->validate($request, $this->rules['update']);
+ $requestData = $this->validate($request, $this->rules()['update']);
/** @var Attachment $attachment */
$attachment = Attachment::visible()->findOrFail($id);
}
$this->attachmentService->updateFile($attachment, $requestData);
+
return response()->json($attachment);
}
return response('', 204);
}
+ protected function rules(): array
+ {
+ return [
+ 'create' => [
+ 'name' => ['required', 'min:1', 'max:255', 'string'],
+ 'uploaded_to' => ['required', 'integer', 'exists:pages,id'],
+ 'file' => array_merge(['required_without:link'], $this->attachmentService->getFileValidationRules()),
+ 'link' => ['required_without:file', 'min:1', 'max:2000', 'safe_url'],
+ ],
+ 'update' => [
+ 'name' => ['min:1', 'max:255', 'string'],
+ 'uploaded_to' => ['integer', 'exists:pages,id'],
+ 'file' => $this->attachmentService->getFileValidationRules(),
+ 'link' => ['min:1', 'max:2000', 'safe_url'],
+ ],
+ ];
+ }
}