mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-25 21:54:14 -08:00
* More helpful text on how the custom validator works * Clarified language of custom format, fixed regex example * Fixed regex example in placeholder * Added comments to custom fields * Added regex validation string * Added valid_regex validator in format requirements * Removed useles comments * Fixes #4236 - validate the regex custom validation
This commit is contained in:
parent
f672b14468
commit
04ab522ee3
|
@ -71,9 +71,7 @@ class CategoriesController extends Controller
|
||||||
*/
|
*/
|
||||||
public function store(ImageUploadRequest $request)
|
public function store(ImageUploadRequest $request)
|
||||||
{
|
{
|
||||||
// create a new model instance
|
|
||||||
$category = new Category();
|
$category = new Category();
|
||||||
// Update the category data
|
|
||||||
$category->name = $request->input('name');
|
$category->name = $request->input('name');
|
||||||
$category->category_type = $request->input('category_type');
|
$category->category_type = $request->input('category_type');
|
||||||
$category->eula_text = $request->input('eula_text');
|
$category->eula_text = $request->input('eula_text');
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\CustomFieldRequest;
|
||||||
use View;
|
use View;
|
||||||
use App\Models\CustomFieldset;
|
use App\Models\CustomFieldset;
|
||||||
use App\Models\CustomField;
|
use App\Models\CustomField;
|
||||||
|
@ -69,7 +70,7 @@ class CustomFieldsController extends Controller
|
||||||
* @since [v1.8]
|
* @since [v1.8]
|
||||||
* @return Redirect
|
* @return Redirect
|
||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(CustomFieldRequest $request)
|
||||||
{
|
{
|
||||||
$field = new CustomField([
|
$field = new CustomField([
|
||||||
"name" => $request->get("name"),
|
"name" => $request->get("name"),
|
||||||
|
@ -81,27 +82,19 @@ class CustomFieldsController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!in_array(Input::get('format'), array_keys(CustomField::$PredefinedFormats))) {
|
if (!in_array(Input::get('format'), array_keys(CustomField::$PredefinedFormats))) {
|
||||||
$field->format = e($request->get("custom_format"));
|
$field->format = e($request->get("custom_format"));
|
||||||
} else {
|
} else {
|
||||||
$field->format = e($request->get("format"));
|
$field->format = e($request->get("format"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($field->save()) {
|
||||||
$validator = Validator::make(Input::all(), $field->rules);
|
|
||||||
|
|
||||||
if ($validator->passes()) {
|
|
||||||
$results = $field->save();
|
|
||||||
if ($results) {
|
|
||||||
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.create.success'));
|
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.create.success'));
|
||||||
} else {
|
} else {
|
||||||
dd($field);
|
// dd($field);
|
||||||
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.field.create.error'));
|
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.field.create.error'));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return redirect()->back()->withInput()->withErrors($validator);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -169,7 +162,7 @@ class CustomFieldsController extends Controller
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return Redirect
|
* @return Redirect
|
||||||
*/
|
*/
|
||||||
public function update(Request $request, $id)
|
public function update(CustomFieldRequest $request, $id)
|
||||||
{
|
{
|
||||||
$field = CustomField::find($id);
|
$field = CustomField::find($id);
|
||||||
|
|
||||||
|
@ -186,13 +179,12 @@ class CustomFieldsController extends Controller
|
||||||
$field->format = e($request->get("format"));
|
$field->format = e($request->get("format"));
|
||||||
}
|
}
|
||||||
|
|
||||||
$validator = Validator::make(Input::all(), $field->rules);
|
|
||||||
|
|
||||||
if ($field->save()) {
|
if ($field->save()) {
|
||||||
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.update.success'));
|
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.update.success'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back()->withInput()->withErrors($validator);
|
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.field.update.error'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
31
app/Http/Requests/CustomFieldRequest.php
Normal file
31
app/Http/Requests/CustomFieldRequest.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class CustomFieldRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
"name" => "required|unique:custom_fields",
|
||||||
|
"custom_format" => "valid_regex",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,9 @@ class CustomField extends Model
|
||||||
"name" => "required|unique:custom_fields"
|
"name" => "required|unique:custom_fields"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// This is confusing, since it's actually the custom fields table that
|
||||||
|
// we're usually modifying, but since we alter the assets table, we have to
|
||||||
|
// say that here
|
||||||
public static $table_name = "assets";
|
public static $table_name = "assets";
|
||||||
|
|
||||||
public static function name_to_db_name($name)
|
public static function name_to_db_name($name)
|
||||||
|
@ -39,7 +42,6 @@ class CustomField extends Model
|
||||||
{
|
{
|
||||||
self::created(function ($custom_field) {
|
self::created(function ($custom_field) {
|
||||||
|
|
||||||
|
|
||||||
// column exists - nothing to do here
|
// column exists - nothing to do here
|
||||||
if (Schema::hasColumn(CustomField::$table_name, $custom_field->convertUnicodeDbSlug())) {
|
if (Schema::hasColumn(CustomField::$table_name, $custom_field->convertUnicodeDbSlug())) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -62,14 +64,17 @@ class CustomField extends Model
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is just a dumb thing we have to include because Laraval/Doctrine doesn't
|
||||||
|
// play well with enums or a table that EVER had enums. :(
|
||||||
$platform = Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform();
|
$platform = Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform();
|
||||||
$platform->registerDoctrineTypeMapping('enum', 'string');
|
$platform->registerDoctrineTypeMapping('enum', 'string');
|
||||||
|
|
||||||
|
// Rename the field if the name has changed
|
||||||
Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
||||||
$table->renameColumn($custom_field->convertUnicodeDbSlug($custom_field->getOriginal("name")), $custom_field->convertUnicodeDbSlug());
|
$table->renameColumn($custom_field->convertUnicodeDbSlug($custom_field->getOriginal("name")), $custom_field->convertUnicodeDbSlug());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Save the updated column name to the custom fields table
|
||||||
$custom_field->db_column = $custom_field->convertUnicodeDbSlug();
|
$custom_field->db_column = $custom_field->convertUnicodeDbSlug();
|
||||||
$custom_field->save();
|
$custom_field->save();
|
||||||
|
|
||||||
|
@ -78,6 +83,8 @@ class CustomField extends Model
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Drop the assets column if we've deleted it from custom fields
|
||||||
self::deleting(function ($custom_field) {
|
self::deleting(function ($custom_field) {
|
||||||
return Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
return Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
||||||
$table->dropColumn($custom_field->convertUnicodeDbSlug());
|
$table->dropColumn($custom_field->convertUnicodeDbSlug());
|
||||||
|
|
|
@ -75,6 +75,41 @@ class AppServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Yo dawg. I heard you like validators.
|
||||||
|
// This validates the custom validator regex in custom fields.
|
||||||
|
// We're just checking that the regex won't throw an exception, not
|
||||||
|
// that it's actually correct for what the user intended.
|
||||||
|
|
||||||
|
Validator::extend('valid_regex', function ($attribute, $value, $parameters, $validator) {
|
||||||
|
|
||||||
|
// Make sure it's not just an ANY format
|
||||||
|
if ($value!='') {
|
||||||
|
|
||||||
|
// Check that the string starts with regex:
|
||||||
|
if (strpos($value, 'regex:') === FALSE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$test_string = 'My hovercraft is full of eels';
|
||||||
|
|
||||||
|
// We have to stip out the regex: part here to check with preg_match
|
||||||
|
$test_pattern = str_replace('regex:','', $value);
|
||||||
|
|
||||||
|
try {
|
||||||
|
preg_match($test_pattern, $test_string, $matches);
|
||||||
|
return true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Share common setting variables with all views.
|
// Share common setting variables with all views.
|
||||||
view()->composer('*', function ($view) {
|
view()->composer('*', function ($view) {
|
||||||
$view->with('snipeSettings', \App\Models\Setting::getSettings());
|
$view->with('snipeSettings', \App\Models\Setting::getSettings());
|
||||||
|
|
|
@ -5,7 +5,7 @@ return array(
|
||||||
'field' => 'Field',
|
'field' => 'Field',
|
||||||
'about_fieldsets_title' => 'About Fieldsets',
|
'about_fieldsets_title' => 'About Fieldsets',
|
||||||
'about_fieldsets_text' => 'Fieldsets allow you to create groups of custom fields that are frequently re-used used for specific asset model types.',
|
'about_fieldsets_text' => 'Fieldsets allow you to create groups of custom fields that are frequently re-used used for specific asset model types.',
|
||||||
'custom_format' => 'Custom format...',
|
'custom_format' => 'Custom regex format...',
|
||||||
'encrypt_field' => 'Encrypt the value of this field in the database',
|
'encrypt_field' => 'Encrypt the value of this field in the database',
|
||||||
'encrypt_field_help' => 'WARNING: Encrypting a field makes it unsearchable.',
|
'encrypt_field_help' => 'WARNING: Encrypting a field makes it unsearchable.',
|
||||||
'encrypted' => 'Encrypted',
|
'encrypted' => 'Encrypted',
|
||||||
|
@ -19,7 +19,8 @@ return array(
|
||||||
'field_element' => 'Form Element',
|
'field_element' => 'Form Element',
|
||||||
'field_element_short' => 'Element',
|
'field_element_short' => 'Element',
|
||||||
'field_format' => 'Format',
|
'field_format' => 'Format',
|
||||||
'field_custom_format' => 'Custom Format',
|
'field_custom_format' => 'Custom Regex Format',
|
||||||
|
'field_custom_format_help' => 'This field allows you to use a regex expression for validation. It should start with "regex:" - for example, to validate that a custom field value contains a valid IMEI (15 numeric digits), you would use <code>regex:/^[0-9]{15}$/</code>.',
|
||||||
'required' => 'Required',
|
'required' => 'Required',
|
||||||
'req' => 'Req.',
|
'req' => 'Req.',
|
||||||
'used_by_models' => 'Used By Models',
|
'used_by_models' => 'Used By Models',
|
||||||
|
|
|
@ -67,6 +67,7 @@ return array(
|
||||||
'not_in' => 'The selected :attribute is invalid.',
|
'not_in' => 'The selected :attribute is invalid.',
|
||||||
'numeric' => 'The :attribute must be a number.',
|
'numeric' => 'The :attribute must be a number.',
|
||||||
'present' => 'The :attribute field must be present.',
|
'present' => 'The :attribute field must be present.',
|
||||||
|
'valid_regex' => 'That is not a valid regex. ',
|
||||||
'regex' => 'The :attribute format is invalid.',
|
'regex' => 'The :attribute format is invalid.',
|
||||||
'required' => 'The :attribute field is required.',
|
'required' => 'The :attribute field is required.',
|
||||||
'required_if' => 'The :attribute field is required when :other is :value.',
|
'required_if' => 'The :attribute field is required when :other is :value.',
|
||||||
|
|
|
@ -82,7 +82,9 @@
|
||||||
{{ trans('admin/custom_fields/general.field_custom_format') }}
|
{{ trans('admin/custom_fields/general.field_custom_format') }}
|
||||||
</label>
|
</label>
|
||||||
<div class="col-md-6 required">
|
<div class="col-md-6 required">
|
||||||
{{ Form::text('custom_format', Input::old('custom_format', $field->custom_format), array('class' => 'form-control', 'id' => 'custom_format')) }}
|
{{ Form::text('custom_format', Input::old('custom_format', $field->format), array('class' => 'form-control', 'id' => 'custom_format', 'placeholder'=>'regex:/^[0-9]{15}$/')) }}
|
||||||
|
<p class="help-block">{!! trans('admin/custom_fields/general.field_custom_format_help') !!}</p>
|
||||||
|
|
||||||
{!! $errors->first('custom_format', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
|
{!! $errors->first('custom_format', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -102,7 +104,7 @@
|
||||||
|
|
||||||
@if (!$field->id)
|
@if (!$field->id)
|
||||||
<!-- Encrypted -->
|
<!-- Encrypted -->
|
||||||
<div class="form-group {{ $errors->has('custom_format') ? ' has-error' : '' }}">
|
<div class="form-group {{ $errors->has('encrypted') ? ' has-error' : '' }}">
|
||||||
<div class="col-md-8 col-md-offset-4">
|
<div class="col-md-8 col-md-offset-4">
|
||||||
<label for="field_encrypted">
|
<label for="field_encrypted">
|
||||||
<input type="checkbox" value="1" name="field_encrypted" id="field_encrypted" class="minimal"{{ (Input::old('field_encrypted') || $field->field_encrypted) ? ' checked="checked"' : '' }}>
|
<input type="checkbox" value="1" name="field_encrypted" id="field_encrypted" class="minimal"{{ (Input::old('field_encrypted') || $field->field_encrypted) ? ' checked="checked"' : '' }}>
|
||||||
|
@ -137,6 +139,14 @@
|
||||||
<script nonce="{{ csrf_token() }}">
|
<script nonce="{{ csrf_token() }}">
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
// Initialize selected index of the format dropdown
|
||||||
|
// If the custom_regex is ever NOT the last element in the format
|
||||||
|
// listbox, we will need to refactor this.
|
||||||
|
if ($('#custom_format').val()!='') {
|
||||||
|
$('.format').prop('selectedIndex', $('.format')[0].options.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Only display the custom format field if it's a custom format validation type
|
// Only display the custom format field if it's a custom format validation type
|
||||||
$(".format").change(function(){
|
$(".format").change(function(){
|
||||||
$(this).find("option:selected").each(function(){
|
$(this).find("option:selected").each(function(){
|
||||||
|
|
Loading…
Reference in a new issue