Fixes #2551 - use UTF-8 safe slugging for MySQL columns

This commit is contained in:
snipe 2017-01-25 18:38:20 -08:00
parent de869c7ed0
commit dc47a0fad6
7 changed files with 151 additions and 30 deletions

View file

@ -203,7 +203,7 @@ class AssetsController extends Controller
$model = AssetModel::find($request->get('model_id'));
if ($model->fieldset) {
foreach ($model->fieldset->fields as $field) {
$asset->{CustomField::name_to_db_name($field->name)} = e($request->input(CustomField::name_to_db_name($field->name)));
$asset->{$field->convertUnicodeDbSlug()} = e($request->input($field->convertUnicodeDbSlug()));
}
}
@ -267,8 +267,8 @@ class AssetsController extends Controller
if ($request->has('model_id')) {
if (($model = AssetModel::find($request->get('model_id'))) && (isset($model->fieldset))) {
foreach ($model->fieldset->fields as $field) {
if ($request->has(CustomField::name_to_db_name($field->name))) {
$asset->{CustomField::name_to_db_name($field->name)} = e($request->input(CustomField::name_to_db_name($field->name)));
if ($request->has($field->convertUnicodeDbSlug())) {
$asset->{$field->convertUnicodeDbSlug()} = e($request->input($field->convertUnicodeDbSlug()));
}
}

View file

@ -198,14 +198,15 @@ class AssetsController extends Controller
}
// Update custom fields in the database.
// Validation for these fields is handlded through the AssetRequest form request
// Validation for these fields is handled through the AssetRequest form request
// FIXME: No idea why this is returning a Builder error on db_column_name.
// Need to investigate and fix. Using static method for now.
$model = AssetModel::find($request->get('model_id'));
if ($model->fieldset) {
foreach ($model->fieldset->fields as $field) {
$asset->{CustomField::name_to_db_name($field->name)} = e($request->input(CustomField::name_to_db_name($field->name)));
$asset->{$field->convertUnicodeDbSlug()} = e($request->input($field->convertUnicodeDbSlug()));
}
}
@ -348,11 +349,11 @@ class AssetsController extends Controller
foreach ($model->fieldset->fields as $field) {
if ($field->field_encrypted=='1') {
if (Gate::allows('admin')) {
$asset->{CustomField::name_to_db_name($field->name)} = \Crypt::encrypt(e($request->input(CustomField::name_to_db_name($field->name))));
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt(e($request->input($field->convertUnicodeDbSlug())));
}
} else {
$asset->{CustomField::name_to_db_name($field->name)} = e($request->input(CustomField::name_to_db_name($field->name)));
$asset->{$field->convertUnicodeDbSlug()} = e($request->input($field->convertUnicodeDbSlug()));
}
}
}

View file

@ -11,6 +11,7 @@ use App\Models\AssetModel;
use Lang;
use Auth;
use Illuminate\Http\Request;
use App\Helpers\Helper;
use Log;
/**
@ -184,8 +185,6 @@ class CustomFieldsController extends Controller
$validator = Validator::make(Input::all(), $field->rules);
$validator = Validator::make(Input::all(), $field->rules);
if ($field->save()) {
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.update.success'));
}

View file

@ -5,6 +5,9 @@ use Illuminate\Database\Eloquent\Model;
use Schema;
use Watson\Validating\ValidatingTrait;
use App\Http\Traits\UniqueUndeletedTrait;
use ForceUTF8\Encoding;
use EasySlugger\Utf8Slugger;
class CustomField extends Model
{
@ -34,35 +37,53 @@ class CustomField extends Model
public static function boot()
{
self::creating(function ($custom_field) {
self::creating(function ($custom_field)
{
if (Schema::hasColumn(CustomField::$table_name, $custom_field->db_column_name())) {
//field already exists when making a new custom field; fail.
\Log::debug("\n\nCreating Original Name: ".$custom_field->name);
\Log::debug('Creating Column Name: '.$custom_field->convertUnicodeDbSlug());
if (Schema::hasColumn(CustomField::$table_name, $custom_field->convertUnicodeDbSlug())) {
\Log::debug('Column exists. Nothing to do here.');
return false;
}
Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
$table->text($custom_field->db_column_name())->nullable();
$table->text($custom_field->convertUnicodeDbSlug())->nullable();
});
});
self::updating(function ($custom_field) {
self::updating(function ($custom_field)
{
\Log::debug('Updating column name');
\Log::debug('Updating Original Name: '.$custom_field->getOriginal("name"));
\Log::debug('Updating New Column Name: '.$custom_field->convertUnicodeDbSlug());
if ($custom_field->isDirty("name")) {
if (Schema::hasColumn(CustomField::$table_name, $custom_field->db_column_name())) {
//field already exists when renaming a custom field
return false;
if (Schema::hasColumn(CustomField::$table_name, $custom_field->convertUnicodeDbSlug()))
{
\Log::debug('Column already exists. Nothing to update.');
return true;
}
\Log::debug('Updating column name to.'.$custom_field->convertUnicodeDbSlug());
return Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
$table->renameColumn(self::name_to_db_name($custom_field->getOriginal("name")), $custom_field->db_column_name());
$table->renameColumn($custom_field->convertUnicodeDbSlug($custom_field->getOriginal("name")), $custom_field->convertUnicodeDbSlug());
});
}
return true;
});
self::deleting(function ($custom_field) {
self::deleting(function ($custom_field)
{
return Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
$table->dropColumn(self::name_to_db_name($custom_field->getOriginal("name")));
$table->dropColumn($custom_field->convertUnicodeDbSlug());
});
});
}
@ -77,12 +98,6 @@ class CustomField extends Model
return $this->belongsTo('\App\Models\User');
}
//public function
//need helper to go from regex->English
//need helper to go from English->regex
//need helper for save() stuff - basically to alter table for the fields in question
public function check_format($value)
{
@ -91,7 +106,7 @@ class CustomField extends Model
public function db_column_name()
{
return self::name_to_db_name($this->name);
return self::convertUnicodeDbSlug();
}
//mutators for 'format' attribute
@ -150,4 +165,18 @@ class CustomField extends Model
}
return false;
}
public function convertUnicodeDbSlug($original = null)
{
$name = $original ? $original : $this->name;
$slug = '_snipeit_'.Utf8Slugger::slugify($name,'_');
\Log::debug('The slugger slug is '.$slug);
return $slug;
}
}

View file

@ -24,7 +24,8 @@
"pragmarx/google2fa": "^1.0",
"neitanod/forceutf8": "^2.0",
"laravel/legacy-encrypter": "^1.0",
"laravel/passport": "^1.0"
"laravel/passport": "^1.0",
"javiereguiluz/easyslugger": "^1.0"
},
"require-dev": {

34
composer.lock generated
View file

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "09c9f9ab068ae672a965656f1591be6d",
"content-hash": "275081182145ff404e84b759d8f166b5",
"hash": "77a4cee6e9a94078b3073950a4b6f852",
"content-hash": "9f273d2aecd22cda1ce6b0cb105fdad2",
"packages": [
{
"name": "aws/aws-sdk-php",
@ -1258,6 +1258,36 @@
],
"time": "2015-04-20 18:58:01"
},
{
"name": "javiereguiluz/easyslugger",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/javiereguiluz/EasySlugger.git",
"reference": "11524a3fd70e3f0c98043755a0ffa228f2529211"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/javiereguiluz/EasySlugger/zipball/11524a3fd70e3f0c98043755a0ffa228f2529211",
"reference": "11524a3fd70e3f0c98043755a0ffa228f2529211",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"psr-4": {
"EasySlugger\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "A fast and easy to use slugger with full UTF-8 support.",
"time": "2015-04-12 19:57:10"
},
{
"name": "jeremeamia/SuperClosure",
"version": "2.3.0",

View file

@ -0,0 +1,61 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Migrations\Migration;
use App\Models\CustomField;
/**
* Fixes issue #2551 where columns got donked if the field name in non-ascii
* format.
*
* The only time this is ever called is in the
* 2017_01_25_063357_fix_utf8_custom_field_column_names.php migration
* as a one-time fix.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return Array
*/
function updateLegacyColumnName($customfield) {
$name_to_db_name = CustomField::name_to_db_name($customfield->name);
if (Schema::hasColumn(CustomField::$table_name, $name_to_db_name)) {
return Schema::table(CustomField::$table_name,
function ($table) use ($name_to_db_name, $customfield) {
$table->renameColumn($name_to_db_name, $customfield->convertUnicodeDbSlug());
}
);
}
}
class FixUtf8CustomFieldColumnNames extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
foreach(CustomField::all() as $field) {
updateLegacyColumnName($field);
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}