Enable pricing (#151)
* Enable Pro plan - WIP * no pricing page if have no paid plans * Set pricing ids in env * views & submissions FREE for all * extra param for env * form password FREE for all * Custom Code is PRO feature * Replace codeinput prism with codemirror * Better form Cleaning message * Added risky user email spam protection * fix form cleaning * Pricing page new UI * form cleaner * Polish changes * Fixed tests --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
@@ -34,13 +34,21 @@ class FormController extends Controller
|
||||
$this->authorize('viewAny', Form::class);
|
||||
|
||||
$workspaceIsPro = $workspace->is_pro;
|
||||
$forms = $workspace->forms()->with(['creator','views','submissions'])->paginate(10)->through(function (Form $form) use ($workspace, $workspaceIsPro){
|
||||
$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);
|
||||
@@ -91,8 +99,7 @@ class FormController extends Controller
|
||||
|
||||
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_cleaning' => $this->formCleaner->getPerformedCleanings(),
|
||||
'form' => new FormResource($form),
|
||||
'form' => (new FormResource($form))->setCleanings($this->formCleaner->getPerformedCleanings()),
|
||||
'users_first_form' => $request->user()->forms()->count() == 1
|
||||
]);
|
||||
}
|
||||
@@ -116,8 +123,7 @@ class FormController extends Controller
|
||||
|
||||
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_cleaning' => $this->formCleaner->getPerformedCleanings(),
|
||||
'form' => new FormResource($form)
|
||||
'form' => (new FormResource($form))->setCleanings($this->formCleaner->getPerformedCleanings()),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ namespace App\Http\Controllers\Forms;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Forms\Form;
|
||||
use Carbon\CarbonPeriod;
|
||||
use App\Models\Forms\FormStatistic;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FormStatsController extends Controller
|
||||
{
|
||||
@@ -15,9 +13,10 @@ class FormStatsController extends Controller
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
public function getFormStats(Request $request)
|
||||
public function getFormStats(string $formId)
|
||||
{
|
||||
$form = $request->form; // Added by ProForm middleware
|
||||
$form = Form::findOrFail($formId);
|
||||
|
||||
$this->authorize('view', $form);
|
||||
|
||||
$formStats = $form->statistics()->where('date','>',now()->subDays(29)->startOfDay())->get();
|
||||
|
||||
@@ -45,9 +45,8 @@ class PublicFormController extends Controller
|
||||
$form->views()->create();
|
||||
}
|
||||
|
||||
$formResource = new FormResource($form);
|
||||
$formResource->setCleanings($formCleaner->getPerformedCleanings());
|
||||
return $formResource;
|
||||
return (new FormResource($form))
|
||||
->setCleanings($formCleaner->getPerformedCleanings());
|
||||
}
|
||||
|
||||
public function listUsers(Request $request)
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Subscriptions\UpdateStripeDetailsRequest;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Laravel\Cashier\Subscription;
|
||||
|
||||
class SubscriptionController extends Controller
|
||||
{
|
||||
const SUBSCRIPTION_PLANS = ['monthly_2022', 'yearly_2022'];
|
||||
const SUBSCRIPTION_PLANS = ['monthly', 'yearly'];
|
||||
|
||||
const PRO_SUBSCRIPTION_NAME = 'default';
|
||||
const ENTERPRISE_SUBSCRIPTION_NAME = 'enterprise';
|
||||
@@ -41,7 +42,7 @@ class SubscriptionController extends Controller
|
||||
->allowPromotionCodes();
|
||||
|
||||
if ($trial != null) {
|
||||
$checkoutBuilder->trialDays(3);
|
||||
$checkoutBuilder->trialUntil(now()->addDays(3)->addHour());
|
||||
}
|
||||
|
||||
$checkout = $checkoutBuilder
|
||||
@@ -49,6 +50,11 @@ class SubscriptionController extends Controller
|
||||
->checkout([
|
||||
'success_url' => url('/subscriptions/success'),
|
||||
'cancel_url' => url('/subscriptions/error'),
|
||||
'billing_address_collection' => 'required',
|
||||
'customer_update' => [
|
||||
'address' => 'auto',
|
||||
'name' => 'never',
|
||||
]
|
||||
]);
|
||||
|
||||
return $this->success([
|
||||
@@ -56,6 +62,22 @@ class SubscriptionController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateStripeDetails(UpdateStripeDetailsRequest $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
if (!$user->hasStripeId()) {
|
||||
$user->createAsStripeCustomer();
|
||||
}
|
||||
$user->updateStripeCustomer([
|
||||
'email' => $request->email,
|
||||
'name' => $request->name,
|
||||
]);
|
||||
|
||||
return $this->success([
|
||||
'message' => 'Details saved.',
|
||||
]);
|
||||
}
|
||||
|
||||
public function billingPortal()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
@@ -69,7 +91,7 @@ class SubscriptionController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
private function getPricing($product = 'pro')
|
||||
private function getPricing($product = 'default')
|
||||
{
|
||||
return App::environment() == 'production' ? config('pricing.production.'.$product.'.pricing') : config('pricing.test.'.$product.'.pricing');
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ class PasswordProtectedForm
|
||||
'form' => $form,
|
||||
]);
|
||||
$userIsFormOwner = Auth::check() && Auth::user()->workspaces()->find($form->workspace_id) !== null;
|
||||
if (!$userIsFormOwner && $form->is_pro && $form->has_password) {
|
||||
if (!$userIsFormOwner && $form->has_password) {
|
||||
if($this->hasCorrectPassword($request, $form)){
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ use App\Rules\ValidHCaptcha;
|
||||
|
||||
class AnswerFormRequest extends FormRequest
|
||||
{
|
||||
const MAX_FILE_SIZE_PRO = 5000000;
|
||||
const MAX_FILE_SIZE_ENTERPRISE = 20000000;
|
||||
const MAX_FILE_SIZE_FREE = 5000000; // 5 MB
|
||||
const MAX_FILE_SIZE_PRO = 50000000; // 50 MB
|
||||
|
||||
public Form $form;
|
||||
|
||||
@@ -26,10 +26,10 @@ class AnswerFormRequest extends FormRequest
|
||||
{
|
||||
$this->form = $request->form;
|
||||
|
||||
$this->maxFileSize = self::MAX_FILE_SIZE_PRO;
|
||||
$this->maxFileSize = self::MAX_FILE_SIZE_FREE;
|
||||
$workspace = $this->form->workspace;
|
||||
if ($workspace && $workspace->is_enterprise) {
|
||||
$this->maxFileSize = self::MAX_FILE_SIZE_ENTERPRISE;
|
||||
if ($workspace && $workspace->is_pro) {
|
||||
$this->maxFileSize = self::MAX_FILE_SIZE_PRO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,9 +53,9 @@ class AnswerFormRequest extends FormRequest
|
||||
foreach ($this->form->properties as $property) {
|
||||
$rules = [];
|
||||
|
||||
if (!$this->form->is_pro) { // If not pro then not check logic
|
||||
/*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();
|
||||
@@ -96,12 +96,12 @@ class AnswerFormRequest extends FormRequest
|
||||
}
|
||||
|
||||
// Validate hCaptcha
|
||||
if ($this->form->is_pro && $this->form->use_captcha) {
|
||||
if ($this->form->use_captcha) {
|
||||
$this->requestRules['h-captcha-response'] = [new ValidHCaptcha()];
|
||||
}
|
||||
|
||||
// Validate submission_id for edit mode
|
||||
if ($this->form->editable_submissions) {
|
||||
if ($this->form->is_pro && $this->form->editable_submissions) {
|
||||
$this->requestRules['submission_id'] = 'string';
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ class AnswerFormRequest extends FormRequest
|
||||
return ['numeric'];
|
||||
case 'select':
|
||||
case 'multi_select':
|
||||
if ($this->form->is_pro && ($property['allow_creation'] ?? false)) {
|
||||
if (($property['allow_creation'] ?? false)) {
|
||||
return ['string'];
|
||||
}
|
||||
return [Rule::in($this->getSelectPropertyOptions($property))];
|
||||
@@ -174,7 +174,7 @@ class AnswerFormRequest extends FormRequest
|
||||
return ['url'];
|
||||
case 'files':
|
||||
$allowedFileTypes = [];
|
||||
if($this->form->is_pro && !empty($property['allowed_file_types'])){
|
||||
if(!empty($property['allowed_file_types'])){
|
||||
$allowedFileTypes = explode(",", $property['allowed_file_types']);
|
||||
}
|
||||
$this->requestRules[$property['id'].'.*'] = [new StorageFile($this->maxFileSize, $allowedFileTypes, $this->form)];
|
||||
|
||||
@@ -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',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -26,8 +26,8 @@ class FormResource extends JsonResource
|
||||
|
||||
$ownerData = $this->userIsFormOwner() ? [
|
||||
'creator' => new UserResource($this->creator),
|
||||
'views_count' => $this->when($this->workspaceIsPro(), $this->views_count),
|
||||
'submissions_count' => $this->when($this->workspaceIsPro(), $this->submissions_count),
|
||||
'views_count' => $this->views_count,
|
||||
'submissions_count' => $this->submissions_count,
|
||||
'notifies' => $this->notifies,
|
||||
'notifies_slack' => $this->notifies_slack,
|
||||
'notifies_discord' => $this->notifies_discord,
|
||||
@@ -35,7 +35,7 @@ class FormResource extends JsonResource
|
||||
'webhook_url' => $this->webhook_url,
|
||||
'redirect_url' => $this->redirect_url,
|
||||
'database_fields_update' => $this->database_fields_update,
|
||||
'cleanings' => $this->cleanings,
|
||||
'cleanings' => $this->getCleanigns(),
|
||||
'notification_sender' => $this->notification_sender,
|
||||
'notification_subject' => $this->notification_subject,
|
||||
'notification_body' => $this->notification_body,
|
||||
@@ -95,7 +95,7 @@ class FormResource extends JsonResource
|
||||
|
||||
private function doesMissPassword(Request $request)
|
||||
{
|
||||
if (!$this->workspaceIsPro() || !$this->has_password) return false;
|
||||
if (!$this->has_password) return false;
|
||||
|
||||
return !PasswordProtectedForm::hasCorrectPassword($request, $this->resource);
|
||||
}
|
||||
@@ -132,4 +132,9 @@ class FormResource extends JsonResource
|
||||
&& Auth::user()->workspaces()->find($this->workspace_id) !== null
|
||||
);
|
||||
}
|
||||
|
||||
private function getCleanigns()
|
||||
{
|
||||
return $this->extra?->cleanings ?? $this->cleanings;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ class SubmissionConfirmation implements ShouldQueue
|
||||
{
|
||||
use InteractsWithQueue;
|
||||
|
||||
const RISKY_USERS_LIMIT = 120;
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
@@ -26,7 +28,13 @@ class SubmissionConfirmation implements ShouldQueue
|
||||
*/
|
||||
public function handle(FormSubmitted $event)
|
||||
{
|
||||
if (!$event->form->send_submission_confirmation) return;
|
||||
if (
|
||||
!$event->form->is_pro ||
|
||||
!$event->form->send_submission_confirmation ||
|
||||
$this->riskLimitReached($event) // To avoid phishing abuse we limit this feature for risky users
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$email = $this->getRespondentEmail($event);
|
||||
if (!$email) return;
|
||||
@@ -56,6 +64,21 @@ class SubmissionConfirmation implements ShouldQueue
|
||||
return null;
|
||||
}
|
||||
|
||||
private function riskLimitReached(FormSubmitted $event): bool
|
||||
{
|
||||
// This is a per-workspace limit for risky workspaces
|
||||
if ($event->form->workspace->is_risky) {
|
||||
if ($event->form->workspace->submissions_count >= self::RISKY_USERS_LIMIT) {
|
||||
\Log::error('!!!DANGER!!! Dangerous user detected! Attempting many email sending.', [
|
||||
'form_id' => $event->form->id,
|
||||
'workspace_id' => $event->form->workspace->id,
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function validateEmail($email): bool {
|
||||
return (boolean) filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||
}
|
||||
|
||||
@@ -179,6 +179,15 @@ class User extends Authenticatable implements JWTSubject //, MustVerifyEmail
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getIsRiskyAttribute()
|
||||
{
|
||||
return $this->created_at->isAfter(now()->subDays(3)) || // created in last 3 days
|
||||
$this->subscriptions()->where(function ($q) {
|
||||
$q->where('stripe_status', 'trialing')
|
||||
->orWhere('stripe_status', 'active');
|
||||
})->first()?->onTrial();
|
||||
}
|
||||
|
||||
public static function boot ()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
@@ -24,7 +24,9 @@ class Workspace extends Model
|
||||
|
||||
public function getIsProAttribute()
|
||||
{
|
||||
return true; // Temporary true for ALL
|
||||
if(is_null(config('cashier.key'))){
|
||||
return true; // If no paid plan so TRUE for ALL
|
||||
}
|
||||
|
||||
// Make sure at least one owner is pro
|
||||
foreach ($this->owners as $owner) {
|
||||
@@ -37,7 +39,9 @@ class Workspace extends Model
|
||||
|
||||
public function getIsEnterpriseAttribute()
|
||||
{
|
||||
return true; // Temporary true for ALL
|
||||
if(is_null(config('cashier.key'))){
|
||||
return true; // If no paid plan so TRUE for ALL
|
||||
}
|
||||
|
||||
foreach ($this->owners as $owner) {
|
||||
if ($owner->has_enterprise_subscription) {
|
||||
@@ -47,6 +51,28 @@ class Workspace extends Model
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getIsRiskyAttribute()
|
||||
{
|
||||
// A workspace is risky if all of his users are risky
|
||||
foreach ($this->owners as $owner) {
|
||||
if (!$owner->is_risky) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSubmissionsCountAttribute()
|
||||
{
|
||||
$total = 0;
|
||||
foreach ($this->forms as $form) {
|
||||
$total += $form->submissions_count;
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
|
||||
@@ -11,7 +11,6 @@ use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Stevebauman\Purify\Facades\Purify;
|
||||
use function App\Service\str_starts_with;
|
||||
use function collect;
|
||||
|
||||
class FormCleaner
|
||||
@@ -26,76 +25,34 @@ class FormCleaner
|
||||
|
||||
private array $formDefaults = [
|
||||
'notifies' => false,
|
||||
'color' => '#3B82F6',
|
||||
'hide_title' => false,
|
||||
'no_branding' => false,
|
||||
'transparent_background' => false,
|
||||
'uppercase_labels' => true,
|
||||
'webhook_url' => null,
|
||||
'cover_picture' => null,
|
||||
'logo_picture' => null,
|
||||
'database_fields_update' => null,
|
||||
'theme' => 'default',
|
||||
'use_captcha' => false,
|
||||
'password' => null,
|
||||
'slack_webhook_url' => null,
|
||||
'discord_webhook_url' => null,
|
||||
'editable_submissions' => false,
|
||||
'custom_code' => null,
|
||||
];
|
||||
|
||||
private array $fieldDefaults = [
|
||||
// 'name' => '' TODO: prevent name changing, use alias for column and keep original name as it is
|
||||
'hide_field_name' => false,
|
||||
'prefill' => null,
|
||||
'placeholder' => null,
|
||||
'help' => null,
|
||||
'file_upload' => false,
|
||||
'with_time' => null,
|
||||
'width' => 'full',
|
||||
'generates_uuid' => false,
|
||||
'generates_auto_increment_id' => false,
|
||||
'logic' => null,
|
||||
'allow_creation' => false
|
||||
];
|
||||
|
||||
private array $cleaningMessages = [
|
||||
// For form
|
||||
'notifies' => "Email notification were disabled.",
|
||||
'color' => "Form color set to default blue.",
|
||||
'hide_title' => "Title is not hidden.",
|
||||
'no_branding' => "OpenForm branding is not hidden.",
|
||||
'transparent_background' => "Transparent background was disabled.",
|
||||
'uppercase_labels' => "Labels use uppercase letters",
|
||||
'webhook_url' => "Webhook disabled.",
|
||||
'cover_picture' => 'The cover picture was removed.',
|
||||
'logo_picture' => 'The logo was removed.',
|
||||
'database_fields_update' => 'Form submission will only create new records (no updates).',
|
||||
'theme' => 'Default theme was applied.',
|
||||
'slack_webhook_url' => "Slack webhook disabled.",
|
||||
'discord_webhook_url' => "Discord webhook disabled.",
|
||||
'editable_submissions' => 'Users will not be able to edit their submissions.',
|
||||
'custom_code' => 'Custom code was disabled',
|
||||
|
||||
// For fields
|
||||
'hide_field_name' => 'Hide field name removed.',
|
||||
'prefill' => "Field prefill removed.",
|
||||
'placeholder' => "Empty text (placeholder) removed",
|
||||
'help' => "Help text removed.",
|
||||
'file_upload' => "Link field is not a file upload.",
|
||||
'with_time' => "Time was removed from date input.",
|
||||
'custom_block' => 'The custom block was removed.',
|
||||
'files' => 'The file upload file was hidden.',
|
||||
'relation' => 'The relation file was hidden.',
|
||||
'width' => 'The field width was set to full width',
|
||||
'allow_creation' => 'Select option creation was disabled.',
|
||||
|
||||
// Advanced fields
|
||||
'generates_uuid' => 'ID generation disabled.',
|
||||
'generates_auto_increment_id' => 'ID generation disabled.',
|
||||
|
||||
'use_captcha' => 'Captcha form protection was disabled.',
|
||||
|
||||
// Security & Privacy
|
||||
'password' => 'Password protection was disabled',
|
||||
|
||||
'logic' => 'Logic disabled for this property'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -144,7 +101,8 @@ class FormCleaner
|
||||
/**
|
||||
* Create form cleaner instance from existing form
|
||||
*/
|
||||
public function processForm(Request $request, Form $form) : FormCleaner {
|
||||
public function processForm(Request $request, Form $form) : FormCleaner
|
||||
{
|
||||
$data = (new FormResource($form))->toArray($request);
|
||||
$this->data = $this->commonCleaning($data);
|
||||
|
||||
@@ -159,10 +117,11 @@ class FormCleaner
|
||||
* Dry run celanings
|
||||
* @param User|null $user
|
||||
*/
|
||||
public function simulateCleaning(Workspace $workspace): FormCleaner {
|
||||
if($this->isPro($workspace)) return $this;
|
||||
|
||||
$this->data = $this->removeProFeatures($this->data, true);
|
||||
public function simulateCleaning(Workspace $workspace): FormCleaner
|
||||
{
|
||||
if (!$this->isPro($workspace)) {
|
||||
$this->data = $this->removeProFeatures($this->data, true);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -174,9 +133,9 @@ class FormCleaner
|
||||
*/
|
||||
public function performCleaning(Workspace $workspace): FormCleaner
|
||||
{
|
||||
if($this->isPro($workspace)) return $this;
|
||||
|
||||
$this->data = $this->removeProFeatures($this->data);
|
||||
if (!$this->isPro($workspace)) {
|
||||
$this->data = $this->removeProFeatures($this->data);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -212,6 +171,7 @@ class FormCleaner
|
||||
private function cleanProperties(array &$data, $simulation = false): void
|
||||
{
|
||||
foreach ($data['properties'] as $key => &$property) {
|
||||
/*
|
||||
// Remove pro custom blocks
|
||||
if (\Str::of($property['type'])->startsWith('nf-')) {
|
||||
$this->cleanings[$property['name']][] = 'custom_block';
|
||||
@@ -221,6 +181,15 @@ class FormCleaner
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove logic
|
||||
if (($property['logic']['conditions'] ?? null) != null || ($property['logic']['actions'] ?? []) != []) {
|
||||
$this->cleanings[$property['name']][] = 'logic';
|
||||
if (!$simulation) {
|
||||
unset($data['properties'][$key]['logic']);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Clean pro field options
|
||||
$this->cleanField($property, $this->fieldDefaults, $simulation);
|
||||
}
|
||||
@@ -229,8 +198,18 @@ class FormCleaner
|
||||
private function clean(array &$data, array $defaults, $simulation = false): void
|
||||
{
|
||||
foreach ($defaults as $key => $value) {
|
||||
if (Arr::get($data, $key) !== $value) {
|
||||
if (!isset($this->cleanings['form'])) $this->cleanings['form'] = [];
|
||||
|
||||
// Get value from form
|
||||
$formVal = Arr::get($data, $key);
|
||||
|
||||
// Transform boolean values
|
||||
$formVal = (($formVal === 0 || $formVal === "0") ? false : $formVal);
|
||||
$formVal = (($formVal === 1 || $formVal === "1") ? true : $formVal);
|
||||
|
||||
if (!is_null($formVal) && $formVal !== $value) {
|
||||
if (!isset($this->cleanings['form'])) {
|
||||
$this->cleanings['form'] = [];
|
||||
}
|
||||
$this->cleanings['form'][] = $key;
|
||||
|
||||
// If not a simulation, do the cleaning
|
||||
@@ -253,14 +232,14 @@ class FormCleaner
|
||||
}
|
||||
|
||||
// Remove pro types columns
|
||||
foreach (['files'] as $proType) {
|
||||
/*foreach (['files'] as $proType) {
|
||||
if ($data['type'] == $proType && (!isset($data['hidden']) || !$data['hidden'])) {
|
||||
$this->cleanings[$data['name']][] = $proType;
|
||||
if (!$simulation) {
|
||||
$data['hidden'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user