217 lines
7.3 KiB
PHP
217 lines
7.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Forms;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\StoreFormRequest;
|
|
use App\Http\Requests\UpdateFormRequest;
|
|
use App\Http\Requests\UploadAssetRequest;
|
|
use App\Http\Resources\FormResource;
|
|
use App\Models\Forms\Form;
|
|
use App\Models\Workspace;
|
|
use App\Service\Forms\FormCleaner;
|
|
use App\Service\Storage\StorageFileNameParser;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
|
|
class FormController extends Controller
|
|
{
|
|
const ASSETS_UPLOAD_PATH = 'assets/forms';
|
|
|
|
private FormCleaner $formCleaner;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->middleware('auth');
|
|
$this->formCleaner = new FormCleaner();
|
|
}
|
|
|
|
public function index($workspaceId)
|
|
{
|
|
$workspace = Workspace::findOrFail($workspaceId);
|
|
$this->authorize('view', $workspace);
|
|
$this->authorize('viewAny', Form::class);
|
|
|
|
$workspaceIsPro = $workspace->is_pro;
|
|
$forms = $workspace->forms()->with(['creator','views','submissions'])
|
|
->orderByDesc('updated_at')
|
|
->paginate(10)->through(function (Form $form) use ($workspace, $workspaceIsPro){
|
|
|
|
// Add attributes for faster loading
|
|
$form->extra = (object) [
|
|
'loadedWorkspace' => $workspace,
|
|
'workspaceIsPro' => $workspaceIsPro,
|
|
'userIsOwner' => true,
|
|
'cleanings' => $this->formCleaner
|
|
->processForm(request(), $form)
|
|
->simulateCleaning($workspace)
|
|
->getPerformedCleanings()
|
|
];
|
|
|
|
return $form;
|
|
});
|
|
return FormResource::collection($forms);
|
|
}
|
|
|
|
/**
|
|
* Return all user forms, used for zapier
|
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
*/
|
|
public function indexAll()
|
|
{
|
|
$forms = collect();
|
|
foreach (Auth::user()->workspaces as $workspace) {
|
|
$this->authorize('view', $workspace);
|
|
$this->authorize('viewAny', Form::class);
|
|
|
|
$workspaceIsPro = $workspace->is_pro;
|
|
$newForms = $workspace->forms()->with(['creator','views','submissions'])->get()->map(function (Form $form) use ($workspace, $workspaceIsPro){
|
|
// Add attributes for faster loading
|
|
$form->extra = (object) [
|
|
'loadedWorkspace' => $workspace,
|
|
'workspaceIsPro' => $workspaceIsPro,
|
|
'userIsOwner' => true,
|
|
];
|
|
return $form;
|
|
});
|
|
|
|
$forms = $forms->merge($newForms);
|
|
}
|
|
return FormResource::collection($forms);
|
|
}
|
|
|
|
public function store(StoreFormRequest $request)
|
|
{
|
|
$this->authorize('create', Form::class);
|
|
|
|
$workspace = Workspace::findOrFail($request->get('workspace_id'));
|
|
$this->authorize('view', $workspace);
|
|
|
|
$formData = $this->formCleaner
|
|
->processRequest($request)
|
|
->simulateCleaning($workspace)
|
|
->getData();
|
|
|
|
$form = Form::create(array_merge($formData, [
|
|
'creator_id' => $request->user()->id
|
|
]));
|
|
|
|
return $this->success([
|
|
'message' => $this->formCleaner->hasCleaned() ? 'Form successfully created, but the Pro features you used will be disabled when sharing your form:' : 'Form created.' . ($form->visibility == 'draft' ? ' But other people won\'t be able to see the form since it\'s currently in draft mode' : ''),
|
|
'form' => (new FormResource($form))->setCleanings($this->formCleaner->getPerformedCleanings()),
|
|
'users_first_form' => $request->user()->forms()->count() == 1
|
|
]);
|
|
}
|
|
|
|
public function update(UpdateFormRequest $request, string $id)
|
|
{
|
|
$form = Form::findOrFail($id);
|
|
$this->authorize('update', $form);
|
|
|
|
$formData = $this->formCleaner
|
|
->processRequest($request)
|
|
->simulateCleaning($form->workspace)
|
|
->getData();
|
|
|
|
// Set Removed Properties
|
|
$formData['removed_properties'] = array_merge($form->removed_properties, collect($form->properties)->filter(function ($field) use ($formData) {
|
|
return (!Str::of($field['type'])->startsWith('nf-') && !in_array($field['id'], collect($formData['properties'])->pluck("id")->toArray()));
|
|
})->toArray());
|
|
|
|
$form->update($formData);
|
|
|
|
return $this->success([
|
|
'message' => $this->formCleaner->hasCleaned() ? 'Form successfully updated, but the Pro features you used will be disabled when sharing your form:' : 'Form updated.' . ($form->visibility == 'draft' ? ' But other people won\'t be able to see the form since it\'s currently in draft mode' : ''),
|
|
'form' => (new FormResource($form))->setCleanings($this->formCleaner->getPerformedCleanings()),
|
|
]);
|
|
}
|
|
|
|
public function destroy($id)
|
|
{
|
|
$form = Form::findOrFail($id);
|
|
$this->authorize('delete', $form);
|
|
|
|
$form->delete();
|
|
return $this->success([
|
|
'message' => 'Form was deleted.'
|
|
]);
|
|
}
|
|
|
|
public function duplicate($id)
|
|
{
|
|
$form = Form::findOrFail($id);
|
|
$this->authorize('update', $form);
|
|
|
|
// Create copy
|
|
$formCopy = $form->replicate();
|
|
$formCopy->title = 'Copy of '.$formCopy->title;
|
|
$formCopy->save();
|
|
|
|
return $this->success([
|
|
'message' => 'Form successfully duplicated.',
|
|
'new_form' => new FormResource($formCopy)
|
|
]);
|
|
}
|
|
|
|
public function regenerateLink($id, $option)
|
|
{
|
|
$form = Form::findOrFail($id);
|
|
$this->authorize('update', $form);
|
|
|
|
if ( $option == 'slug') {
|
|
$form->generateSlug();
|
|
} elseif ($option == 'uuid') {
|
|
$form->slug = Str::uuid();
|
|
}
|
|
$form->save();
|
|
|
|
return $this->success([
|
|
'message' => 'Form url successfully updated. Your new form url now is: '.$form->share_url.'.',
|
|
'form' => new FormResource($form)
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Upload a form asset
|
|
*/
|
|
public function uploadAsset(UploadAssetRequest $request)
|
|
{
|
|
$this->authorize('viewAny', Form::class);
|
|
|
|
$fileNameParser = StorageFileNameParser::parse($request->url);
|
|
|
|
// Make sure we retrieve the file in tmp storage, move it to persistent
|
|
$fileName = PublicFormController::TMP_FILE_UPLOAD_PATH.'/'.$fileNameParser->uuid;;
|
|
if (!Storage::exists($fileName)) {
|
|
// File not found, we skip
|
|
return null;
|
|
}
|
|
$newPath = self::ASSETS_UPLOAD_PATH.'/'.$fileNameParser->getMovedFileName();
|
|
Storage::move($fileName, $newPath);
|
|
|
|
return $this->success([
|
|
'message' => 'File uploaded.',
|
|
'url' => route("forms.assets.show", [$fileNameParser->getMovedFileName()])
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* File uploads retrieval
|
|
*/
|
|
public function viewFile($id, $fileName)
|
|
{
|
|
$form = Form::findOrFail($id);
|
|
$this->authorize('view', $form);
|
|
|
|
$path = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $form->id).'/'.$fileName;
|
|
if (!Storage::exists($path)) {
|
|
return $this->error([
|
|
'message' => 'File not found.'
|
|
]);
|
|
}
|
|
|
|
return redirect()->to(Storage::temporaryUrl($path, now()->addMinutes(5)));
|
|
}
|
|
}
|