diff --git a/app/Console/Commands/ImportBookmarks.php b/app/Console/Commands/ImportBookmarks.php index 53b7f3d..165a843 100644 --- a/app/Console/Commands/ImportBookmarks.php +++ b/app/Console/Commands/ImportBookmarks.php @@ -3,6 +3,7 @@ namespace App\Console\Commands; use App\Jobs\ImportBookmark; +use App\Models\User; use Illuminate\Console\Command; use RuntimeException; @@ -15,7 +16,7 @@ class ImportBookmarks extends Command * * @var string */ - protected $signature = 'app:import-bookmarks {json_file}'; + protected $signature = 'app:import-bookmarks {user} {json_file}'; /** * The console command description. @@ -29,6 +30,8 @@ class ImportBookmarks extends Command */ public function handle() { + $user = User::find($this->argument('user')); + $json_file_path = $this->argument('json_file'); if (!file_exists($json_file_path)) { throw new RuntimeException('Unable to find JSON file'); @@ -38,7 +41,7 @@ class ImportBookmarks extends Command $bookmarks = json_decode($json, true); foreach (array_chunk($bookmarks, self::$perBatch) as $bookmarks_json) { - ImportBookmark::dispatch(...$bookmarks_json); + ImportBookmark::dispatch($user, ...$bookmarks_json); } } } diff --git a/app/Http/Controllers/BookmarkController.php b/app/Http/Controllers/BookmarkController.php index 9a0d666..b6779dd 100644 --- a/app/Http/Controllers/BookmarkController.php +++ b/app/Http/Controllers/BookmarkController.php @@ -3,19 +3,26 @@ namespace App\Http\Controllers; use App\Models\Bookmark; -use App\Models\Tag; use Illuminate\Http\Request; +use Illuminate\Routing\Controllers\HasMiddleware; -class BookmarkController extends Controller +class BookmarkController extends Controller implements HasMiddleware { + public static function middleware() + { + return [ + 'auth', + ]; + } + /** * Display a listing of the resource. */ - public function index() + public function index(Request $request) { return view( 'bookmarks.index', [ - 'bookmarks' => Bookmark::orderByDesc('created_at')->paginate(20), + 'bookmarks' => $request->user()->bookmarks()->orderByDesc('created_at')->paginate(20), ] ); } @@ -34,6 +41,7 @@ class BookmarkController extends Controller public function store(Request $request) { $bookmark = new Bookmark; + $bookmark->user()->associate($request->user()); $bookmark->title = $request->post('title'); $bookmark->description = $request->post('description', ''); $bookmark->href = $request->post('href'); @@ -51,8 +59,10 @@ class BookmarkController extends Controller /** * Display the specified resource. */ - public function show(Bookmark $bookmark) + public function show(Request $request, Bookmark $bookmark) { + abort_unless($bookmark->user()->is($request->user()), 404); + return view( 'bookmarks.show', [ 'bookmark' => $bookmark, @@ -63,8 +73,10 @@ class BookmarkController extends Controller /** * Show the form for editing the specified resource. */ - public function edit(Bookmark $bookmark) + public function edit(Request $request, Bookmark $bookmark) { + abort_unless($bookmark->user()->is($request->user()), 404); + return view( 'bookmarks.edit', [ 'bookmark' => $bookmark, @@ -77,6 +89,8 @@ class BookmarkController extends Controller */ public function update(Request $request, Bookmark $bookmark) { + abort_unless($bookmark->user()->is($request->user()), 404); + $bookmark->title = $request->post('title'); $bookmark->description = $request->post('description', ''); $bookmark->href = $request->post('href'); diff --git a/app/Http/Controllers/TagController.php b/app/Http/Controllers/TagController.php index 323526d..02ba61a 100644 --- a/app/Http/Controllers/TagController.php +++ b/app/Http/Controllers/TagController.php @@ -2,12 +2,19 @@ namespace App\Http\Controllers; -use App\Models\Bookmark; use App\Models\Tag; use Illuminate\Http\Request; +use Illuminate\Routing\Controllers\HasMiddleware; -class TagController extends Controller +class TagController extends Controller implements HasMiddleware { + public static function middleware() + { + return [ + 'auth', + ]; + } + /** * Display a listing of the resource. */ @@ -35,13 +42,15 @@ class TagController extends Controller /** * Display the specified resource. */ - public function show(Tag $tag) + public function show(Request $request, Tag $tag) { + $bookmarks = $tag->bookmarks()->where('user_id', $request->user()->id)->latest(); + return view( 'tag.show', [ 'tag' => $tag, - 'tag_count' => $tag->bookmarks()->count(), - 'bookmarks' => $tag->bookmarks()->latest()->paginate(20), + 'tag_count' => $bookmarks->count(), + 'bookmarks' => $bookmarks->paginate(20), ] ); } diff --git a/app/Jobs/ImportBookmark.php b/app/Jobs/ImportBookmark.php index 08ebbaf..f7d5f00 100644 --- a/app/Jobs/ImportBookmark.php +++ b/app/Jobs/ImportBookmark.php @@ -5,6 +5,7 @@ namespace App\Jobs; use App\Models\Bookmark; use App\Models\BookmarkTag; use App\Models\Tag; +use App\Models\User; use DateTimeImmutable; use DateTimeInterface; use Illuminate\Bus\Queueable; @@ -22,7 +23,7 @@ class ImportBookmark implements ShouldQueue /** * Create a new job instance. */ - public function __construct(array ...$bookmarks_json) + public function __construct(protected User $user, array ...$bookmarks_json) { $this->bookmarks_json = $bookmarks_json; } @@ -36,6 +37,7 @@ class ImportBookmark implements ShouldQueue $created_at = DateTimeImmutable::createFromFormat(DateTimeInterface::ISO8601_EXPANDED, $bookmark_json['time']); $bookmark = new Bookmark; + $bookmark->user()->associate($this->user); $bookmark->href = $bookmark_json['href']; $bookmark->title = $bookmark_json['description']; $bookmark->description = $bookmark_json['extended']; @@ -43,18 +45,7 @@ class ImportBookmark implements ShouldQueue $bookmark->updated_at = $created_at; $bookmark->save(); - $tags = []; - $tokens = explode(' ', $bookmark_json['tags']); - foreach ($tokens as $tag_raw) { - $tag = Tag::firstOrCreate( - [ - 'name' => $tag_raw, - ] - ); - $tags[$tag->id] = true;; - } - - $bookmark->tags()->sync(array_keys($tags)); + $bookmark->syncTagsFromString($bookmark_json['tags']); } } } diff --git a/app/Models/Bookmark.php b/app/Models/Bookmark.php index 31e25ee..cb42f1c 100644 --- a/app/Models/Bookmark.php +++ b/app/Models/Bookmark.php @@ -4,8 +4,8 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; -use Illuminate\Database\Eloquent\Relations\HasManyThrough; class Bookmark extends Model { @@ -33,4 +33,9 @@ class Bookmark extends Model { return $this->belongsToMany(Tag::class); } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } } diff --git a/app/Models/User.php b/app/Models/User.php index def621f..15ff764 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -4,6 +4,7 @@ namespace App\Models; // use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; @@ -44,4 +45,9 @@ class User extends Authenticatable 'password' => 'hashed', ]; } + + public function bookmarks(): HasMany + { + return $this->hasMany(Bookmark::class); + } } diff --git a/database/migrations/2024_05_30_214905_user_bookmark_relationship.php b/database/migrations/2024_05_30_214905_user_bookmark_relationship.php new file mode 100644 index 0000000..9d89f99 --- /dev/null +++ b/database/migrations/2024_05_30_214905_user_bookmark_relationship.php @@ -0,0 +1,33 @@ +foreignId('user_id')->after('id')->index(); + } + ); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table( + 'bookmarks', function (Blueprint $table) { + $table->dropColumn('user_id'); + } + ); + } +}; diff --git a/routes/web.php b/routes/web.php index f845935..ea14ef2 100644 --- a/routes/web.php +++ b/routes/web.php @@ -11,14 +11,14 @@ Route::get( } ); -Route::resource('bookmarks', BookmarkController::class)->middleware(['auth', 'verified']); -Route::post('/bookmarks/{bookmark}', [BookmarkController::class, 'update'])->middleware(['auth', 'verified']); +Route::resource('bookmarks', BookmarkController::class); +Route::post('/bookmarks/{bookmark}', [BookmarkController::class, 'update']); Route::resource('tags', TagController::class)->parameters( [ 'tags' => 'tag:name', // tag names in url, rather than ids ] -)->middleware(['auth', 'verified']); +); Route::get( '/dashboard', function () {