diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index c672781e6f..dd375d0823 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -591,6 +591,11 @@ class AssetsController extends Controller } } } + if ($field->element == 'checkbox') { + if(is_array($field_val)) { + $field_val = implode(',', $field_val); + } + } $asset->{$field->db_column} = $field_val; @@ -659,13 +664,22 @@ class AssetsController extends Controller // Update custom fields if (($model) && (isset($model->fieldset))) { foreach ($model->fieldset->fields as $field) { + $field_val = $request->input($field->db_column, null); + if ($request->has($field->db_column)) { if ($field->field_encrypted == '1') { if (Gate::allows('admin')) { - $asset->{$field->db_column} = \Crypt::encrypt($request->input($field->db_column)); + $asset->{$field->db_column} = Crypt::encrypt($field_val); } - } else { - $asset->{$field->db_column} = $request->input($field->db_column); + } + if ($field->element == 'checkbox') { + if(is_array($field_val)) { + $field_val = implode(',', $field_val); + $asset->{$field->db_column} = $field_val; + } + } + else { + $asset->{$field->db_column} = $field_val; } } } diff --git a/app/Http/Controllers/AssetModelsController.php b/app/Http/Controllers/AssetModelsController.php index 484a2e2f85..8d387f968f 100755 --- a/app/Http/Controllers/AssetModelsController.php +++ b/app/Http/Controllers/AssetModelsController.php @@ -7,6 +7,7 @@ use App\Http\Requests\ImageUploadRequest; use App\Models\Actionlog; use App\Models\Asset; use App\Models\AssetModel; +use App\Models\CustomField; use App\Models\User; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; @@ -486,11 +487,11 @@ class AssetModelsController extends Controller * @param array $defaultValues * @return void */ - private function assignCustomFieldsDefaultValues(AssetModel $model, array $defaultValues) + private function assignCustomFieldsDefaultValues(AssetModel $model, array $defaultValues): bool { $data = array(); foreach ($defaultValues as $customFieldId => $defaultValue) { - $customField = \App\Models\CustomField::find($customFieldId); + $customField = CustomField::find($customFieldId); $data[$customField->db_column] = $defaultValue; } diff --git a/app/Models/CustomFieldset.php b/app/Models/CustomFieldset.php index a62f96d631..71be28e8a3 100644 --- a/app/Models/CustomFieldset.php +++ b/app/Models/CustomFieldset.php @@ -5,6 +5,8 @@ namespace App\Models; use Gate; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Log; +use Illuminate\Validation\Rule; use Watson\Validating\ValidatingTrait; class CustomFieldset extends Model @@ -92,8 +94,19 @@ class CustomFieldset extends Model array_push($rule, $field->attributes['format']); $rules[$field->db_column_name()] = $rule; - //add not_array to rules for all fields - $rules[$field->db_column_name()][] = 'not_array'; + + // add not_array to rules for all fields but checkboxes + if ($field->element != 'checkbox') { + $rules[$field->db_column_name()][] = 'not_array'; + } + + if ($field->element == 'checkbox') { + $rules[$field->db_column_name()][] = 'checkboxes'; + } + + if ($field->element == 'radio') { + $rules[$field->db_column_name()][] = 'radio_buttons'; + } } return $rules; diff --git a/app/Providers/ValidationServiceProvider.php b/app/Providers/ValidationServiceProvider.php index 50468c8d72..803d540865 100644 --- a/app/Providers/ValidationServiceProvider.php +++ b/app/Providers/ValidationServiceProvider.php @@ -2,9 +2,12 @@ namespace App\Providers; +use App\Models\CustomField; use App\Models\Department; use App\Models\Setting; use DB; +use Illuminate\Support\Facades\Crypt; +use Illuminate\Support\Facades\Log; use Illuminate\Support\ServiceProvider; use Illuminate\Validation\Rule; use Validator; @@ -294,6 +297,39 @@ class ValidationServiceProvider extends ServiceProvider Validator::extend('not_array', function ($attribute, $value, $parameters, $validator) { return !is_array($value); }); + + // This is only used in Models/CustomFieldset.php - it does automatic validation for checkboxes by making sure + // that the submitted values actually exist in the options. + Validator::extend('checkboxes', function ($attribute, $value, $parameters, $validator){ + $field = CustomField::where('db_column', $attribute)->first(); + $options = $field->formatFieldValuesAsArray(); + + if(is_array($value)) { + $invalid = array_diff($value, $options); + if(count($invalid) > 0) { + return false; + } + } + + // for legacy, allows users to submit a comma separated string of options + elseif(!is_array($value)) { + $exploded = array_map('trim', explode(',', $value)); + $invalid = array_diff($exploded, $options); + if(count($invalid) > 0) { + return false; + } + } + + return true; + }); + + // Validates that a radio button option exists + Validator::extend('radio_buttons', function ($attribute, $value) { + $field = CustomField::where('db_column', $attribute)->first(); + $options = $field->formatFieldValuesAsArray(); + + return in_array($value, $options); + }); } /** diff --git a/resources/lang/en-US/validation.php b/resources/lang/en-US/validation.php index 1c6ad8a148..d027a93f86 100644 --- a/resources/lang/en-US/validation.php +++ b/resources/lang/en-US/validation.php @@ -105,6 +105,8 @@ return [ 'gte' => [ 'numeric' => 'Value cannot be negative' ], + 'checkboxes' => ':attribute contains invalid options.', + 'radio_buttons' => ':attribute is invalid.', /* diff --git a/resources/views/custom_fields/fields/edit.blade.php b/resources/views/custom_fields/fields/edit.blade.php index 504b556faa..e21e9fba48 100644 --- a/resources/views/custom_fields/fields/edit.blade.php +++ b/resources/views/custom_fields/fields/edit.blade.php @@ -135,7 +135,7 @@ @if (!$field->id) -
+
- @endif @@ -298,11 +297,16 @@ }).change(); // Only display the field element if the type is not text + // and don't display encryption option for checkbox or radio $(".field_element").change(function(){ $(this).find("option:selected").each(function(){ if (($(this).attr("value")!="text") && ($(this).attr("value")!="textarea")){ $("#field_values_text").show(); + if ($(this).attr("value") == "checkbox" || $(this).attr("value") == "radio") { + $("#encryption_section").hide(); + } } else{ + $("#encryption_section").show(); $("#field_values_text").hide(); } });