Skip to content

Commit

Permalink
Add public user profiles (#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kovah committed Jul 19, 2022
1 parent 26ac19a commit cbebfa4
Show file tree
Hide file tree
Showing 13 changed files with 293 additions and 25 deletions.
2 changes: 2 additions & 0 deletions app/Actions/Settings/SetDefaultSettingsForUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public function up(): void
$this->migrator->add($group . '.time_format', $defaults['time_format']);
$this->migrator->add($group . '.locale', $defaults['locale']);

$this->migrator->add($group . '.profile_is_public', $defaults['profile_is_public']);

$this->migrator->add($group . '.links_default_visibility', $defaults['links_default_visibility']);
$this->migrator->add($group . '.notes_default_visibility', $defaults['notes_default_visibility']);
$this->migrator->add($group . '.lists_default_visibility', $defaults['lists_default_visibility']);
Expand Down
11 changes: 8 additions & 3 deletions app/Helper/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,20 @@ function setupCompleted()
/**
* Shorthand for the current user settings
*
* @param string $key
* @param string $key
* @param int|null $userId
* @return mixed
*/
function usersettings(string $key = ''): mixed
function usersettings(string $key = '', ?int $userId = null): mixed
{
if (!auth()->user()) {
if (is_null($userId) && !auth()->user()) {
return null;
}

if (!is_null($userId)) {
app(UserSettings::class)::setUserId($userId);
}

if ($key === '') {
return app(UserSettings::class)->toArray();
}
Expand Down
2 changes: 0 additions & 2 deletions app/Http/Controllers/App/UserSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ public function saveAccountSettings(Request $request): RedirectResponse
*/
public function saveAppSettings(UserSettings $settings, UserSettingsUpdateRequest $request): RedirectResponse
{
$userId = $request->user()->id;

// Save all user settings or update them
$newSettings = $request->except(['_token', 'share']);
foreach ($newSettings as $key => $value) {
Expand Down
54 changes: 54 additions & 0 deletions app/Http/Controllers/Guest/UserController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace App\Http\Controllers\Guest;

use App\Enums\ModelAttribute;
use App\Http\Controllers\Controller;
use App\Models\Link;
use App\Models\LinkList;
use App\Models\Note;
use App\Models\Tag;
use App\Models\User;

class UserController extends Controller
{
public function show(User $user)
{
if (usersettings('profile_is_public', $user->id) === false) {
abort(404);
}

$links = Link::byUser($user->id)
->whereVisibility(ModelAttribute::VISIBILITY_PUBLIC)
->latest()
->take(10)
->paginate(pageName: 'link_page');

$lists = LinkList::byUser($user->id)
->whereVisibility(ModelAttribute::VISIBILITY_PUBLIC)
->latest()
->take(10)
->paginate(pageName: 'link_page');

$tags = Tag::byUser($user->id)
->whereVisibility(ModelAttribute::VISIBILITY_PUBLIC)
->latest()
->take(10)
->paginate(pageName: 'link_page');

$stats = [
'total_links' => Link::byUser($user->id)->whereVisibility(ModelAttribute::VISIBILITY_PUBLIC)->count(),
'total_lists' => LinkList::byUser($user->id)->whereVisibility(ModelAttribute::VISIBILITY_PUBLIC)->count(),
'total_tags' => Tag::byUser($user->id)->whereVisibility(ModelAttribute::VISIBILITY_PUBLIC)->count(),
'total_notes' => Note::byUser($user->id)->whereVisibility(ModelAttribute::VISIBILITY_PUBLIC)->count(),
];

return view('guest.users.show', [
'user' => $user,
'links' => $links,
'lists' => $lists,
'tags' => $tags,
'stats' => $stats,
]);
}
}
22 changes: 16 additions & 6 deletions app/Settings/UserSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class UserSettings extends Settings
public string $time_format;
public string $locale;

public bool $profile_is_public;

public int $links_default_visibility;
public int $notes_default_visibility;
public int $lists_default_visibility;
Expand Down Expand Up @@ -47,23 +49,31 @@ class UserSettings extends Settings
public bool $share_whatsapp;
public bool $share_xing;

private static int $user_id = 0;

public static function group(): string
{
return 'user-' . auth()->id();
return 'user-' . self::getUserId();
}

public static function setUserId(int $user_id): void
{
self::$user_id = $user_id;
}

protected static function getUserId(): int
{
return self::$user_id ?: auth()->id();
}

/**
* Returns the default settings for users
*
* @return array{string: string|int|bool|null}
*/
public static function defaults(): array
{
return [
'timezone' => 'UTC',
'date_format' => config('linkace.default.date_format'),
'time_format' => config('linkace.default.time_format'),
'locale' => config('app.fallback_locale'),
'profile_is_public' => false,
'links_default_visibility' => ModelAttribute::VISIBILITY_PUBLIC,
'notes_default_visibility' => ModelAttribute::VISIBILITY_PUBLIC,
'lists_default_visibility' => ModelAttribute::VISIBILITY_PUBLIC,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ protected function migrateUserSettings(): void
$this->userSettings->get('locale', config('app.fallback_locale'))
);

$this->migrator->add(
'user-1.profile_is_public',
(bool)$this->sysSettings->get('system_guest_access', false)
);

$this->migrator->add(
'user-1.links_default_visibility',
$this->userSettings->get('links_private_default', false)
Expand Down
4 changes: 3 additions & 1 deletion lang/en_US/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
'markdown_for_text' => 'Enable Markdown for descriptions and notes',

'privacy' => 'Privacy',
'default_visibility_help' => 'Choose the default visibility for Links, Lists, Notes and Tags when adding new entries.',
'profile_privacy' => 'The following settings apply to your user profile which is visible to guests.',
'profile_is_public' => 'Profile is public',
'default_visibility_help' => 'The following settings define the default visibility for Links, Lists, Notes and Tags when adding new ones.',
'links_default_visibility' => 'Default Links visibility',
'notes_default_visibility' => 'Default Notes visibility',
'lists_default_visibility' => 'Default Lists visibility',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,33 @@
@lang('settings.privacy')
</h5>

<p>@lang('settings.profile_privacy')</p>

<div class="row mb-4">
<div class="col-12 col-sm-8 col-md-6">
<label class="form-label" for="profile_is_public">
@lang('settings.profile_is_public')
</label>
<select id="profile_is_public" name="profile_is_public"
class="form-select{{ $errors->has('profile_is_public') ? ' is-invalid' : '' }}">
<option value="1"
@if(usersettings('profile_is_public') === true) selected @endif>
@lang('linkace.yes')
</option>
<option value="0"
@if(usersettings('profile_is_public') === false) selected @endif>
@lang('linkace.no')
</option>
</select>
@if ($errors->has('profile_is_public'))
<p class="invalid-feedback" role="alert">
{{ $errors->first('profile_is_public') }}
</p>
@endif
</div>
</div>


<p>@lang('settings.default_visibility_help')</p>

<div class="row">
Expand Down
103 changes: 103 additions & 0 deletions resources/views/guest/users/show.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
@extends('layouts.app')

@section('content')

<div class="card">
<div class="card-header">
@lang('user.user')
</div>
<div class="card-body">
<h2 class="mb-0">{{ $user->name }}</h2>
</div>
</div>

<div class="row">
<div class="col-12 col-md-7">

<div class="card mt-4">
<div class="card-header">
@lang('link.recent_links')
</div>

<ul class="list-group list-group-flush">
@forelse($links as $link)
<a href="{{ $link->url }}" class="list-group-item list-group-item-action one-line">
{!! $link->getIcon('me-1') !!}
{{ $link->title }}
</a>
@empty
<li class="list-group-item text-muted">
@lang('linkace.no_results_found', ['model' => trans('link.links')])
</li>
@endforelse
</ul>
</div>

</div>
<div class="col-12 col-md-5">

<div class="card mt-4">
<div class="card-header">
@lang('stats.stats')
</div>

<ul class="list-group list-group-flush">
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="me-1">@lang('stats.total_links')</span>
<span class="badge bg-secondary">{{ $stats['total_links'] }}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="me-1">@lang('stats.total_lists')</span>
<span class="badge bg-secondary">{{ $stats['total_lists'] }}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="me-1">@lang('stats.total_tags')</span>
<span class="badge bg-secondary">{{ $stats['total_tags'] }}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="me-1">@lang('stats.total_notes')</span>
<span class="badge bg-secondary">{{ $stats['total_notes'] }}</span>
</li>
</ul>
</div>

<div class="card mt-4">
<div class="card-header">
@lang('list.recent_lists')
</div>

<div class="card-body">
@forelse($lists as $list)
<a href="{{ route('guest.lists.show', ['list' => $list]) }}" class="btn btn-light btn-sm m-1">
{{ $list->name }}
</a>
@empty
<div class="text-muted">
@lang('linkace.no_results_found', ['model' => trans('list.lists')])
</div>
@endforelse
</div>
</div>

<div class="card mt-4">
<div class="card-header">
@lang('tag.recent_tags')
</div>

<div class="card-body">
@forelse($tags as $tag)
<a href="{{ route('guest.tags.show', ['tag' => $tag]) }}" class="btn btn-light btn-sm m-1">
{{ $tag->name }}
</a>
@empty
<div class="text-muted">
@lang('linkace.no_results_found', ['model' => trans('tag.tags')])
</div>
@endforelse
</div>
</div>

</div>
</div>

@endsection
13 changes: 2 additions & 11 deletions resources/views/models/users/show.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,14 @@ class="list-group-item list-group-item-action one-line">
</ul>
</div>

</div>
</div>

<div class="row">
<div class="col-12 col-md-7">

<div class="card mt-4">
<div class="card-header">
@lang('list.recent_lists')
</div>

<div class="card-body">
@forelse($lists as $list)
<a href="{{ route('lists.show', ['list' => $list]) }}" class="btn btn-light btn-sm">
<a href="{{ route('lists.show', ['list' => $list]) }}" class="btn btn-light btn-sm m-1">
{{ $list->name }}
</a>
@empty
Expand All @@ -86,17 +80,14 @@ class="list-group-item list-group-item-action one-line">
</div>
</div>

</div>
<div class="col-12 col-md-5">

<div class="card mt-4">
<div class="card-header">
@lang('tag.recent_tags')
</div>

<div class="card-body">
@forelse($tags as $tag)
<a href="{{ route('tags.show', ['tag' => $tag]) }}" class="btn btn-light btn-sm">
<a href="{{ route('tags.show', ['tag' => $tag]) }}" class="btn btn-light btn-sm m-1">
{{ $tag->name }}
</a>
@empty
Expand Down
3 changes: 3 additions & 0 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use App\Http\Controllers\Guest\LinkController as GuestLinkController;
use App\Http\Controllers\Guest\ListController as GuestListController;
use App\Http\Controllers\Guest\TagController as GuestTagController;
use App\Http\Controllers\Guest\UserController as GuestUserController;
use App\Http\Controllers\Models\LinkController;
use App\Http\Controllers\Models\ListController;
use App\Http\Controllers\Models\NoteController;
Expand Down Expand Up @@ -180,6 +181,8 @@
Route::get('tags/feed', [GuestFeedController::class, 'tags'])->name('guest.tags.feed');
Route::get('tags/{tag}/feed', [GuestFeedController::class, 'tagLinks'])->name('guest.tags.links.feed');

Route::get('users/{user:name}', [GuestUserController::class, 'show'])->name('guest.users.show');

Route::resource('links', GuestLinkController::class)
->only(['index'])
->names([
Expand Down
4 changes: 2 additions & 2 deletions tests/Controller/App/FeedControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class FeedControllerTest extends TestCase
{
use RefreshDatabase;

private $user;
private User $user;

protected function setUp(): void
{
Expand Down Expand Up @@ -82,7 +82,7 @@ public function testTagLinkFeed(): void
$tagLink = Link::factory()->create();
$unrelatedLink = Link::factory()->create();

$tagLink->tags()->sync(['tag' => $tag]);
$tagLink->tags()->sync([$tag->id]);

$response = $this->getAuthorized('tags/1/feed');

Expand Down
Loading

0 comments on commit cbebfa4

Please sign in to comment.