Skip to content

Commit

Permalink
Storage support for local disk (#165)
Browse files Browse the repository at this point in the history
* Storage support for local disk

* UI change ai feature page

---------

Co-authored-by: Julien Nahum <[email protected]>
  • Loading branch information
formsdev and JhumanJ authored Aug 16, 2023
1 parent c42c7ca commit 3c71be5
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 20 deletions.
28 changes: 28 additions & 0 deletions app/Http/Controllers/Content/FileUploadController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Http\Controllers\Content;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Forms\PublicFormController;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class FileUploadController extends Controller
{
/**
* Upload file to local temp
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function upload(Request $request)
{
$uuid = (string) Str::uuid();
$path = $request->file('file')->storeAs(PublicFormController::TMP_FILE_UPLOAD_PATH, $uuid);

return response()->json([
'uuid' => $uuid,
'key' => $path
], 201);
}
}
8 changes: 4 additions & 4 deletions app/Http/Controllers/Forms/FormController.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,12 @@ public function uploadAsset(UploadAssetRequest $request)

// Make sure we retrieve the file in tmp storage, move it to persistent
$fileName = PublicFormController::TMP_FILE_UPLOAD_PATH.'/'.$fileNameParser->uuid;;
if (!Storage::disk('s3')->exists($fileName)) {
if (!Storage::exists($fileName)) {
// File not found, we skip
return null;
}
$newPath = self::ASSETS_UPLOAD_PATH.'/'.$fileNameParser->getMovedFileName();
Storage::disk('s3')->move($fileName, $newPath);
Storage::move($fileName, $newPath);

return $this->success([
'message' => 'File uploaded.',
Expand All @@ -199,12 +199,12 @@ public function viewFile($id, $fileName)
$this->authorize('view', $form);

$path = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $form->id).'/'.$fileName;
if (!Storage::disk('s3')->exists($path)) {
if (!Storage::exists($path)) {
return $this->error([
'message' => 'File not found.'
]);
}

return redirect()->to(Storage::disk('s3')->temporaryUrl($path, now()->addMinutes(5)));
return redirect()->to(Storage::temporaryUrl($path, now()->addMinutes(5)));
}
}
4 changes: 2 additions & 2 deletions app/Http/Controllers/Forms/FormSubmissionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ public function submissionFile($id, $fileName)
$fileName = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $id).'/'
.urldecode($fileName);

if (!Storage::disk('s3')->exists($fileName)) {
if (!Storage::exists($fileName)) {
return $this->error([
'message' => 'File not found.',
], 404);
}

return redirect(
Storage::disk('s3')->temporaryUrl($fileName, now()->addMinute())
Storage::temporaryUrl($fileName, now()->addMinute())
);
}
}
6 changes: 3 additions & 3 deletions app/Http/Controllers/Forms/PublicFormController.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ public function listUsers(Request $request)
public function showAsset($assetFileName)
{
$path = FormController::ASSETS_UPLOAD_PATH.'/'.$assetFileName;
if (!Storage::disk('s3')->exists($path)) {
if (!Storage::exists($path)) {
return $this->error([
'message' => 'File not found.',
'file_name' => $assetFileName
]);
}

return redirect()->to(Storage::disk('s3')->temporaryUrl($path, now()->addMinutes(5)));
return redirect()->to(Storage::temporaryUrl($path, now()->addMinutes(5)));
}

public function answer(AnswerFormRequest $request)
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Middleware/VerifyCsrfToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class VerifyCsrfToken extends Middleware
*/
protected $except = [
'stripe/webhook',
'vapor/signed-storage-url'
'vapor/signed-storage-url',
'upload-file'
];
}
8 changes: 4 additions & 4 deletions app/Jobs/Form/StoreFormSubmissionJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ private function getFormData()
private function isSkipForUpload($value)
{
$newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id);
return Storage::disk('s3')->exists($newPath.'/'.$value);
return Storage::exists($newPath.'/'.$value);
}

/**
Expand All @@ -165,7 +165,7 @@ private function storeFile(?string $value)

// Make sure we retrieve the file in tmp storage, move it to persistent
$fileName = PublicFormController::TMP_FILE_UPLOAD_PATH.'/'.$fileNameParser->uuid;
if (!Storage::disk('s3')->exists($fileName)) {
if (!Storage::exists($fileName)) {
// File not found, we skip
return null;
}
Expand All @@ -178,7 +178,7 @@ private function storeFile(?string $value)
'form_id' => $this->form->id,
'form_slug' => $this->form->slug,
]);
Storage::disk('s3')->move($fileName, $completeNewFilename);
Storage::move($fileName, $completeNewFilename);

return $fileNameParser->getMovedFileName();
}
Expand All @@ -193,7 +193,7 @@ private function storeSignature(?string $value)
$newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id);
$completeNewFilename = $newPath.'/'.$fileName;

Storage::disk('s3')->put($completeNewFilename, base64_decode(explode(',', $value)[1]));
Storage::put($completeNewFilename, base64_decode(explode(',', $value)[1]));

return $fileName;
}
Expand Down
13 changes: 12 additions & 1 deletion app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
use Laravel\Cashier\Cashier;
use Laravel\Dusk\DuskServiceProvider;
use Illuminate\Support\Facades\Validator;

use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
class AppServiceProvider extends ServiceProvider
{
/**
Expand All @@ -18,6 +19,16 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot()
{
if(config('filesystems.default') === 'local'){
Storage::disk('local')->buildTemporaryUrlsUsing(function ($path, $expiration, $options) {
return URL::temporarySignedRoute(
'local.temp',
$expiration,
array_merge($options, ['path' => $path])
);
});
}

JsonResource::withoutWrapping();
Cashier::calculateTaxes();

Expand Down
2 changes: 1 addition & 1 deletion app/Rules/StorageFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function passes($attribute, $value): bool
// This is use when updating a record, and file uploads aren't changed.
if($this->form){
$newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id);
if(Storage::disk('s3')->exists($newPath.'/'.$value)){
if(Storage::exists($newPath.'/'.$value)){
return true;
}
}
Expand Down
9 changes: 6 additions & 3 deletions resources/js/components/pages/welcome/AiFeature.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,16 @@
</li>
</ul>

<div class="mt-6 sm:mt-8 flex">
<v-button v-if="!authenticated" class="mr-1" :to="{ name: 'forms.create.guest' }" :arrow="true">
<div class="mt-6 sm:mt-8 flex text-center justify-center lg:justify-start">
<v-button v-if="!authenticated" class="mr-2 block" :to="{ name: 'forms.create.guest' }" :arrow="true">
Get started for free
</v-button>
<v-button v-else class="mr-1" :to="{ name: 'forms.create' }" :arrow="true">
<v-button v-else class="mr-2 block" :to="{ name: 'forms.create' }" :arrow="true">
Get started for free
</v-button>
<v-button color="light-gray" class="mr-1 block" :to="{ name: 'aiformbuilder' }">
Learn more
</v-button>
</div>
</div>

Expand Down
20 changes: 20 additions & 0 deletions resources/js/plugins/vapor.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@ Vue.mixin({
* Store a file in S3 and return its UUID, key, and other information.
*/
async storeFile (file, options = {}) {
if(!window.config.s3_enabled) { // If not s3 then upload to local temp
if (typeof options.progress === 'undefined') {
options.progress = () => {}
}
const cleanAxios = axios.create()
let formData = new FormData();
formData.append('file', file);
const response = await cleanAxios.post('/upload-file', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: (progressEvent) => {
options.progress(progressEvent.loaded / progressEvent.total)
}
})

response.data.extension = file.name.split('.').pop()
return response.data
}

const response = await axios.post(options.signedStorageUrl ? options.signedStorageUrl : '/vapor/signed-storage-url', {
bucket: options.bucket || '',
content_type: options.contentType || file.type,
Expand Down
3 changes: 2 additions & 1 deletion resources/views/spa.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
'google_analytics_code' => config('services.google_analytics_code'),
'amplitude_code' => config('services.amplitude_code'),
'crisp_website_id' => config('services.crisp_website_id'),
'ai_features_enabled' => !is_null(config('services.openai.api_key'))
'ai_features_enabled' => !is_null(config('services.openai.api_key')),
's3_enabled' => config('filesystems.default') === 's3'
];
@endphp
<!DOCTYPE html>
Expand Down
15 changes: 15 additions & 0 deletions routes/web.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
Expand All @@ -22,4 +24,17 @@
'/vapor/signed-storage-url',
[\App\Http\Controllers\Content\SignedStorageUrlController::class, 'store']
)->middleware([]);
Route::post(
'/upload-file',
[\App\Http\Controllers\Content\FileUploadController::class, 'upload']
)->middleware([]);
Route::get('local/temp/{path}', function (Request $request, string $path){
if (!$request->hasValidSignature()) {
abort(401);
}
$response = Response::make(Storage::get($path), 200);
$response->header("Content-Type", Storage::mimeType($path));
return $response;
})->where('path', '(.*)')->name('local.temp');

Route::get('/sitemap.xml', [\App\Http\Controllers\SitemapController::class, 'getSitemap'])->name('sitemap');

0 comments on commit 3c71be5

Please sign in to comment.