Skip to content
This repository has been archived by the owner on Aug 12, 2021. It is now read-only.

User Profile with Conference List #56

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/Conference.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class Conference extends Model
{
protected $fillable = ['name', 'start_date', 'end_date', 'slug'];
protected $fillable = ['name', 'conf_url', 'start_date', 'end_date', 'slug'];
protected $casts = ['user_id' => 'integer'];
protected $dates = ['start_date', 'end_date'];

Expand Down
38 changes: 38 additions & 0 deletions app/Events/UserWasAdded.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace App\Events;

use App\Events\Event;
use App\User;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;

class UserWasAdded extends Event
{
use SerializesModels;

/**
* @var \App\User
*/
public $user;

/**
* Create a new event instance.
*
* @return void
*/
public function __construct(User $user)
{
$this->user = $user;
}

/**
* Get the channels the event should be broadcast on.
*
* @return array
*/
public function broadcastOn()
{
return [];
}
}
7 changes: 4 additions & 3 deletions app/Friend.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ protected static function boot()
parent::boot();

/**
* When deleting a friend, if they are the last record in the database
* with the given username, delete the cached avatar from storage.
* When deleting a friend, if they are the last friend record in the database
* with the given username and they are not themselves a user, delete the
* cached avatar from storage.
*/
static::deleted(function ($friend) {
if (! static::where('username', $friend->username)->exists()) {
if (! static::where('username', $friend->username)->exists() && ! User::where('twitter_nickname')->exists()) {
if (file_exists($avatar_path = public_path($friend->avatar))) {
@unlink($avatar_path);
}
Expand Down
4 changes: 3 additions & 1 deletion app/Http/Controllers/API/ConferencesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@ public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'conf_url' => 'sometimes|active_url',
'start_date' => 'required|date_format:Y-m-d',
'end_date' => 'required|date_format:Y-m-d|after:' . dayBefore($request->start_date),
]);

return Auth::user()->addConference($request->only([
'name',
'conf_url',
'start_date',
'end_date',
]));
}

public function index()
{
return Auth::user()->conferences()->get();
return Auth::user()->conferences;
}

public function delete(Conference $conference)
Expand Down
64 changes: 64 additions & 0 deletions app/Http/Controllers/API/UserController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace App\Http\Controllers\API;

use App\Conference;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;

class UserController extends Controller
{
public function getUserConferences(User $user)
{
if (! $user->conferenceListIsPublic) {
return response('no_content', 204);
}
$conferences = $user->conferences()->orderBy('start_date', 'desc')->get();
$conferences->transform(function ($conference) {
$conference->timeframe = ($conference->isUpcoming()) ? "future" : "past";

return $conference;
});

return $conferences->groupBy('timeframe');
}

public function delete(Conference $conference)
{
abort_if($conference->user_id !== Auth::user()->id, 404);

$conference->delete();
}

public function settings()
{
$user = Auth::user();

return [
"userIsSearchable" => isset($user->userIsSearchable) ? $user->userIsSearchable : false ,
"conferenceListIsPublic" => isset($user->conferenceListIsPublic) ? $user->conferenceListIsPublic : false,
];
}

public function updateSettings(Request $request)
{
$user = Auth::user();

$request->replace([
'userIsSearchable' => (boolean) $request->userIsSearchable,
'conferenceListIsPublic' => (boolean) $request->conferenceListIsPublic,
]);

$this->validate($request, [
'userIsSearchable' => 'required|boolean',
'conferenceListIsPublic' => 'required|boolean',
]);

$user->userIsSearchable = $request->userIsSearchable;
$user->conferenceListIsPublic = $request->conferenceListIsPublic;
$user->save();
}
}
4 changes: 4 additions & 0 deletions app/Http/Controllers/Auth/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Http\Controllers\Auth;

use App\Events\UserWasAdded;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
Expand Down Expand Up @@ -51,9 +52,12 @@ public function handleTwitterCallback()
Auth::login($user = User::create([
'name' => $twitter->name,
'twitter_id' => $twitter->id,
'twitter_nickname' => $twitter->nickname,
]), true);
}

event(new UserWasAdded($user));

return redirect('/');
}

Expand Down
18 changes: 17 additions & 1 deletion app/Http/Controllers/AvatarController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

use App\Friend;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Support\Facades\File;

class AvatarController extends Controller
{
public function show($username)
{
if (! $friend = Friend::where('username', $username)->first()) {
return $this->defaultAvatarResponse();
return $this->showUser($username);
}

if (! file_exists(public_path($friend->avatar))) {
Expand All @@ -27,4 +28,19 @@ private function defaultAvatarResponse()
{
return $this->fileResponse(public_path('assets/img/default_avatar.png'), ['Content-type' => 'image/png']);
}

private function showUser($username)
{
if (! $user = User::where('twitter_nickname', $username)->first()) {
return $this->defaultAvatarResponse();
}

if (! file_exists(public_path($user->avatar))) {
return $this->defaultAvatarResponse();
}

$mimeType = File::mimeType($avatar_path = public_path($user->avatar));

return $this->fileResponse($avatar_path, ['Content-type' => $mimeType]);
}
}
21 changes: 21 additions & 0 deletions app/Http/Controllers/UserController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Support\Facades\Auth;

class UserController extends Controller
{
public function show(User $user)
{
return view('users.show')
->with('user', $user);
}

public function settings()
{
return view('users.settings')
->with('user', Auth::user());
}
}
8 changes: 8 additions & 0 deletions app/Http/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
return view('dashboard');
});

Route::get('users/{twitter_nickname}', 'UserController@show');
Route::get('settings', 'UserController@settings');

Route::get('conferences/{conference}', 'ConferencesController@show');
});

Expand All @@ -29,6 +32,11 @@
Route::patch('{conference}/online-friends/{friend}', 'ConferenceOnlineFriendsController@update');
Route::delete('{conference}/online-friends/{friend}', 'ConferenceOnlineFriendsController@delete');
});
Route::group(['prefix' => 'users'], function () {
Route::get('{twitter_nickname}/conferences', 'UserController@getUserConferences');
});
Route::get('settings', 'UserController@settings');
Route::post('settings', 'UserController@updateSettings');
});

Route::get('local-login', 'Auth\AuthController@localLogin');
Expand Down
48 changes: 48 additions & 0 deletions app/Jobs/FetchUserAvatar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace App\Jobs;

use Abraham\TwitterOAuth\TwitterOAuth;
use App\User;
use Exception;
use Illuminate\Contracts\Bus\SelfHandling;

class FetchUserAvatar extends Job implements SelfHandling
{
/**
* @var \App\User
*/
private $user;

/**
* Create a new job instance.
*
* @param \App\Friend $friend
* @return void
*/
public function __construct(User $user)
{
$this->user = $user;
}

/**
* Execute the job.
*
* @return void
*/
public function handle()
{
try {
$details = app(TwitterOAuth::class)->get('users/show', ['screen_name' => $this->user->twitter_nickname]);
$url = str_replace('_normal', '', $details->profile_image_url_https);

if (@file_put_contents(public_path($this->user->avatar), @file_get_contents($url))) {
return true;
}
} catch (Exception $e) {
// No big deal, as we have a default avatar
}

return false;
}
}
35 changes: 35 additions & 0 deletions app/Listeners/FetchUserAvatar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace App\Listeners;

use App\Events\UserWasAdded;
use App\Jobs\FetchUserAvatar as FetchJob;
use Illuminate\Foundation\Bus\DispatchesJobs;

class FetchUserAvatar
{
use DispatchesJobs;

/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}

/**
* Handle the event.
*
* @param UserWasAdded $event
* @return void
*/
public function handle(UserWasAdded $event)
{
if (! file_exists(public_path($event->user->avatar))) {
$this->dispatch(new FetchJob($event->user));
}
}
}
3 changes: 3 additions & 0 deletions app/Providers/EventServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class EventServiceProvider extends ServiceProvider
'App\Events\FriendWasAdded' => [
'App\Listeners\FetchFriendAvatar',
],
'App\Events\UserWasAdded' => [
'App\Listeners\FetchUserAvatar',
],
];

/**
Expand Down
4 changes: 4 additions & 0 deletions app/Providers/RouteServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Conference;
use App\Friend;
use App\User;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Routing\Router;

Expand Down Expand Up @@ -32,6 +33,9 @@ public function boot(Router $router)
return Conference::where('slug', $conference)->firstOrFail();
});
$router->model('friend', Friend::class);
$router->bind('twitter_nickname', function ($nickname) {
return User::where('twitter_nickname', $nickname)->firstOrFail();
});
}

/**
Expand Down
Loading