From d9262c055c2f52b2599648146a722c6999cab6e5 Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Thu, 8 Aug 2019 11:55:22 +0800 Subject: [PATCH] Convert SQL query of user model Automatically, for data integration. --- app/Models/User.php | 178 ++++++++++++++++++++++++++++- tests/Concerns/User.php | 22 ++++ tests/ModelsTest/UserTest.php | 209 ++++++++++++++++++++++++++++++++++ 3 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 tests/Concerns/User.php diff --git a/app/Models/User.php b/app/Models/User.php index 6dcc347a..6d40d550 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,10 +2,12 @@ namespace App\Models; +use Illuminate\Support\Arr; use Laravel\Passport\HasApiTokens; use App\Models\Concerns\HasPassword; use Tymon\JWTAuth\Contracts\JWTSubject; use Illuminate\Notifications\Notifiable; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable implements JWTSubject @@ -19,7 +21,7 @@ class User extends Authenticatable implements JWTSubject const ADMIN = 1; const SUPER_ADMIN = 2; - public $primaryKey = 'uid'; + protected $primaryKey = 'uid'; public $timestamps = false; protected $fillable = ['email', 'nickname', 'permission']; @@ -33,6 +35,65 @@ class User extends Authenticatable implements JWTSubject protected $hidden = ['password', 'remember_token']; + protected static $mappings = []; + + protected static function boot() + { + parent::boot(); + + $columns = [ + 'uid', + 'email', + 'nickname', + 'score', + 'avatar', + 'password', + 'ip', + 'permission', + 'last_sign_at', + 'register_at', + 'verified', + 'remember_token', + ]; + array_walk($columns, function ($column) { + static::$mappings[$column] = Arr::get(static::$mappings, $column, $column); + }); + + static::addGlobalScope(function (Builder $builder) { + $query = $builder->getQuery(); + + $mapItem = function ($item) { + if (Arr::has(static::$mappings, $item['column'])) { + $item['column'] = static::$mappings[$item['column']]; + } + return $item; + }; + $mapColumn = function ($column) { + if (Arr::has(static::$mappings, $column)) { + return static::$mappings[$column]; + } + return $column; + }; + + $query->wheres = array_map($mapItem, $query->wheres); + if ($query->columns) { + $query->columns = array_map($mapColumn, $query->columns); + } + if ($query->orders) { + $query->orders = array_map($mapItem, $query->orders); + } + if ($query->groups) { + $query->groups = array_map($mapColumn, $query->groups); + } + if ($query->havings) { + $query->havings = array_map($mapItem, $query->havings); + } + + $builder->setQuery($query); + return $builder; + }); + } + public function isAdmin() { return $this->permission >= static::ADMIN; @@ -43,6 +104,121 @@ class User extends Authenticatable implements JWTSubject return $this->belongsToMany(Texture::class, 'user_closet')->withPivot('item_name'); } + public function getUidAttribute() + { + return $this->attributes[$this->primaryKey]; + } + + public function getEmailAttribute() + { + return $this->attributes[static::$mappings['email']]; + } + + public function setEmailAttribute($value) + { + $this->attributes[static::$mappings['email']] = $value; + } + + public function getNicknameAttribute() + { + return $this->attributes[static::$mappings['nickname']]; + } + + public function setNicknameAttribute($value) + { + $this->attributes[static::$mappings['nickname']] = $value; + } + + public function getScoreAttribute() + { + return $this->attributes[static::$mappings['score']]; + } + + public function setScoreAttribute($value) + { + $this->attributes[static::$mappings['score']] = $value; + } + + public function getAvatarAttribute() + { + return $this->attributes[static::$mappings['avatar']]; + } + + public function setAvatarAttribute($value) + { + $this->attributes[static::$mappings['avatar']] = $value; + } + + public function getPasswordAttribute() + { + return $this->attributes[static::$mappings['password']]; + } + + public function setPasswordAttribute($value) + { + $this->attributes[static::$mappings['password']] = $value; + } + + public function getIpAttribute() + { + return $this->attributes[static::$mappings['ip']]; + } + + public function setIpAttribute($value) + { + $this->attributes[static::$mappings['ip']] = $value; + } + + public function getPermissionAttribute() + { + return $this->attributes[static::$mappings['permission']]; + } + + public function setPermissionAttribute($value) + { + $this->attributes[static::$mappings['permission']] = $value; + } + + public function getLastSignAtAttribute() + { + return $this->attributes[static::$mappings['last_sign_at']]; + } + + public function setLastSignAtAttribute($value) + { + $this->attributes[static::$mappings['last_sign_at']] = $value; + } + + public function getRegisterAtAttribute() + { + return $this->attributes[static::$mappings['register_at']]; + } + + public function setRegisterAtAttribute($value) + { + $this->attributes[static::$mappings['register_at']] = $value; + } + + public function getVerifiedAttribute() + { + return $this->attributes[static::$mappings['verified']]; + } + + public function setVerifiedAttribute($value) + { + $this->attributes[static::$mappings['verified']] = $value; + } + + public function getRememberTokenAttribute() + { + return $this->attributes[static::$mappings['remember_token']]; + } + + public function setRememberTokenAttribute($value) + { + $this->attributes[static::$mappings['remember_token']] = $value; + } + public function getPlayerNameAttribute() { $player = $this->players->first(); diff --git a/tests/Concerns/User.php b/tests/Concerns/User.php new file mode 100644 index 00000000..993b2dc9 --- /dev/null +++ b/tests/Concerns/User.php @@ -0,0 +1,22 @@ + 'bs_email', + 'nickname' => 'bs_nickname', + 'score' => 'bs_score', + 'avatar' => 'bs_avatar', + 'password' => 'bs_password', + 'ip' => 'bs_ip', + 'permission' => 'bs_permission', + 'last_sign_at' => 'bs_last_sign_at', + 'register_at' => 'bs_register_at', + 'verified' => 'bs_verified', + 'remember_token' => 'bs_remember_token', + ]; +} diff --git a/tests/ModelsTest/UserTest.php b/tests/ModelsTest/UserTest.php index 613f4499..5eb3706e 100644 --- a/tests/ModelsTest/UserTest.php +++ b/tests/ModelsTest/UserTest.php @@ -2,14 +2,223 @@ namespace Tests; +use Schema; +use Carbon\Carbon; use App\Models\User; use App\Models\Player; +use Tests\Concerns\User as ExtendedUser; +use Illuminate\Database\Schema\Blueprint; use Illuminate\Foundation\Testing\DatabaseTransactions; class UserTest extends TestCase { use DatabaseTransactions; + public function testConvertQuery() + { + $this->assertStringContainsString( + 'where `bs_email`', + ExtendedUser::where('email', '')->toSql() + ); + $this->assertStringContainsString( + 'select `bs_email` from', + ExtendedUser::select(['email'])->toSql() + ); + $this->assertStringContainsString( + 'order by `bs_score`', + ExtendedUser::orderBy('score')->toSql() + ); + $this->assertStringContainsString( + 'group by `bs_permission`', + ExtendedUser::groupBy('permission')->toSql() + ); + $this->assertStringContainsString( + 'having `bs_permission`', + ExtendedUser::having('permission')->toSql() + ); + } + + public function testGetUidAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('uid', 'bs_uid'); + }); + $users = get_class(new class extends User { + protected $primaryKey = 'bs_uid'; + + protected $table = 'users'; + + protected static $mappings = ['uid' => 'bs_uid']; + }); + $user = $users::first(); + $this->assertEquals($user->getAttribute('bs_uid'), $user->uid); + } + + public function testEmailAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('email', 'bs_email'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_email'), $user->email); + + $user->email = 'a@b.c'; + $user->save(); + $this->assertDatabaseHas('users', ['bs_email' => 'a@b.c']); + } + + public function testNicknameAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('nickname', 'bs_nickname'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_nickname'), $user->nickname); + + $user->nickname = 'name'; + $user->save(); + $this->assertDatabaseHas('users', ['bs_nickname' => 'name']); + } + + public function testScoreAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('score', 'bs_score'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_score'), $user->score); + + $user->score = 50; + $user->save(); + $this->assertDatabaseHas('users', ['bs_score' => 50]); + } + + public function testAvatarAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('avatar', 'bs_avatar'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_avatar'), $user->avatar); + + $user->avatar = 5; + $user->save(); + $this->assertDatabaseHas('users', ['bs_avatar' => 5]); + } + + public function testPasswordAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('password', 'bs_password'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_password'), $user->password); + + $user->password = '123'; + $user->save(); + $this->assertDatabaseHas('users', ['bs_password' => '123']); + } + + public function testIpAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('ip', 'bs_ip'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_ip'), $user->ip); + + $user->ip = '255.255.255.255'; + $user->save(); + $this->assertDatabaseHas('users', ['bs_ip' => '255.255.255.255']); + } + + public function testPermissionAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('permission', 'bs_permission'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_permission'), $user->permission); + + $user->permission = 1; + $user->save(); + $this->assertDatabaseHas('users', ['bs_permission' => 1]); + } + + public function testLastSignAtAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('last_sign_at', 'bs_last_sign_at'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_last_sign_at'), $user->last_sign_at); + + $time = Carbon::now()->toDateTimeString(); + $user->last_sign_at = $time; + $user->save(); + $this->assertDatabaseHas('users', ['bs_last_sign_at' => $time]); + } + + public function testRegisterAtAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('register_at', 'bs_register_at'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_register_at'), $user->register_at); + + $time = Carbon::now()->toDateTimeString(); + $user->register_at = $time; + $user->save(); + $this->assertDatabaseHas('users', ['bs_register_at' => $time]); + } + + public function testVerifiedAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('verified', 'bs_verified'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_verified'), $user->verified); + + $user->verified = 0; + $user->save(); + $this->assertDatabaseHas('users', ['bs_verified' => 0]); + + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('bs_verified', 'verified'); + }); + } + + public function testRememberTokenAttribute() + { + factory(User::class)->create(); + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('remember_token', 'bs_remember_token'); + }); + $user = ExtendedUser::first(); + $this->assertEquals($user->getAttribute('bs_remember_token'), $user->remember_token); + + $user->remember_token = 'abc'; + $user->save(); + $this->assertDatabaseHas('users', ['bs_remember_token' => 'abc']); + + Schema::table('users', function (Blueprint $table) { + $table->renameColumn('bs_remember_token', 'remember_token'); + }); + } + public function testGetPlayerNameAttribute() { $user = factory(User::class)->create();