diff --git a/app/Console/Commands/RegressLikesField.php b/app/Console/Commands/RegressLikesField.php new file mode 100644 index 00000000..d3a537a5 --- /dev/null +++ b/app/Console/Commands/RegressLikesField.php @@ -0,0 +1,45 @@ +info('We are going to update your `textures` table. Please wait...'); + $textures = Texture::all(); + $bar = $this->output->createProgressBar($textures->count()); + + $textures->each(function ($texture) use ($bar) { + $texture->likes = $texture->likers->count(); + $texture->save(); + $bar->advance(); + }); + + $bar->finish(); + $this->info("\nCongratulations! Table was updated successfully."); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 596f7bff..200fd3bc 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -18,6 +18,7 @@ class Kernel extends ConsoleKernel Commands\MigratePlayersTable::class, Commands\MigrateCloset::class, Commands\ExecuteInstallation::class, + Commands\RegressLikesField::class, ]; /** diff --git a/app/Http/Controllers/ClosetController.php b/app/Http/Controllers/ClosetController.php index de2c787d..d4b01fab 100644 --- a/app/Http/Controllers/ClosetController.php +++ b/app/Http/Controllers/ClosetController.php @@ -95,6 +95,9 @@ class ClosetController extends Controller $user->closet()->attach($tid, ['item_name' => $request->name]); $user->setScore(option('score_per_closet_item'), 'minus'); + $texture->likes++; + $texture->save(); + $uploader = User::find($texture->uploader); if ($uploader && $uploader->uid != $user->uid) { $uploader->score += option('score_award_per_like', 0); @@ -132,7 +135,11 @@ class ClosetController extends Controller $user->setScore(option('score_per_closet_item'), 'plus'); } - $uploader = User::find(Texture::find($tid)->uploader); + $texture = Texture::find($tid); + $texture->likes--; + $texture->save(); + + $uploader = User::find($texture->uploader); $uploader->score -= option('score_award_per_like', 0); $uploader->save(); diff --git a/app/Http/Controllers/SkinlibController.php b/app/Http/Controllers/SkinlibController.php index 3b617a6e..2c670452 100644 --- a/app/Http/Controllers/SkinlibController.php +++ b/app/Http/Controllers/SkinlibController.php @@ -97,8 +97,7 @@ class SkinlibController extends Controller $totalPages = ceil($query->count() / $itemsPerPage); $sort = $request->input('sort', 'time'); - $sortBy = $sort == 'time' ? 'upload_at' : ($sort == 'likes' ? 'likers_count' : $sort); - $query->withCount('likers'); + $sortBy = $sort == 'time' ? 'upload_at' : $sort; $query = $query->orderBy($sortBy, 'desc'); $textures = $query->skip(($currentPage - 1) * $itemsPerPage)->take($itemsPerPage)->get(); @@ -228,10 +227,10 @@ class SkinlibController extends Controller Storage::disk('textures')->put($t->hash, file_get_contents($request->file('file'))); } + $t->likes++; $t->save(); $user->setScore($cost, 'minus'); - $user->closet()->attach($t->tid, ['item_name' => $t->name]); return json(trans('skinlib.upload.success', ['name' => $request->input('name')]), 0, [ @@ -243,47 +242,47 @@ class SkinlibController extends Controller public function delete(Request $request) { - $result = Texture::find($request->tid); + $texture = Texture::find($request->tid); $user = Auth::user(); - if (! $result) { + if (! $texture) { return json(trans('skinlib.non-existent'), 1); } - if ($result->uploader != $user->uid && ! $user->isAdmin()) { + if ($texture->uploader != $user->uid && ! $user->isAdmin()) { return json(trans('skinlib.no-permission'), 1); } // check if file occupied - if (Texture::where('hash', $result->hash)->count() == 1) { - Storage::disk('textures')->delete($result->hash); + if (Texture::where('hash', $texture->hash)->count() == 1) { + Storage::disk('textures')->delete($texture->hash); } - $result->likers()->get()->each(function ($user) use ($result) { - $user->closet()->detach($result->tid); + $texture->likers()->get()->each(function ($user) use ($texture) { + $user->closet()->detach($texture->tid); if (option('return_score')) { $user->setScore(option('score_per_closet_item'), 'plus'); } }); - if ($u = User::find($result->uploader)) { + if ($u = User::find($texture->uploader)) { $ret = 0; if (option('return_score')) { - $ret += $result->size * ( - $result->public + $ret += $texture->size * ( + $texture->public ? option('score_per_storage') : option('private_score_per_storage') ); } - if ($result->public && option('take_back_scores_after_deletion', true)) { + if ($texture->public && option('take_back_scores_after_deletion', true)) { $ret -= option('score_award_per_texture', 0); } $u->setScore($ret, 'plus'); } - if ($result->delete()) { + if ($texture->delete()) { return json(trans('skinlib.delete.success'), 0); } } @@ -322,6 +321,7 @@ class SkinlibController extends Controller if (option('return_score')) { $user->setScore(option('score_per_closet_item'), 'plus'); } + $t->likes--; }); @$uploader->setScore($score_diff, 'plus'); diff --git a/app/Models/Texture.php b/app/Models/Texture.php index 5007a1b3..d4f2a629 100644 --- a/app/Models/Texture.php +++ b/app/Models/Texture.php @@ -15,17 +15,9 @@ class Texture extends Model 'size' => 'integer', 'uploader' => 'integer', 'public' => 'boolean', + 'likes' => 'integer', ]; - protected $appends = [ - 'likes', - ]; - - public function getLikesAttribute() - { - return $this->likers()->count(); - } - public function scopeLike($query, $field, $value) { return $query->where($field, 'LIKE', "%$value%"); diff --git a/database/factories/TextureModelFactory.php b/database/factories/TextureModelFactory.php index 8a0201f9..640aab74 100644 --- a/database/factories/TextureModelFactory.php +++ b/database/factories/TextureModelFactory.php @@ -8,6 +8,7 @@ $factory->define(Texture::class, function (Faker\Generator $faker) { 'type' => 'steve', 'hash' => $faker->sha256, 'size' => rand(1, 2048), + 'likes' => rand(1, 10), 'uploader' => factory(App\Models\User::class)->create()->uid, 'public' => true, 'upload_at' => $faker->dateTime, @@ -20,6 +21,7 @@ $factory->defineAs(Texture::class, 'alex', function (Faker\Generator $faker) { 'type' => 'alex', 'hash' => $faker->sha256, 'size' => rand(1, 2048), + 'likes' => rand(1, 10), 'uploader' => factory(App\Models\User::class)->create()->uid, 'public' => true, 'upload_at' => $faker->dateTime, diff --git a/database/migrations/2019_05_05_103143_add_likes_field.php b/database/migrations/2019_05_05_103143_add_likes_field.php new file mode 100644 index 00000000..92ea335a --- /dev/null +++ b/database/migrations/2019_05_05_103143_add_likes_field.php @@ -0,0 +1,26 @@ +integer('likes')->unsigned()->default(0); + }); + } + } + + public function down() + { + if (Schema::hasColumn('textures', 'likes')) { + Schema::table('textures', function (Blueprint $table) { + $table->dropColumn('likes'); + }); + } + } +} diff --git a/database/update_scripts/update-4.1.3-to-4.1.4.php b/database/update_scripts/update-4.1.3-to-4.1.4.php new file mode 100644 index 00000000..94679eee --- /dev/null +++ b/database/update_scripts/update-4.1.3-to-4.1.4.php @@ -0,0 +1,8 @@ +php artisan migrate --force', + 'php artisan bs:migrate-v4:likes', +]; diff --git a/tests/ClosetControllerTest.php b/tests/ClosetControllerTest.php index 9446606f..b094cca8 100644 --- a/tests/ClosetControllerTest.php +++ b/tests/ClosetControllerTest.php @@ -219,7 +219,7 @@ class ClosetControllerTest extends TestCase 'code' => 0, 'message' => trans('user.closet.remove.success'), ]); - $this->assertEquals($likes, Texture::find($texture->tid)->likes); + $this->assertEquals($likes - 1, Texture::find($texture->tid)->likes); $this->assertEquals($score + option('score_per_closet_item'), $this->user->score); $this->assertEquals(0, $this->user->closet()->count()); $uploader->refresh(); @@ -232,7 +232,7 @@ class ClosetControllerTest extends TestCase $this->user->closet()->attach($texture->tid, ['item_name' => 'name']); $score = $this->user->score; $this->postJson('/user/closet/remove/'.$texture->tid)->assertJson(['code' => 0]); - $this->assertEquals($likes, Texture::find($texture->tid)->likes); + $this->assertEquals($likes - 1, Texture::find($texture->tid)->likes); $this->assertEquals($score, $this->user->score); $this->assertEquals(0, $this->user->closet()->count()); } diff --git a/tests/SkinlibControllerTest.php b/tests/SkinlibControllerTest.php index a17ad635..6e910196 100644 --- a/tests/SkinlibControllerTest.php +++ b/tests/SkinlibControllerTest.php @@ -109,18 +109,6 @@ class SkinlibControllerTest extends TestCase }, $items); $this->assertArraySubset($ordered, $items); - // Sort by `likes` - $user = factory(User::class)->create(); - $user->closet()->attach($skins->random()->tid, ['item_name' => 'name']); - $items = $this->getJson('/skinlib/data?sort=likes') - ->assertJson(['data' => [ - 'current_uid' => 0, - 'total_pages' => 1, - ]]) - ->decodeResponseJson('data')['items']; - $this->assertEquals(1, $items[0]['likes']); - $this->assertEquals(0, $items[1]['likes']); - // Search $keyword = Str::limit($skins->random()->name, 1, ''); $keyworded = $skins