From a9f012572c6acbb60b8ea514400307edd90c85ff Mon Sep 17 00:00:00 2001 From: Diana Chan Date: Thu, 31 Aug 2023 02:43:14 -0700 Subject: [PATCH 1/4] Fixes #24 - Added ability for users to share their closet and/or wishlist to the public. Added toggle to the user's profile. Changed the URL of closet and wishlist to be /profile//closet and /profile//wishlist. Redirected the old /profile/wishlist and /profile/closet links to the user's own wishlist/profile links if they're logged in. --- app/Http/Controllers/ProfileController.php | 13 ++-- .../Controllers/PublicProfileController.php | 61 +++++++++++++++ app/Http/Kernel.php | 1 + .../AllowOwnerOrPublicViewEnabled.php | 21 ++++++ ...56____add_public_wishlist_closet_flags.php | 33 +++++++++ resources/lang/en/ui.php | 6 ++ .../components/navbar/dropdown.blade.php | 4 +- resources/views/profile/closet.blade.php | 74 ++++++++++--------- resources/views/profile/index.blade.php | 8 ++ resources/views/profile/layout.blade.php | 21 ++++-- resources/views/profile/wishlist.blade.php | 74 ++++++++++--------- routes/web.php | 2 + 12 files changed, 238 insertions(+), 80 deletions(-) create mode 100644 app/Http/Controllers/PublicProfileController.php create mode 100644 app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php create mode 100644 database/migrations/0056____add_public_wishlist_closet_flags.php diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 4d80ff71..50a8ea28 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -28,8 +28,9 @@ public function __construct() public function profile() { $user = Auth::user(); + $isOwner = true; - return view('profile.index', compact('user')); + return view('profile.index', compact('user', 'isOwner')); } /** @@ -72,6 +73,9 @@ public function update(Request $request) $user->password = Hash::make($validatedData['password']); } + $user->public_closet = $request->has('public_closet') == '1' ? '1' : '0'; + $user->public_wishlist = $request->has('public_wishlist') == '1' ? '1' : '0'; + $user->save(); return redirect('profile')->with('status', $status); @@ -86,9 +90,8 @@ public function update(Request $request) public function closet(Request $request) { $user = Auth::user(); - $items = $user->closet($request->input('order'))->paginate(24); - return view('profile.closet', compact('user', 'items')); + return redirect()->route('public_closet', ['username' => $user->username]); } /** @@ -100,8 +103,6 @@ public function closet(Request $request) public function wishlist(Request $request) { $user = Auth::user(); - $items = $user->wishlist($request->input('order'))->paginate(24); - - return view('profile.wishlist', compact('user', 'items')); + return redirect()->route('public_wishlist', ['username' => $user->username]); } } diff --git a/app/Http/Controllers/PublicProfileController.php b/app/Http/Controllers/PublicProfileController.php new file mode 100644 index 00000000..c28f2d20 --- /dev/null +++ b/app/Http/Controllers/PublicProfileController.php @@ -0,0 +1,61 @@ +middleware('auth.owner'); + } + + + /** + * Get a user's closet (owned items). + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function closet(Request $request) + { + $requestedUser = $request->get('requestedUser'); + $isOwner = $request->get('isOwner'); + + if (!$isOwner && !$requestedUser->public_closet) { + abort(404); + } + + $items = $requestedUser->closet($request->input('order'))->paginate(24); + + $user = $requestedUser; + return view('profile.closet', compact('user', 'items', 'isOwner')); + } + + /** + * Get a user's wishlist (favourited items). + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function wishlist(Request $request) + { + $requestedUser = $request->get('requestedUser'); + $isOwner = $request->get('isOwner'); + + if (!$isOwner && !$requestedUser->public_wishlist) { + abort(404); + } + + $items = $requestedUser->wishlist($request->input('order'))->paginate(24); + + $user = $requestedUser; + return view('profile.wishlist', compact('user', 'items', 'isOwner')); + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index a974b3ab..facb6c92 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -54,6 +54,7 @@ class Kernel extends HttpKernel protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'auth.owner' => \App\Http\Middleware\AllowOwnerOrPublicViewEnabled::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, diff --git a/app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php b/app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php new file mode 100644 index 00000000..c9a766f5 --- /dev/null +++ b/app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php @@ -0,0 +1,21 @@ +route('username'); + $requestedUser = User::where('username', $username)->firstOrFail(); + $isOwner = (!empty($currentUser) && $currentUser->id == $requestedUser->id); + $request->attributes->add(['isOwner' => $isOwner, 'requestedUser' => $requestedUser]); + + return $next($request); + } +} diff --git a/database/migrations/0056____add_public_wishlist_closet_flags.php b/database/migrations/0056____add_public_wishlist_closet_flags.php new file mode 100644 index 00000000..011d2d92 --- /dev/null +++ b/database/migrations/0056____add_public_wishlist_closet_flags.php @@ -0,0 +1,33 @@ +tinyInteger('public_wishlist')->unsigned()->default(0); + $table->tinyInteger('public_closet')->unsigned()->default(0); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn(['public_wishlist', 'public_closet']); + }); + } +} diff --git a/resources/lang/en/ui.php b/resources/lang/en/ui.php index 44d6609c..7c91cb45 100644 --- a/resources/lang/en/ui.php +++ b/resources/lang/en/ui.php @@ -41,6 +41,8 @@ 'pw_reset_btn' => 'Send Password Reset Link', 'pw_no_change' => "Leave this blank if you don't want to change your password.", 'username_txt' => 'To change your username, click here', + 'public_closet' => 'Make closet public?', + 'public_wishlist' => 'Make wishlist public?', ], 'blog' => [ @@ -77,8 +79,10 @@ 'removed' => 'Removed ":item" from your wishlist', 'stargazers' => 'Stargazer|Stargazers', 'title' => 'Wishlist', + 'owner_title' => ":user's Wishlist", 'remove' => 'Remove from Wishlist', 'empty' => 'There are no items in your wishlist.', + 'empty_guest' => "There are no items in :user's wishlist", 'add' => 'Why not search for some items to add?', ], @@ -87,8 +91,10 @@ 'removed' => 'Removed ":item" from your closet', 'owners' => 'Owner|Owners', 'title' => 'Closet', + 'owner_title' => ":user's Closet", 'remove' => 'Remove from Closet', 'empty' => 'There are no items in your closet.', + 'empty_guest' => "There are no items in :user's closet", 'add' => 'Why not search for some items to add?', ], diff --git a/resources/views/components/navbar/dropdown.blade.php b/resources/views/components/navbar/dropdown.blade.php index f4abfece..cda07480 100644 --- a/resources/views/components/navbar/dropdown.blade.php +++ b/resources/views/components/navbar/dropdown.blade.php @@ -8,11 +8,11 @@ {{ __('Profile') }} - + {{ __('Wishlist') }} - + {{ __('Closet') }} diff --git a/resources/views/profile/closet.blade.php b/resources/views/profile/closet.blade.php index 825c9a86..5cf05a20 100644 --- a/resources/views/profile/closet.blade.php +++ b/resources/views/profile/closet.blade.php @@ -1,4 +1,4 @@ -@extends('profile.layout', ['title' => __('ui.closet.title')]) +@extends('profile.layout', ['title' => __('ui.closet.owner_title', ['user' => $user->username])]) @section('profile') @if ($items->count() > 0) @@ -6,16 +6,18 @@ @foreach ($items as $item)
@component('items.card', ['item' => $item, 'type' => 'small']) -
- @csrf - + @if ($isOwner) + + @csrf + - -
+ + + @endif @endcomponent
@endforeach @@ -23,32 +25,38 @@ {{ $items->links() }} @else -
-

{{ __('ui.closet.empty') }}

-

@lang('ui.closet.add', ['link' => route('search')])

-
-
-
-
-
- -
+ @if ($isOwner) +
+

{{ __('ui.closet.empty') }}

+

@lang('ui.closet.add', ['link' => route('search')])

-
-
-
-
- +
+
+
+
+ +
+
-
-
-
-
-
- +
+
+
+ +
+
+
+
+
+
+ +
+
-
-
+ @else +
+

{{ __('ui.closet.empty_guest', ['user' => $user->username]) }}

+
+ @endif @endif @endsection diff --git a/resources/views/profile/index.blade.php b/resources/views/profile/index.blade.php index d43216ed..d86fc063 100644 --- a/resources/views/profile/index.blade.php +++ b/resources/views/profile/index.blade.php @@ -37,6 +37,14 @@ {{ __('ui.auth.pw_no_change') }}
+
+ public_wishlist) checked @endif/> + +
+
+ public_closet) checked @endif/> + +
diff --git a/resources/views/profile/layout.blade.php b/resources/views/profile/layout.blade.php index 14c42eb1..e89a0dee 100644 --- a/resources/views/profile/layout.blade.php +++ b/resources/views/profile/layout.blade.php @@ -7,20 +7,29 @@
+
+ {{ $user->username }} +
diff --git a/resources/views/profile/wishlist.blade.php b/resources/views/profile/wishlist.blade.php index 83e3dc14..098be262 100644 --- a/resources/views/profile/wishlist.blade.php +++ b/resources/views/profile/wishlist.blade.php @@ -1,4 +1,4 @@ -@extends('profile.layout', ['title' => __('ui.wishlist.title')]) +@extends('profile.layout', ['title' => __('ui.wishlist.owner_title', ['user' => $user->username])]) @section('profile') @if ($items->count() > 0) @@ -6,16 +6,18 @@ @foreach ($items as $item)
@component('items.card', ['item' => $item, 'type' => 'small']) -
- @csrf - + @if ($isOwner) + + @csrf + - -
+ + + @endif @endcomponent
@endforeach @@ -23,32 +25,38 @@ {{ $items->links() }} @else -
-

{{ __('ui.wishlist.empty') }}

-

@lang('ui.wishlist.add', ['link' => route('search')])

-
-
-
-
-
- -
+ @if ($isOwner) +
+

{{ __('ui.wishlist.empty') }}

+

@lang('ui.wishlist.add', ['link' => route('search')])

-
-
-
-
- +
+
+
+
+ +
+
-
-
-
-
-
- +
+
+
+ +
+
+
+
+
+
+ +
+
-
-
+ @else +
+

{{ __('ui.wishlist.empty_guest', ['user' => $user->username]) }}

+
+ @endif @endif @endsection diff --git a/routes/web.php b/routes/web.php index d22e692c..2e1754e9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -23,7 +23,9 @@ Route::get('/', 'ProfileController@profile')->name('profile'); Route::post('/', 'ProfileController@update')->name('update'); Route::get('closet', 'ProfileController@closet')->name('closet'); + Route::get('{username}/closet', 'PublicProfileController@closet')->name('public_closet'); Route::get('wishlist', 'ProfileController@wishlist')->name('wishlist'); + Route::get('{username}/wishlist', 'PublicProfileController@wishlist')->name('public_wishlist'); }); // auth endpoint (for mediawiki) From ce441fbad72977ca52a0d1d5c23ef5387021bf91 Mon Sep 17 00:00:00 2001 From: Diana Chan Date: Thu, 31 Aug 2023 15:35:43 -0700 Subject: [PATCH 2/4] #24 Add more error handling --- app/Http/Controllers/PublicProfileController.php | 4 ++-- app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/PublicProfileController.php b/app/Http/Controllers/PublicProfileController.php index c28f2d20..b1f9bbd0 100644 --- a/app/Http/Controllers/PublicProfileController.php +++ b/app/Http/Controllers/PublicProfileController.php @@ -28,7 +28,7 @@ public function closet(Request $request) $requestedUser = $request->get('requestedUser'); $isOwner = $request->get('isOwner'); - if (!$isOwner && !$requestedUser->public_closet) { + if (empty($requestedUser) || (!$isOwner && !$requestedUser->public_closet)) { abort(404); } @@ -49,7 +49,7 @@ public function wishlist(Request $request) $requestedUser = $request->get('requestedUser'); $isOwner = $request->get('isOwner'); - if (!$isOwner && !$requestedUser->public_wishlist) { + if (empty($requestedUser) || (!$isOwner && !$requestedUser->public_wishlist)) { abort(404); } diff --git a/app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php b/app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php index c9a766f5..015f3b64 100644 --- a/app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php +++ b/app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php @@ -12,8 +12,11 @@ public function handle($request, Closure $next) { $currentUser = Auth::user(); $username = $request->route('username'); - $requestedUser = User::where('username', $username)->firstOrFail(); - $isOwner = (!empty($currentUser) && $currentUser->id == $requestedUser->id); + $requestedUser = User::where('username', $username)->first(); + $isOwner = ( + !empty($currentUser) && !empty($requestedUser) + && $currentUser->id == $requestedUser->id + ); $request->attributes->add(['isOwner' => $isOwner, 'requestedUser' => $requestedUser]); return $next($request); From 390e3e1d3c927db500cb378bd5d0a20022d7c4a4 Mon Sep 17 00:00:00 2001 From: Diana Chan Date: Thu, 31 Aug 2023 15:52:10 -0700 Subject: [PATCH 3/4] #24 - Updated some comments --- app/Http/Controllers/PublicProfileController.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/PublicProfileController.php b/app/Http/Controllers/PublicProfileController.php index b1f9bbd0..bf3f8d28 100644 --- a/app/Http/Controllers/PublicProfileController.php +++ b/app/Http/Controllers/PublicProfileController.php @@ -7,7 +7,7 @@ class PublicProfileController extends Controller { /** - * Construct a new Profile Controller. + * Construct a new Public Profile Controller. * * @return void */ @@ -18,7 +18,7 @@ public function __construct() /** - * Get a user's closet (owned items). + * Get a given user's closet (owned items). * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response @@ -39,7 +39,7 @@ public function closet(Request $request) } /** - * Get a user's wishlist (favourited items). + * Get a given user's wishlist (favourited items). * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response From b8135d00706608199aa7d723674140bbf25d9ab0 Mon Sep 17 00:00:00 2001 From: Diana Chan Date: Thu, 31 Aug 2023 16:03:34 -0700 Subject: [PATCH 4/4] #24 - Rename middleware --- app/Http/Kernel.php | 2 +- ...wOwnerOrPublicViewEnabled.php => CheckIfOwnerIsLoggedIn.php} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename app/Http/Middleware/{AllowOwnerOrPublicViewEnabled.php => CheckIfOwnerIsLoggedIn.php} (94%) diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index facb6c92..b1020c99 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -54,7 +54,7 @@ class Kernel extends HttpKernel protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, - 'auth.owner' => \App\Http\Middleware\AllowOwnerOrPublicViewEnabled::class, + 'auth.owner' => \App\Http\Middleware\CheckIfOwnerIsLoggedIn::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, diff --git a/app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php b/app/Http/Middleware/CheckIfOwnerIsLoggedIn.php similarity index 94% rename from app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php rename to app/Http/Middleware/CheckIfOwnerIsLoggedIn.php index 015f3b64..8520cbcf 100644 --- a/app/Http/Middleware/AllowOwnerOrPublicViewEnabled.php +++ b/app/Http/Middleware/CheckIfOwnerIsLoggedIn.php @@ -6,7 +6,7 @@ use Closure; use Illuminate\Support\Facades\Auth; -class AllowOwnerOrPublicViewEnabled +class CheckIfOwnerIsLoggedIn { public function handle($request, Closure $next) {