Separated laravel app to its own folder (#540)
This commit is contained in:
20
api/app/Http/Requests/AiGenerateFormRequest.php
Normal file
20
api/app/Http/Requests/AiGenerateFormRequest.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class AiGenerateFormRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'form_prompt' => 'required|string|max:1000',
|
||||
];
|
||||
}
|
||||
}
|
||||
281
api/app/Http/Requests/AnswerFormRequest.php
Normal file
281
api/app/Http/Requests/AnswerFormRequest.php
Normal file
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use App\Rules\CustomFieldValidationRule;
|
||||
use App\Rules\MatrixValidationRule;
|
||||
use App\Rules\StorageFile;
|
||||
use App\Rules\ValidHCaptcha;
|
||||
use App\Rules\ValidPhoneInputRule;
|
||||
use App\Rules\ValidUrl;
|
||||
use App\Service\Forms\FormLogicPropertyResolver;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class AnswerFormRequest extends FormRequest
|
||||
{
|
||||
public Form $form;
|
||||
|
||||
protected array $requestRules = [];
|
||||
|
||||
protected int $maxFileSize;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->form = $request->form;
|
||||
$this->maxFileSize = $this->form->workspace->max_file_size;
|
||||
}
|
||||
|
||||
private function getFieldMaxFileSize($fieldProps)
|
||||
{
|
||||
return array_key_exists('max_file_size', $fieldProps) ?
|
||||
min($fieldProps['max_file_size'] * 1000000, $this->maxFileSize) : $this->maxFileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate form before use it
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return !$this->form->is_closed && !$this->form->max_number_of_submissions_reached && $this->form->visibility === 'public';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the form.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$selectionFields = collect($this->form->properties)->filter(function ($pro) {
|
||||
return in_array($pro['type'], ['select', 'multi_select']);
|
||||
});
|
||||
foreach ($this->form->properties as $property) {
|
||||
$rules = [];
|
||||
/*if (!$this->form->is_pro) { // If not pro then not check logic
|
||||
$property['logic'] = false;
|
||||
}*/
|
||||
|
||||
// For get values instead of Id for select/multi select options
|
||||
$data = $this->toArray();
|
||||
foreach ($selectionFields as $field) {
|
||||
if (isset($data[$field['id']]) && is_array($data[$field['id']])) {
|
||||
$data[$field['id']] = array_map(function ($val) use ($field) {
|
||||
$tmpop = collect($field[$field['type']]['options'])->first(function ($op) use ($val) {
|
||||
return $op['id'] ?? $op['value'] === $val;
|
||||
});
|
||||
|
||||
return isset($tmpop['name']) ? $tmpop['name'] : '';
|
||||
}, $data[$field['id']]);
|
||||
}
|
||||
}
|
||||
if (FormLogicPropertyResolver::isRequired($property, $data)) {
|
||||
$rules[] = 'required';
|
||||
|
||||
if ($property['type'] == 'checkbox') {
|
||||
// Required for checkboxes means true
|
||||
$rules[] = 'accepted';
|
||||
} elseif ($property['type'] == 'rating') {
|
||||
// For star rating, needs a minimum of 1 star
|
||||
$rules[] = 'min:1';
|
||||
} elseif ($property['type'] == 'matrix') {
|
||||
$rules[] = new MatrixValidationRule($property, true);
|
||||
}
|
||||
} else {
|
||||
$rules[] = 'nullable';
|
||||
if ($property['type'] == 'matrix') {
|
||||
$rules[] = new MatrixValidationRule($property, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean id to escape "."
|
||||
$propertyId = $property['id'];
|
||||
if (in_array($property['type'], ['multi_select'])) {
|
||||
$rules[] = 'array';
|
||||
$this->requestRules[$propertyId . '.*'] = $this->getPropertyRules($property);
|
||||
} else {
|
||||
$rules = array_merge($rules, $this->getPropertyRules($property));
|
||||
}
|
||||
|
||||
// User custom validation
|
||||
if (!(Str::of($property['type'])->startsWith('nf-')) && isset($property['validation'])) {
|
||||
$rules[] = (new CustomFieldValidationRule($property['validation'], $data));
|
||||
}
|
||||
|
||||
$this->requestRules[$propertyId] = $rules;
|
||||
}
|
||||
|
||||
// Validate hCaptcha
|
||||
if ($this->form->use_captcha) {
|
||||
$this->requestRules['h-captcha-response'] = [new ValidHCaptcha()];
|
||||
}
|
||||
|
||||
// Validate submission_id for edit mode
|
||||
if ($this->form->is_pro && $this->form->editable_submissions) {
|
||||
$this->requestRules['submission_id'] = 'string';
|
||||
}
|
||||
|
||||
return $this->requestRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames validated fields (because field names are ids)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes()
|
||||
{
|
||||
$fields = [];
|
||||
foreach ($this->form->properties as $property) {
|
||||
$fields[$property['id']] = $property['name'];
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation messages that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages()
|
||||
{
|
||||
$messages = [];
|
||||
foreach ($this->form->properties as $property) {
|
||||
if ($property['type'] == 'date' && isset($property['date_range']) && $property['date_range']) {
|
||||
$messages[$property['id'] . '.0.required_with'] = 'From date is required';
|
||||
$messages[$property['id'] . '.1.required_with'] = 'To date is required';
|
||||
$messages[$property['id'] . '.0.before_or_equal'] = 'From date must be before or equal To date';
|
||||
}
|
||||
if ($property['type'] == 'rating') {
|
||||
$messages[$property['id'] . '.min'] = 'A rating must be selected';
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return validation rules for a given form property
|
||||
*/
|
||||
private function getPropertyRules($property): array
|
||||
{
|
||||
switch ($property['type']) {
|
||||
case 'text':
|
||||
case 'signature':
|
||||
return ['string'];
|
||||
case 'number':
|
||||
case 'rating':
|
||||
case 'scale':
|
||||
case 'slider':
|
||||
return ['numeric'];
|
||||
case 'select':
|
||||
case 'multi_select':
|
||||
if (($property['allow_creation'] ?? false)) {
|
||||
return ['string'];
|
||||
}
|
||||
|
||||
return [Rule::in($this->getSelectPropertyOptions($property))];
|
||||
case 'checkbox':
|
||||
return ['boolean'];
|
||||
case 'url':
|
||||
if (isset($property['file_upload']) && $property['file_upload']) {
|
||||
$this->requestRules[$property['id'] . '.*'] = [new StorageFile($this->maxFileSize, [], $this->form)];
|
||||
|
||||
return ['array'];
|
||||
}
|
||||
|
||||
return [new ValidUrl()];
|
||||
case 'files':
|
||||
$allowedFileTypes = [];
|
||||
if (!empty($property['allowed_file_types'])) {
|
||||
$allowedFileTypes = explode(',', $property['allowed_file_types']);
|
||||
}
|
||||
$this->requestRules[$property['id'] . '.*'] = [new StorageFile($this->getFieldMaxFileSize($property), $allowedFileTypes, $this->form)];
|
||||
|
||||
return ['array'];
|
||||
case 'email':
|
||||
return ['email:filter'];
|
||||
case 'date':
|
||||
if (isset($property['date_range']) && $property['date_range']) {
|
||||
$this->requestRules[$property['id'] . '.*'] = $this->getRulesForDate($property);
|
||||
$this->requestRules[$property['id'] . '.0'] = ['required_with:' . $property['id'] . '.1', 'before_or_equal:' . $property['id'] . '.1'];
|
||||
$this->requestRules[$property['id'] . '.1'] = ['required_with:' . $property['id'] . '.0'];
|
||||
|
||||
return ['array', 'min:2'];
|
||||
}
|
||||
|
||||
return $this->getRulesForDate($property);
|
||||
case 'phone_number':
|
||||
if (isset($property['use_simple_text_input']) && $property['use_simple_text_input']) {
|
||||
return ['string'];
|
||||
}
|
||||
|
||||
return ['string', 'min:6', new ValidPhoneInputRule()];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private function getRulesForDate($property)
|
||||
{
|
||||
if (isset($property['disable_past_dates']) && $property['disable_past_dates']) {
|
||||
return ['date', 'after:yesterday'];
|
||||
} elseif (isset($property['disable_future_dates']) && $property['disable_future_dates']) {
|
||||
return ['date', 'before:tomorrow'];
|
||||
}
|
||||
|
||||
return ['date'];
|
||||
}
|
||||
|
||||
private function getSelectPropertyOptions($property): array
|
||||
{
|
||||
$type = $property['type'];
|
||||
if (!isset($property[$type])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_column($property[$type]['options'], 'name');
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$receivedData = $this->toArray();
|
||||
$mergeData = [];
|
||||
$countryCodeMapper = json_decode(file_get_contents(resource_path('data/country_code_mapper.json')), true);
|
||||
collect($this->form->properties)->each(function ($property) use ($countryCodeMapper, $receivedData, &$mergeData) {
|
||||
$receivedValue = $receivedData[$property['id']] ?? null;
|
||||
|
||||
// Escape all '\' in select options
|
||||
if (in_array($property['type'], ['select', 'multi_select']) && !is_null($receivedValue)) {
|
||||
if (is_array($receivedValue)) {
|
||||
$mergeData[$property['id']] = collect($receivedValue)->map(function ($value) {
|
||||
$value = Str::of($value);
|
||||
|
||||
return $value->replace(
|
||||
["\e", "\f", "\n", "\r", "\t", "\v", '\\'],
|
||||
['\\e', '\\f', '\\n', '\\r', '\\t', '\\v', '\\\\']
|
||||
)->toString();
|
||||
})->toArray();
|
||||
} else {
|
||||
$receivedValue = Str::of($receivedValue);
|
||||
$mergeData[$property['id']] = $receivedValue->replace(
|
||||
["\e", "\f", "\n", "\r", "\t", "\v", '\\'],
|
||||
['\\e', '\\f', '\\n', '\\r', '\\t', '\\v', '\\\\']
|
||||
)->toString();
|
||||
}
|
||||
}
|
||||
|
||||
if ($property['type'] === 'phone_number' && (!isset($property['use_simple_text_input']) || !$property['use_simple_text_input']) && $receivedValue && in_array($receivedValue, $countryCodeMapper)) {
|
||||
$mergeData[$property['id']] = null;
|
||||
}
|
||||
});
|
||||
|
||||
$this->merge($mergeData);
|
||||
}
|
||||
}
|
||||
22
api/app/Http/Requests/CreateTokenRequest.php
Normal file
22
api/app/Http/Requests/CreateTokenRequest.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CreateTokenRequest extends FormRequest
|
||||
{
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
],
|
||||
'abilities' => [
|
||||
'nullable',
|
||||
'array'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Integration;
|
||||
|
||||
use App\Models\Integration\FormIntegration;
|
||||
use App\Rules\IntegrationLogicRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class FormIntegrationsRequest extends FormRequest
|
||||
{
|
||||
public array $integrationRules = [];
|
||||
|
||||
private ?string $integrationClassName = null;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
if ($request->integration_id) {
|
||||
// Load integration class, and get rules
|
||||
$integration = FormIntegration::getIntegration($request->integration_id);
|
||||
if ($integration && isset($integration['file_name']) && class_exists(
|
||||
'App\Integrations\Handlers\\' . $integration['file_name']
|
||||
)) {
|
||||
$this->integrationClassName = 'App\Integrations\Handlers\\' . $integration['file_name'];
|
||||
$this->loadIntegrationRules();
|
||||
return;
|
||||
}
|
||||
throw new \Exception('Unknown Integration!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return array_merge([
|
||||
'integration_id' => ['required', Rule::in(array_keys(FormIntegration::getAllIntegrations()))],
|
||||
'oauth_id' => [
|
||||
$this->isOAuthRequired() ? 'required' : 'nullable',
|
||||
Rule::exists('oauth_providers', 'id')
|
||||
],
|
||||
'settings' => 'present|array',
|
||||
'status' => 'required|boolean',
|
||||
'logic' => [new IntegrationLogicRule()],
|
||||
], $this->integrationRules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the validated fields a better "human-readable" name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes()
|
||||
{
|
||||
$attributes = $this->integrationClassName::getValidationAttributes();
|
||||
|
||||
$fields = [];
|
||||
foreach ($this->rules() as $key => $value) {
|
||||
$fields[$key] = $attributes[$key] ?? Str::of($key)
|
||||
->replace('settings.', '')
|
||||
->headline()
|
||||
->toString();
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function isOAuthRequired(): bool
|
||||
{
|
||||
return $this->integrationClassName::isOAuthRequired();
|
||||
}
|
||||
|
||||
private function loadIntegrationRules()
|
||||
{
|
||||
foreach ($this->integrationClassName::getValidationRules() as $key => $value) {
|
||||
$this->integrationRules['settings.' . $key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function toIntegrationData(): array
|
||||
{
|
||||
return $this->integrationClassName::formatData([
|
||||
'status' => ($this->validated(
|
||||
'status'
|
||||
)) ? FormIntegration::STATUS_ACTIVE : FormIntegration::STATUS_INACTIVE,
|
||||
'integration_id' => $this->validated('integration_id'),
|
||||
'data' => $this->validated('settings') ?? [],
|
||||
'logic' => $this->validated('logic') ?? [],
|
||||
'oauth_id' => $this->validated('oauth_id'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Integration;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use App\Models\Integration\FormZapierWebhook;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreFormZapierWebhookRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'form_slug' => 'required|exists:forms,slug',
|
||||
'hook_url' => 'required|string|url',
|
||||
];
|
||||
}
|
||||
|
||||
public function instanciateHook()
|
||||
{
|
||||
$form = Form::whereSlug($this->form_slug)->firstOrFail();
|
||||
|
||||
return new FormZapierWebhook([
|
||||
'form_id' => $form->id,
|
||||
'hook_url' => $this->hook_url,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Integration\Zapier;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class PollSubmissionRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'form_id' => [
|
||||
'required',
|
||||
Rule::exists(Form::getModel()->getTable(), 'id'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function form(): Form
|
||||
{
|
||||
return Form::findOrFail($this->input('form_id'));
|
||||
}
|
||||
}
|
||||
18
api/app/Http/Requests/StoreFormRequest.php
Normal file
18
api/app/Http/Requests/StoreFormRequest.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
class StoreFormRequest extends UserFormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return array_merge(parent::rules(), [// Info about database
|
||||
'workspace_id' => 'required|exists:workspaces,id',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Subscriptions;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateStripeDetailsRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string',
|
||||
'email' => 'required|email',
|
||||
];
|
||||
}
|
||||
}
|
||||
87
api/app/Http/Requests/Templates/FormTemplateRequest.php
Normal file
87
api/app/Http/Requests/Templates/FormTemplateRequest.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Templates;
|
||||
|
||||
use App\Models\Template;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class FormTemplateRequest extends FormRequest
|
||||
{
|
||||
public const IGNORED_KEYS = [
|
||||
'id',
|
||||
'creator',
|
||||
'cleanings',
|
||||
'closes_at',
|
||||
'deleted_at',
|
||||
'updated_at',
|
||||
'form_pending_submission_key',
|
||||
'is_closed',
|
||||
'is_pro',
|
||||
'is_password_protected',
|
||||
'last_edited_human',
|
||||
'max_number_of_submissions_reached',
|
||||
'removed_properties',
|
||||
'creator_id',
|
||||
'extra',
|
||||
'workspace',
|
||||
'workspace_id',
|
||||
'submissions',
|
||||
'submissions_count',
|
||||
'views',
|
||||
'views_count',
|
||||
'visibility',
|
||||
'webhook_url',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$slugRule = '';
|
||||
if ($this->id) {
|
||||
$slugRule = ',' . $this->id;
|
||||
}
|
||||
|
||||
return [
|
||||
'form' => 'required|array',
|
||||
'publicly_listed' => 'boolean',
|
||||
'name' => 'required|string|max:60',
|
||||
'slug' => 'required|string|alpha_dash|unique:templates,slug' . $slugRule,
|
||||
'short_description' => 'required|string|max:1000',
|
||||
'description' => 'required|string',
|
||||
'image_url' => 'required|string',
|
||||
'types' => 'nullable|array',
|
||||
'industries' => 'nullable|array',
|
||||
'related_templates' => 'nullable|array',
|
||||
'questions' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
public function getTemplate(): Template
|
||||
{
|
||||
$structure = $this->form;
|
||||
foreach ($structure as $key => $val) {
|
||||
if (in_array($key, self::IGNORED_KEYS)) {
|
||||
unset($structure[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return new Template([
|
||||
'creator_id' => $this->user()?->id ?? null,
|
||||
'publicly_listed' => $this->publicly_listed,
|
||||
'name' => $this->name,
|
||||
'slug' => $this->slug,
|
||||
'short_description' => $this->short_description,
|
||||
'description' => $this->description,
|
||||
'image_url' => $this->image_url,
|
||||
'structure' => $structure,
|
||||
'types' => $this->types ?? [],
|
||||
'industries' => $this->industries ?? [],
|
||||
'related_templates' => $this->related_templates ?? [],
|
||||
'questions' => $this->questions ?? [],
|
||||
]);
|
||||
}
|
||||
}
|
||||
7
api/app/Http/Requests/UpdateFormRequest.php
Normal file
7
api/app/Http/Requests/UpdateFormRequest.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
class UpdateFormRequest extends UserFormRequest
|
||||
{
|
||||
}
|
||||
35
api/app/Http/Requests/UploadAssetRequest.php
Normal file
35
api/app/Http/Requests/UploadAssetRequest.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Rules\StorageFile;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UploadAssetRequest extends FormRequest
|
||||
{
|
||||
public const FORM_ASSET_MAX_SIZE = 5000000;
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$fileTypes = [
|
||||
'png',
|
||||
'jpeg',
|
||||
'jpg',
|
||||
'bmp',
|
||||
'gif',
|
||||
'svg',
|
||||
];
|
||||
if ($this->offsetExists('type') && $this->get('type') === 'files') {
|
||||
$fileTypes = [];
|
||||
}
|
||||
|
||||
return [
|
||||
'url' => ['required', new StorageFile(self::FORM_ASSET_MAX_SIZE, $fileTypes)],
|
||||
];
|
||||
}
|
||||
}
|
||||
140
api/app/Http/Requests/UserFormRequest.php
Normal file
140
api/app/Http/Requests/UserFormRequest.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Workspace\CustomDomainRequest;
|
||||
use App\Models\Forms\Form;
|
||||
use App\Rules\FormPropertyLogicRule;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Abstract class to validate create/update forms
|
||||
*
|
||||
* Class UserFormRequest
|
||||
*/
|
||||
abstract class UserFormRequest extends \Illuminate\Foundation\Http\FormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
// Form Info
|
||||
'title' => 'required|string|max:60',
|
||||
'description' => 'nullable|string|max:2000',
|
||||
'tags' => 'nullable|array',
|
||||
'visibility' => ['required', Rule::in(Form::VISIBILITY)],
|
||||
|
||||
// Customization
|
||||
'font_family' => 'string|nullable',
|
||||
'theme' => ['required', Rule::in(Form::THEMES)],
|
||||
'width' => ['required', Rule::in(Form::WIDTHS)],
|
||||
'size' => ['required', Rule::in(Form::SIZES)],
|
||||
'border_radius' => ['required', Rule::in(Form::BORDER_RADIUS)],
|
||||
'cover_picture' => 'url|nullable',
|
||||
'logo_picture' => 'url|nullable',
|
||||
'dark_mode' => ['required', Rule::in(Form::DARK_MODE_VALUES)],
|
||||
'color' => 'required|string',
|
||||
'hide_title' => 'required|boolean',
|
||||
'uppercase_labels' => 'required|boolean',
|
||||
'no_branding' => 'required|boolean',
|
||||
'transparent_background' => 'required|boolean',
|
||||
'closes_at' => 'date|nullable',
|
||||
'closed_text' => 'string|nullable',
|
||||
|
||||
// Custom Code
|
||||
'custom_code' => 'string|nullable',
|
||||
|
||||
// Submission
|
||||
'submit_button_text' => 'string|min:1|max:50',
|
||||
're_fillable' => 'boolean',
|
||||
're_fill_button_text' => 'string|min:1|max:50',
|
||||
'submitted_text' => 'string|max:2000',
|
||||
'redirect_url' => 'nullable|active_url|max:255',
|
||||
'database_fields_update' => 'nullable|array',
|
||||
'max_submissions_count' => 'integer|nullable|min:1',
|
||||
'max_submissions_reached_text' => 'string|nullable',
|
||||
'editable_submissions' => 'boolean|nullable',
|
||||
'editable_submissions_button_text' => 'string|min:1|max:50',
|
||||
'confetti_on_submission' => 'boolean',
|
||||
'show_progress_bar' => 'boolean',
|
||||
'auto_save' => 'boolean',
|
||||
'auto_focus' => 'boolean',
|
||||
|
||||
// Properties
|
||||
'properties' => 'required|array',
|
||||
'properties.*.id' => 'required',
|
||||
'properties.*.name' => 'required',
|
||||
'properties.*.type' => 'required',
|
||||
'properties.*.placeholder' => 'sometimes|nullable',
|
||||
'properties.*.prefill' => 'sometimes|nullable',
|
||||
'properties.*.help' => 'sometimes|nullable',
|
||||
'properties.*.help_position' => ['sometimes', Rule::in(['below_input', 'above_input'])],
|
||||
'properties.*.hidden' => 'boolean|nullable',
|
||||
'properties.*.required' => 'boolean|nullable',
|
||||
'properties.*.multiple' => 'boolean|nullable',
|
||||
'properties.*.timezone' => 'sometimes|nullable',
|
||||
'properties.*.width' => ['sometimes', Rule::in(['full', '1/2', '1/3', '2/3', '1/3', '3/4', '1/4'])],
|
||||
'properties.*.align' => ['sometimes', Rule::in(['left', 'center', 'right', 'justify'])],
|
||||
'properties.*.allowed_file_types' => 'sometimes|nullable',
|
||||
'properties.*.use_toggle_switch' => 'boolean|nullable',
|
||||
|
||||
// Logic
|
||||
'properties.*.logic' => ['array', 'nullable', new FormPropertyLogicRule()],
|
||||
|
||||
// Form blocks
|
||||
'properties.*.content' => 'sometimes|nullable',
|
||||
|
||||
// Text field
|
||||
'properties.*.multi_lines' => 'boolean|nullable',
|
||||
'properties.*.max_char_limit' => 'integer|nullable|min:1|max:2000',
|
||||
'properties.*.show_char_limit ' => 'boolean|nullable',
|
||||
'properties.*.secret_input' => 'boolean|nullable',
|
||||
|
||||
// Date field
|
||||
'properties.*.with_time' => 'boolean|nullable',
|
||||
'properties.*.date_range' => 'boolean|nullable',
|
||||
'properties.*.prefill_today' => 'boolean|nullable',
|
||||
'properties.*.disable_past_dates' => 'boolean|nullable',
|
||||
'properties.*.disable_future_dates' => 'boolean|nullable',
|
||||
|
||||
// Select / Multi Select field
|
||||
'properties.*.allow_creation' => 'boolean|nullable',
|
||||
'properties.*.without_dropdown' => 'boolean|nullable',
|
||||
|
||||
// Advanced Options
|
||||
'properties.*.generates_uuid' => 'boolean|nullable',
|
||||
'properties.*.generates_auto_increment_id' => 'boolean|nullable',
|
||||
|
||||
// For file (min and max)
|
||||
'properties.*.max_file_size' => 'min:1|numeric',
|
||||
|
||||
// Security & Privacy
|
||||
'can_be_indexed' => 'boolean',
|
||||
'password' => 'sometimes|nullable',
|
||||
'use_captcha' => 'boolean',
|
||||
|
||||
// Custom SEO
|
||||
'seo_meta' => 'nullable|array',
|
||||
'custom_domain' => 'sometimes|nullable|regex:' . CustomDomainRequest::CUSTOM_DOMAINS_REGEX,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation messages that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'properties.*.name.required' => 'The form block number :position is missing a name.',
|
||||
'properties.*.type.required' => 'The form block number :position is missing a type.',
|
||||
'properties.*.max_char_limit.min' => 'The form block number :position max character limit must be at least 1 OR Empty',
|
||||
'properties.*.max_char_limit.max' => 'The form block number :position max character limit may not be greater than 2000.',
|
||||
];
|
||||
}
|
||||
}
|
||||
62
api/app/Http/Requests/Workspace/CustomDomainRequest.php
Normal file
62
api/app/Http/Requests/Workspace/CustomDomainRequest.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Workspace;
|
||||
|
||||
use App\Models\Workspace;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CustomDomainRequest extends FormRequest
|
||||
{
|
||||
public const CUSTOM_DOMAINS_REGEX = '/^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,20}$/';
|
||||
|
||||
public Workspace $workspace;
|
||||
|
||||
public array $customDomains = [];
|
||||
|
||||
public function __construct(Request $request, Workspace $workspace)
|
||||
{
|
||||
$this->workspace = Workspace::findOrFail($request->workspaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'custom_domains' => [
|
||||
'present',
|
||||
'array',
|
||||
function ($attribute, $value, $fail) {
|
||||
$errors = [];
|
||||
$domains = collect($value)->filter(function ($domain) {
|
||||
return ! empty(trim($domain));
|
||||
})->each(function ($domain) use (&$errors) {
|
||||
if (! preg_match(self::CUSTOM_DOMAINS_REGEX, $domain)) {
|
||||
$errors[] = 'Invalid domain: '.$domain;
|
||||
}
|
||||
});
|
||||
|
||||
if (count($errors)) {
|
||||
$fail($errors);
|
||||
}
|
||||
|
||||
$limit = $this->workspace->custom_domain_count_limit;
|
||||
if ($limit && $domains->count() > $limit) {
|
||||
$fail('You can only add '.$limit.' domain(s).');
|
||||
}
|
||||
|
||||
$this->customDomains = $domains->toArray();
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
protected function passedValidation()
|
||||
{
|
||||
$this->replace(['custom_domains' => $this->customDomains]);
|
||||
}
|
||||
}
|
||||
29
api/app/Http/Requests/Zapier/CreateIntegrationRequest.php
Normal file
29
api/app/Http/Requests/Zapier/CreateIntegrationRequest.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Zapier;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class CreateIntegrationRequest extends FormRequest
|
||||
{
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'form_id' => [
|
||||
'required',
|
||||
Rule::exists(Form::getModel()->getTable(), 'id'),
|
||||
],
|
||||
'hookUrl' => [
|
||||
'required',
|
||||
'url',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function form(): Form
|
||||
{
|
||||
return Form::findOrFail($this->input('form_id'));
|
||||
}
|
||||
}
|
||||
29
api/app/Http/Requests/Zapier/DeleteIntegrationRequest.php
Normal file
29
api/app/Http/Requests/Zapier/DeleteIntegrationRequest.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Zapier;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class DeleteIntegrationRequest extends FormRequest
|
||||
{
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'form_id' => [
|
||||
'required',
|
||||
Rule::exists(Form::getModel()->getTable(), 'id'),
|
||||
],
|
||||
'hookUrl' => [
|
||||
'required',
|
||||
'url',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function form(): Form
|
||||
{
|
||||
return Form::findOrFail($this->input('form_id'));
|
||||
}
|
||||
}
|
||||
25
api/app/Http/Requests/Zapier/ListFormsRequest.php
Normal file
25
api/app/Http/Requests/Zapier/ListFormsRequest.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Zapier;
|
||||
|
||||
use App\Models\Workspace;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class ListFormsRequest extends FormRequest
|
||||
{
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'workspace_id' => [
|
||||
'required',
|
||||
Rule::exists(Workspace::getModel()->getTable(), 'id'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function workspace(): Workspace
|
||||
{
|
||||
return Workspace::findOrFail($this->input('workspace_id'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user