diff --git a/app/Http/Controllers/GameController.php b/app/Http/Controllers/GameController.php index de9c84c..92003a1 100644 --- a/app/Http/Controllers/GameController.php +++ b/app/Http/Controllers/GameController.php @@ -20,7 +20,14 @@ class GameController extends Controller */ public function index(Request $request) { - return Game::latest()->get(['id', 'slug']); + return Game::latest()->get(['id', 'slug', 'title_fa', 'title_en', 'games'])->transform(function ($game) { + return [ + 'id' => $game->id, + 'slug' => $game->slug, + 'title_fa' => $game->title_fa ?? $game->games[0]['title_fa'][0] ?? '', + 'title_en' => $game->title_en ?? $game->games[0]['title_en'][0] ?? '', + ]; + }); } /** @@ -28,24 +35,25 @@ public function index(Request $request) */ public function store(Request $request) { - $input = $request->except(['producers', 'publishers', 'contributes', 'photos']); + return DB::transaction(function () use ($request) { + $input = $request->except(['producers', 'publishers', 'contributes', 'photos']); - $game = Game::create($input); - $game->producers()->attach($request->producers, ['relation' => 'producer']); - $game->publishers()->attach($request->publishers, ['relation' => 'publisher']); + $game = Game::create($input); + $game->producers()->attach($request->producers, ['relation' => 'producer']); + $game->publishers()->attach($request->publishers, ['relation' => 'publisher']); + $game->contributes()->createMany($request->contributes); - $game->contributes()->createMany($request->contributes); - - foreach ($request->photos as $photo) { - if (isset($photo["dataURL"])) - $game->addMediaFromBase64($photo["dataURL"]) - ->usingFileName(str_replace('/tmp/', '', tempnam(sys_get_temp_dir(), 'media-library')) . '.jpg') - ->toMediaCollection(); - } + foreach ($request->photos as $photo) { + if (isset($photo["dataURL"])) + $game->addMediaFromBase64($photo["dataURL"]) + ->usingFileName(str_replace('/tmp/', '', tempnam(sys_get_temp_dir(), 'media-library')) . '.jpg') + ->toMediaCollection(); + } - return $game; + return $game; + }); } /** @@ -55,18 +63,16 @@ public function show($id) { $game = Game::with(['producers:id', 'publishers:id', 'contributes'])->findOrFail($id); - $game->producers = $game->producers->map->id->values(); - $game->unsetRelation('producers'); - $game->publishers = $game->publishers->map->id->values(); - $game->unsetRelation('publishers'); - - $photos = $game->getMedia() - ->map(function ($photo) { - return ["id" => $photo->id, "url" => $photo->getUrl()]; - }); - - return [...$game->toArray(), 'photos' => $photos]; + return [ + ...$game->toArray(), + 'producers' => $game->producers->pluck('id'), + 'publishers' => $game->publishers->pluck('id'), + 'photos' => $game->getMedia() + ->map(function ($photo) { + return ["id" => $photo->id, "url" => $photo->getUrl()]; + }), + ]; } /** @@ -74,51 +80,32 @@ public function show($id) */ public function update(Request $request, Game $game) { + return DB::transaction(function () use ($game, $request) { + if ($request->filled('photos')) { + $photos = collect($request->photos); - $input = $request->except(['producers', 'publishers', 'contributes', 'photos']); - - if ($request->filled('photos')) { - // Photos to keep in media library - $toKeep = collect(array_filter($request->photos, function ($photo) { - return !isset($photo["dataURL"]); - })); - $toKeepIds = array_column($toKeep->toArray(), 'id'); + // Photos to keep in the media library + $toKeepIds = $photos->whereNotNull('id')->pluck('id'); - // Remove other items from media library - foreach ($game->getMedia() as $media) { - if (!in_array($media->id, $toKeepIds)) - $media->delete(); - } + // Remove other items from the media library + foreach ($game->getMedia() as $media) { + if ($toKeepIds->doesntContain($media->id)) + $media->delete(); + } - // Upload photos - foreach ($request->photos as $photo) { - if (isset($photo["dataURL"])) + // Upload photos + $photos->whereNotNull('dataURL')->each(function ($photo) use ($game) { $game->addMediaFromBase64($photo["dataURL"])->usingFileName(str_replace('/tmp/', '', tempnam(sys_get_temp_dir(), 'media-library')) . '.jpg')->toMediaCollection(); + }); } - } - - $game->update($input); - $game->producers()->syncWithPivotValues($request->producers, ['relation' => 'producer']); - $game->publishers()->syncWithPivotValues($request->publishers, ['relation' => 'publisher']); - - $currentContributes = $game->contributes->toArray(); - $newContributes = $request->contributes; - - $contributesToAdd = array_values(array_filter($newContributes, function ($value) { - return $value["new"] ?? false; - })); - $contributesToEdit = array_values(array_filter($newContributes, function ($value) { - return !($value["new"] ?? false); - })); - $contributesToDelete = array_values(array_diff(array_column($currentContributes, 'id'), array_column($contributesToEdit, 'id'))); - - foreach ($contributesToEdit as $value) { - $game->contributes->firstWhere('id', $value['id'])->update($value); - } - $game->contributes()->whereIn('id', $contributesToDelete)->delete(); + $game->update($request->except(['producers', 'publishers', 'contributes', 'photos'])); + $game->producers()->syncWithPivotValues($request->producers, ['relation' => 'producer']); + $game->publishers()->syncWithPivotValues($request->publishers, ['relation' => 'publisher']); - $game->contributes()->createMany($contributesToAdd); + $game->contributes()->delete(); + $game->contributes()->createMany($request->contributes); + }); } /** diff --git a/app/Models/Game.php b/app/Models/Game.php index f0765ba..c707ad2 100644 --- a/app/Models/Game.php +++ b/app/Models/Game.php @@ -6,6 +6,8 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\MorphMany; +use Spatie\Activitylog\LogOptions; +use Spatie\Activitylog\Traits\LogsActivity; use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\InteractsWithMedia; @@ -13,6 +15,7 @@ class Game extends Model implements HasMedia { use HasFactory; use InteractsWithMedia; + use LogsActivity; protected $guarded = [ 'id', 'created_at', 'updated_at' @@ -20,6 +23,11 @@ class Game extends Model implements HasMedia protected $appends = ['featured_image']; protected $hidden = ['media']; + public function getActivitylogOptions(): LogOptions + { + return LogOptions::defaults(); + } + protected function casts(): array { return [ diff --git a/composer.json b/composer.json index b0fd25d..02e4f1f 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,7 @@ "laravel/sanctum": "^4.0", "laravel/tinker": "^2.9", "nutgram/laravel": "^1.4", + "spatie/laravel-activitylog": "^4.8", "spatie/laravel-medialibrary": "^11.4" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 0bcbb07..4e73204 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2b69b2743bebb1db6da3cb12f4b0754a", + "content-hash": "8e65babb2ecefb9eb5973e8c95eae830", "packages": [ { "name": "brick/math", @@ -3674,6 +3674,97 @@ }, "time": "2023-11-03T10:08:02+00:00" }, + { + "name": "spatie/laravel-activitylog", + "version": "4.8.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-activitylog.git", + "reference": "eb6f37dd40af950ce10cf5280f0acfa3e08c3bff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/eb6f37dd40af950ce10cf5280f0acfa3e08c3bff", + "reference": "eb6f37dd40af950ce10cf5280f0acfa3e08c3bff", + "shasum": "" + }, + "require": { + "illuminate/config": "^8.0 || ^9.0 || ^10.0 || ^11.0", + "illuminate/database": "^8.69 || ^9.27 || ^10.0 || ^11.0", + "illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.6.3" + }, + "require-dev": { + "ext-json": "*", + "orchestra/testbench": "^6.23 || ^7.0 || ^8.0 || ^9.0", + "pestphp/pest": "^1.20 || ^2.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Activitylog\\ActivitylogServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Activitylog\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Tom Witkowski", + "email": "dev.gummibeer@gmail.com", + "homepage": "https://gummibeer.de", + "role": "Developer" + } + ], + "description": "A very simple activity logger to monitor the users of your website or application", + "homepage": "https://github.com/spatie/activitylog", + "keywords": [ + "activity", + "laravel", + "log", + "spatie", + "user" + ], + "support": { + "issues": "https://github.com/spatie/laravel-activitylog/issues", + "source": "https://github.com/spatie/laravel-activitylog/tree/4.8.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-03-08T22:28:17+00:00" + }, { "name": "spatie/laravel-medialibrary", "version": "11.4.6", diff --git a/database/migrations/2024_06_10_032526_create_activity_log_table.php b/database/migrations/2024_06_10_032526_create_activity_log_table.php new file mode 100644 index 0000000..7c05bc8 --- /dev/null +++ b/database/migrations/2024_06_10_032526_create_activity_log_table.php @@ -0,0 +1,27 @@ +create(config('activitylog.table_name'), function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('log_name')->nullable(); + $table->text('description'); + $table->nullableMorphs('subject', 'subject'); + $table->nullableMorphs('causer', 'causer'); + $table->json('properties')->nullable(); + $table->timestamps(); + $table->index('log_name'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->dropIfExists(config('activitylog.table_name')); + } +} diff --git a/database/migrations/2024_06_10_032527_add_event_column_to_activity_log_table.php b/database/migrations/2024_06_10_032527_add_event_column_to_activity_log_table.php new file mode 100644 index 0000000..7b797fd --- /dev/null +++ b/database/migrations/2024_06_10_032527_add_event_column_to_activity_log_table.php @@ -0,0 +1,22 @@ +table(config('activitylog.table_name'), function (Blueprint $table) { + $table->string('event')->nullable()->after('subject_type'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) { + $table->dropColumn('event'); + }); + } +} diff --git a/database/migrations/2024_06_10_032528_add_batch_uuid_column_to_activity_log_table.php b/database/migrations/2024_06_10_032528_add_batch_uuid_column_to_activity_log_table.php new file mode 100644 index 0000000..8f7db66 --- /dev/null +++ b/database/migrations/2024_06_10_032528_add_batch_uuid_column_to_activity_log_table.php @@ -0,0 +1,22 @@ +table(config('activitylog.table_name'), function (Blueprint $table) { + $table->uuid('batch_uuid')->nullable()->after('properties'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) { + $table->dropColumn('batch_uuid'); + }); + } +}