diff --git a/app/Http/Controllers/FriendController.php b/app/Http/Controllers/FriendController.php new file mode 100644 index 0000000..2e898cd --- /dev/null +++ b/app/Http/Controllers/FriendController.php @@ -0,0 +1,112 @@ +has('q')) { + $userFriends = Auth::user()->getFriends(); + foreach ($userFriends as $users) { + if (Str::contains($users->name, $request->get('q'))) { + $user = collect($users); + dd($user); + } + } + }*/ + + /* ADD THIS: search feature */ + + $user = Auth::user()->getFriends($perPage = 10); + + return view('pages.friends')->with('userFriends', $user); + } + + public function requests() + { + $user = Auth::user()->getFriendRequests(); + + return view('pages.requests')->with('userRequests', $user); + } + + public function handle($id, Request $request) + { + $action = $request->input('action'); + + if ($action == 'accept') { + $this->accept($id); + } else { + $this->decline($id); + } + + return redirect()->route('requests'); + } + + public function accept($id): void + { + $user = Auth::user(); + $recipient = User::find($id); + + if (!$user->hasFriendRequestFrom($recipient)) { + abort(404); + } + + $user->acceptFriendRequest($recipient); + } + + public function decline($id): void + { + $user = Auth::user(); + $recipient = User::find($id); + + if (!$user->hasFriendRequestFrom($recipient)) { + abort(404); + } + + $user->denyFriendRequest($recipient); + } + + public function add($id) + { + $user = Auth::user(); + $recipient = User::find($id); + + if (!$recipient || $recipient->id == $user->id) { + abort(404); + } + + if ($user->hasSentFriendRequestTo($recipient) || $user->hasFriendRequestFrom($recipient)) { + abort(404); + } + + $user->befriend($recipient); + return redirect()->back(); + } + + public function remove($id) + { + $user = Auth::user(); + $recipient = User::find($id); + + if (!$recipient || $recipient->id == $user->id) { + abort(404); + } + + if (!$user->isFriendWith($recipient)) { + abort(404); + } + + $user->unfriend($recipient); + return redirect()->back(); + } +} diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index e2ddbeb..8c1e225 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; class HomeController extends Controller { @@ -31,6 +32,8 @@ class HomeController extends Controller public function home() { - return view('home'); + $friends = Auth::user()->getFriends($perPage = 3); + + return view('home')->with('friends', $friends); } } diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php index 522c03a..a6e51d6 100644 --- a/app/Http/Controllers/PageController.php +++ b/app/Http/Controllers/PageController.php @@ -28,6 +28,7 @@ class PageController extends Controller { $user = User::find($id); $badges = DB::table('badges')->get(); + $friends = $user->getFriends($perPage = 3); if (!$user) { abort(404); @@ -35,12 +36,30 @@ class PageController extends Controller $data = [ 'user' => $user, - 'badges' => $badges + 'badges' => $badges, + 'friends' => $friends ]; return view('pages.profile')->with('data', $data); } + public function profile_friends($id) + { + $user = User::find($id); + $friends = $user->getFriends($perPage = 10); + + if (!$user) { + abort(404); + } + + $data = [ + 'user' => $user, + 'friends' => $friends + ]; + + return view('pages.profile_friends')->with('data', $data); + } + public function users(Request $request) { if ($request->has('q')) { @@ -56,9 +75,4 @@ class PageController extends Controller { return view('misc.settings'); } - - public function friends() - { - return view('pages.friends'); - } } diff --git a/app/Models/User.php b/app/Models/User.php index bd99ad6..2864537 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -8,10 +8,11 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; +use Multicaret\Acquaintances\Traits\Friendable; class User extends Authenticatable { - use HasApiTokens, HasFactory, Notifiable; + use HasApiTokens, HasFactory, Notifiable, Friendable; /** * The attributes that are mass assignable. diff --git a/composer.json b/composer.json index acb389a..dbda356 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "laravel/sanctum": "^2.11", "laravel/tinker": "^2.5", "laravel/ui": "^3.4", + "multicaret/laravel-acquaintances": "^3.5", "webpatser/laravel-uuid": "^4.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index ec7ac36..08f6aea 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": "25ae453eae609a277c5bbd141f21342f", + "content-hash": "5b427c2301ce3db3e2dbf83c41ddf6ed", "packages": [ { "name": "asm89/stack-cors", @@ -1825,6 +1825,76 @@ ], "time": "2022-06-09T08:59:12+00:00" }, + { + "name": "multicaret/laravel-acquaintances", + "version": "v3.5.6", + "source": { + "type": "git", + "url": "https://github.com/multicaret/laravel-acquaintances.git", + "reference": "702e446fec8d3ac69aa88243cef247d7602989e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/multicaret/laravel-acquaintances/zipball/702e446fec8d3ac69aa88243cef247d7602989e4", + "reference": "702e446fec8d3ac69aa88243cef247d7602989e4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "codeclimate/php-test-reporter": "^0.3.2", + "doctrine/dbal": "^2.5", + "fzaninotto/faker": "~1.4", + "laravel/laravel": "5.*", + "mockery/mockery": "1.0.x-dev", + "phpunit/phpunit": "5.*" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Multicaret\\Acquaintances\\AcquaintancesServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Multicaret\\Acquaintances\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mohamed Kawsara", + "email": "mkwsra@gmail.com" + } + ], + "description": "This light package, with no dependencies, gives Eloquent models the ability to manage friendships (with groups). And interactions such as: Likes, favorites, votes, subscribe, follow, ..etc. And it includes advanced rating system.", + "keywords": [ + "Followers", + "Rate", + "Rating", + "eloquent", + "followships", + "friend-system", + "friends", + "friendships", + "interactions", + "laravel", + "like", + "social-media", + "wish-list" + ], + "support": { + "issues": "https://github.com/multicaret/laravel-acquaintances/issues", + "source": "https://github.com/multicaret/laravel-acquaintances/tree/v3.5.6" + }, + "time": "2022-02-18T05:49:20+00:00" + }, { "name": "nesbot/carbon", "version": "2.58.0", diff --git a/config/acquaintances.php b/config/acquaintances.php new file mode 100644 index 0000000..2296c5a --- /dev/null +++ b/config/acquaintances.php @@ -0,0 +1,87 @@ + false, + + /* + * Models Related. + */ + 'model_namespace' => (int) app()->version() <= 7 ? 'App' : 'App\Models', + 'models' => [ + /* + * Model name of User model + */ + 'user' => 'User', + /* + * Model name of Interaction Relation model + */ + 'interaction_relation' => \Multicaret\Acquaintances\Models\InteractionRelation::class, + /* + * Model name of Interaction Relation model + */ + 'friendship' => \Multicaret\Acquaintances\Models\Friendship::class, + /* + * Model name of Interaction Relation model + */ + 'friendship_groups' => \Multicaret\Acquaintances\Models\FriendFriendshipGroups::class, + ], + + 'tables' => [ + /* + * Table name of interactions relations. + */ + 'interactions' => 'interactions', + /* + * user foreign key column name within interactions table. + */ + 'interactions_user_id_fk_column_name' => 'user_id', + /* + * user foreign key column type within interactions table. + */ + 'interactions_user_id_fk_column_type' => 'unsignedBigInteger', + /* + * Table name of friendships relations. + */ + 'friendships' => 'friendships', + /* + * Table name of friendship Groups relations. + */ + 'friendship_groups' => 'friendship_groups', + ], + + 'rating' => [ + 'defaults' => [ + 'amount' => 5, + /* + * Default type here is 'general', as longs as you have one criteria of rating a model + * you can ignore this setting. + * It will be the default type of rating of null is provided, if you wish to tweak this type name + * use the value below as you wish. + * + */ + 'type' => 'general', + ], + 'types' => [ + /* Add any other type that your website/application have here, + * the following added rating types are for demonstration purposes only. + * There is no effect on deleting them nor adding to them, however, its a good practice + * to not hard code your rating types, hence, please use this simple array + */ + 'delivery-time', + 'quality', + 'communication', + 'commitment', + ] + ], + + 'friendships_groups' => [ + 'acquaintances' => 0, + 'close_friends' => 1, + 'family' => 2 + ], + +]; diff --git a/database/migrations/2022_07_05_022217_create_acquaintances_friendship_table.php b/database/migrations/2022_07_05_022217_create_acquaintances_friendship_table.php new file mode 100644 index 0000000..add712b --- /dev/null +++ b/database/migrations/2022_07_05_022217_create_acquaintances_friendship_table.php @@ -0,0 +1,27 @@ +id(); + $table->morphs('sender'); + $table->morphs('recipient'); + $table->string('status')->default('pending')->comment('pending/accepted/denied/blocked/'); + $table->timestamps(); + }); + + } + + public function down() + { + Schema::dropIfExists(config('acquaintances.tables.friendships')); + } + +} diff --git a/database/migrations/2022_07_05_022217_create_acquaintances_friendships_groups_table.php b/database/migrations/2022_07_05_022217_create_acquaintances_friendships_groups_table.php new file mode 100644 index 0000000..ce8a67f --- /dev/null +++ b/database/migrations/2022_07_05_022217_create_acquaintances_friendships_groups_table.php @@ -0,0 +1,38 @@ +id(); + + $table->unsignedBigInteger('friendship_id')->unsigned(); + $table->morphs('friend'); + $table->integer('group_id')->unsigned(); + + $table->foreign('friendship_id') + ->references('id') + ->on(config('acquaintances.tables.friendships')) + ->onDelete('cascade'); + + $table->unique(['friendship_id', 'friend_id', 'friend_type', 'group_id'], 'unique'); + + }); + + } + + public function down() + { + Schema::dropIfExists(config('acquaintances.tables.friendship_groups')); + } + +} diff --git a/database/migrations/2022_07_05_022217_create_acquaintances_interactions_table.php b/database/migrations/2022_07_05_022217_create_acquaintances_interactions_table.php new file mode 100644 index 0000000..10caa8c --- /dev/null +++ b/database/migrations/2022_07_05_022217_create_acquaintances_interactions_table.php @@ -0,0 +1,48 @@ +id(); + + $userModel = config('auth.providers.users.model'); + $userModel = (new $userModel); + + $userIdFkType = config('acquaintances.tables.interactions_user_id_fk_column_type'); + $table->{$userIdFkType}('user_id')->index(); + $table->morphs('subject'); + $table->string('relation')->default('follow')->comment('follow/like/subscribe/favorite/upvote/downvote'); + $table->double('relation_value')->nullable(); + $table->string('relation_type')->nullable(); + $table->timestamps(); + + + $table->foreign('user_id') + ->references($userModel->getKeyName()) + ->on($userModel->getTable()) + ->onUpdate('cascade') + ->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::table(config('acquaintances.tables.interactions', 'interactions'), function ($table) { + $table->dropForeign(config('acquaintances.tables.interactions', 'interactions').'_user_id_foreign'); + }); + + Schema::drop(config('acquaintances.tables.interactions', 'interactions')); + } +} diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index 82c1f6a..da26fd2 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -3,7 +3,7 @@ Home - {{ env('APP_NAME') }} @endsection @section('titlediscord') - + @endsection @section('descdiscord') @@ -22,8 +22,8 @@
- Profile Image + Profile Image
skeuomorphism hater @@ -33,8 +33,8 @@
- Profile Image + Profile Image
Thomas @@ -44,8 +44,8 @@
- Profile Image + Profile Image
skeuomorphism hater @@ -55,8 +55,8 @@
- Profile Image + Profile Image
Thomas @@ -67,8 +67,8 @@
- Profile Image + Profile Image
- Profile Image + Profile Image
Thomas @@ -90,11 +90,34 @@
-

Friends (0)

+
+

Friends ({{ Auth::user()->getFriendsCount() }})

+ @if (Auth::user()->getFriendsCount() > 0) + + @endif +
+

-

You don't have any friends yet!

+ @if (Auth::user()->getFriendsCount() > 0) +
+ @foreach ($friends as $friend) + + @endforeach +
+ @else +

You don't have any friends yet!

+ @endif

Recently Played


diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index d2edfc2..c6c5091 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -57,7 +57,7 @@
- Friends + Friends @if (!Auth::guest() && count(Auth::user()->getFriendRequests())) ({{ count(Auth::user()->getFriendRequests()) }}) @endif Avatar Transactions Users diff --git a/resources/views/pages/friends.blade.php b/resources/views/pages/friends.blade.php index a5cff44..0699e2f 100644 --- a/resources/views/pages/friends.blade.php +++ b/resources/views/pages/friends.blade.php @@ -1,67 +1,48 @@ @extends('layouts.app') @section('title') -Friends - {{ env('APP_NAME') }} -@endsection -@section('titlediscord') - -@endsection -@section('descdiscord') - + Friends - {{ env('APP_NAME') }} @endsection @section('content') -

Friends

-All Friends -Pending Requests -
-
-
-

- -

-
-
-
-
-
- Profile Image -
-
- BallsGamer123 -

"I'm new to ARCHBLOX!"

- Website -
- -
+

Friends

+ All Friends + Pending Requests ({{ count(Auth::user()->getFriendRequests()) }}) +
+ +
+
+ @foreach ($userFriends as $user) +
+
+ Profile Image +
+
+ {{ $user->name }} +

"I'm new to ARCHBLOX!"

+ @if (Cache::has('is_online_' . $user->id)) + Website + @else + Offline - Last Online + {{ Carbon\Carbon::parse($user->last_seen)->diffForHumans() }} + @endif +
+
+ @csrf + +
+
+
+ @endforeach + @if (!count($userFriends)) +

You haven't made friends with anyone yet.

+ @endif + {{ $userFriends->links() }}
-
-
- Profile Image -
-
- BallsGamer123 -

"I'm new to ARCHBLOX!"

- Website -
- -
-
-
-
- Profile Image -
-
- BallsGamer123 -

"I'm new to ARCHBLOX!"

- Website -
- -
-
-
- -
-@endsection \ No newline at end of file +
+@endsection diff --git a/resources/views/pages/profile.blade.php b/resources/views/pages/profile.blade.php index c3db15f..220e649 100644 --- a/resources/views/pages/profile.blade.php +++ b/resources/views/pages/profile.blade.php @@ -1,87 +1,107 @@ @extends('layouts.app') @section('title') -{{ $data['user']->name }} - {{ env('APP_NAME') }} + {{ $data['user']->name }} - {{ env('APP_NAME') }} @endsection @section('titlediscord') - + @endsection @section('descdiscord') @endsection @section('content') -
-

{{ $data['user']->name }}

- @if (Cache::has('is_online_' . $data['user']->id)) - Website - @else - Offline - Last Online - {{ Carbon\Carbon::parse($data['user']->last_seen)->diffForHumans() }} - @endif -
- - -
-
-
-

"I'm new to ARCHBLOX!"

- profile image -

{{ $data['user']->blurb }}

+
+

{{ $data['user']->name }}

+ @if (Cache::has('is_online_' . $data['user']->id)) + Website + @else + Offline - Last Online + {{ Carbon\Carbon::parse($data['user']->last_seen)->diffForHumans() }} + @endif
-
-

Joined: {{ $data['user']->created_at->format('d/m/Y') }}

-

Place Visits: 0

-
-
-

Role

-
- @foreach ($data['badges'] as $badge) - @foreach ($data['user']->badges as $user_badge) - @if ($badge->id == $user_badge) -
- -

{{ $badge->title }}

-
+ @if (!Auth::guest() && Auth::id() != $data['user']->id) + @if (Auth::user()->hasSentFriendRequestTo($data['user'])) + + @elseif (Auth::user()->hasFriendRequestFrom($data['user'])) +
+ @csrf + + +
+ @elseif (Auth::user()->isFriendWith($data['user'])) +
+ @csrf + +
+ @else +
+ @csrf + +
@endif - @endforeach - @endforeach -
-
-

Badges

-

This user has not collected any badges yet!

+ + @endif
-
-
-

Games

- -
-

This user hasn't made any games yet!

-
-
-

Friends (1337)

- -
-
-
- Profile Image +
+
+

"I'm new to ARCHBLOX!"

+ profile image +

{{ $data['user']->blurb }}


- BallsGamer123 +
+

Joined: {{ $data['user']->created_at->format('d/m/Y') }}

+

Place Visits: 0

-
- Profile Image
- BallsGamer123 +

Role

+
+ @foreach ($data['badges'] as $badge) + @foreach ($data['user']->badges as $user_badge) + @if ($badge->id == $user_badge) +
+ +

{{ $badge->title }}

+
+ @endif + @endforeach + @endforeach
- +

Badges

+

This user has not collected any badges yet!

+
+
+
+

Games

+ +
+

This user hasn't made any games yet!

+
+
+

Friends ({{ $data['user']->getFriendsCount() }})

+ @if ($data['user']->getFriendsCount() > 0) + +
+
+ @foreach ($data['friends'] as $friend) + + @endforeach +
+ @else

This user hasn't made friends with anyone!

+ @endif
-
-
-@endsection \ No newline at end of file +
+
+@endsection diff --git a/resources/views/pages/profile_friends.blade.php b/resources/views/pages/profile_friends.blade.php new file mode 100644 index 0000000..32e82ee --- /dev/null +++ b/resources/views/pages/profile_friends.blade.php @@ -0,0 +1,42 @@ +@extends('layouts.app') +@section('title') + {{ $data['user']->name }}'s Friends - {{ env('APP_NAME') }} +@endsection + +@section('content') +

{{ $data['user']->name }}'s Friends ({{ $data['user']->getFriendsCount() }})

+
+
+ @foreach ($data['friends'] as $friend) +
+
+ Profile Image +
+
+ {{ $friend->name }} +

"I'm new to ARCHBLOX!"

+ @if (Cache::has('is_online_' . $friend->id)) + Website + @else + Offline - Last Online + {{ Carbon\Carbon::parse($friend->last_seen)->diffForHumans() }} + @endif +
+ @if (Auth::id() == $data['user']->id) +
+ @csrf + +
+ @endif +
+
+ @endforeach + @if (!$data['user']->getFriendsCount()) +

You haven't made friends with anyone yet.

+ @endif + {{ $data['friends']->links() }} +
+
+@endsection diff --git a/resources/views/pages/requests.blade.php b/resources/views/pages/requests.blade.php new file mode 100644 index 0000000..270a14b --- /dev/null +++ b/resources/views/pages/requests.blade.php @@ -0,0 +1,43 @@ +@extends('layouts.app') +@section('title') + Friend Requests - {{ env('APP_NAME') }} +@endsection + +@section('content') +

Friends

+ All Friends + Pending Requests ({{ count(Auth::user()->getFriendRequests()) }}) +
+
+
+ @foreach ($userRequests as $userReq) + @php $user = App\Models\User::find($userReq->sender_id) @endphp +
+
+ Profile Image +
+
+ {{ $user->name }} +

"I'm new to ARCHBLOX!"

+ @if (Cache::has('is_online_' . $user->id)) + Website + @else + Offline - Last Online + {{ Carbon\Carbon::parse($user->last_seen)->diffForHumans() }} + @endif +
+
+ @csrf + + +
+
+
+ @endforeach + @if (!count($userRequests)) +

You have no pending friend requests.

+ @endif +
+
+@endsection diff --git a/routes/web.php b/routes/web.php index 04058bf..089a9db 100644 --- a/routes/web.php +++ b/routes/web.php @@ -21,6 +21,7 @@ Route::get('/', [App\Http\Controllers\HomeController::class, 'index'])->name('in Route::get('/privacy', [App\Http\Controllers\PageController::class, 'privacy'])->name('privacy'); Route::get('/tos', [App\Http\Controllers\PageController::class, 'tos'])->name('tos'); Route::get('/user/{id}', [App\Http\Controllers\PageController::class, 'profile'])->name('profile'); +Route::get('/user/{id}/friends', [App\Http\Controllers\PageController::class, 'profile_friends'])->name('profile_friends'); // Must be logged in Route::middleware(['auth'])->group(function () { @@ -30,7 +31,13 @@ Route::middleware(['auth'])->group(function () { Route::get('/my/settings', [App\Http\Controllers\PageController::class, 'settings'])->name('settings'); Route::get('/my/invites', [App\Http\Controllers\KeyController::class, 'index'])->name('key_index'); Route::post('/my/invites', [App\Http\Controllers\KeyController::class, 'create'])->name('key_create'); - Route::get('/my/friends', [App\Http\Controllers\PageController::class, 'friends'])->name('friends'); + + // Friendship system routes + Route::get('/my/friends', [App\Http\Controllers\FriendController::class, 'friends'])->name('friends'); + Route::get('/my/friends/requests', [App\Http\Controllers\FriendController::class, 'requests'])->name('requests'); + Route::post('/my/friends/requests/{id}', [App\Http\Controllers\FriendController::class, 'handle'])->name('friend_handle'); + Route::post('/friends/add/{id}', [App\Http\Controllers\FriendController::class, 'add'])->name('friend_add'); + Route::post('/friends/remove/{id}', [App\Http\Controllers\FriendController::class, 'remove'])->name('friend_remove'); }); // Admin only