Merge user settings page #101
@ -7,14 +7,115 @@ use App\Facade\Theme;
|
||||
use App\Facade\UserConfig;
|
||||
use App\Helpers\DbHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\SaveUserSettingsRequest;
|
||||
use App\Mail\UserChangeEmailRequired;
|
||||
use App\User;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function confirmEmailChangeState(Request $request)
|
||||
{
|
||||
$user = $this->getUser();
|
||||
if (!$user->is_email_change_in_progress)
|
||||
{
|
||||
return redirect(route('userSettings'));
|
||||
}
|
||||
|
||||
// Update the e-mail address
|
||||
$user->email = $user->new_email_address;
|
||||
|
||||
// Reset the e-mail change state
|
||||
$user->is_email_change_in_progress = false;
|
||||
$user->new_email_address = null;
|
||||
$user->save();
|
||||
|
||||
$request->session()->flash('success', trans('auth.change_email_success_message'));
|
||||
return redirect(route('userSettings'));
|
||||
}
|
||||
|
||||
public function resetEmailChangeState(Request $request)
|
||||
{
|
||||
$user = $this->getUser();
|
||||
if (!$user->is_email_change_in_progress)
|
||||
{
|
||||
return redirect(route('userSettings'));
|
||||
}
|
||||
|
||||
$data = $request->all();
|
||||
|
||||
if (isset($data['resend_email']))
|
||||
{
|
||||
$this->sendEmailChangeConfirmationEmail($user, $user->new_email_address);
|
||||
$request->session()->flash('info', trans('auth.change_email_required_message'));
|
||||
}
|
||||
|
||||
if (isset($data['cancel_change']))
|
||||
{
|
||||
$user->is_email_change_in_progress = false;
|
||||
$user->new_email_address = null;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
return redirect(route('userSettings'));
|
||||
}
|
||||
|
||||
public function saveSettings(SaveUserSettingsRequest $request)
|
||||
{
|
||||
$data = $request->only(['name', 'email', 'profile_alias', 'enable_profile_page']);
|
||||
$user = $this->getUser();
|
||||
|
||||
if (
|
||||
UserConfig::get('require_email_verification') &&
|
||||
isset($data['email']) &&
|
||||
$data['email'] != $user->email &&
|
||||
!$user->is_email_change_in_progress
|
||||
)
|
||||
{
|
||||
// Can't update the e-mail directly until the new e-mail address has been verified.
|
||||
// TODO - send e-mail and handle response, flag e-mail as being "change in-progress"
|
||||
// Send activation e-mail
|
||||
|
||||
$this->sendEmailChangeConfirmationEmail($user, $data['email']);
|
||||
$request->session()->flash('info', trans('auth.change_email_required_message'));
|
||||
|
||||
// Flag the user as a change e-mail in progress
|
||||
$user->new_email_address = $data['email'];
|
||||
$user->is_email_change_in_progress = true;
|
||||
$user->save();
|
||||
|
||||
unset($data['email']);
|
||||
$request->session()->flash('info', trans('auth.change_email_required_message'));
|
||||
}
|
||||
|
||||
// Don't allow e-mail address to be changed if a change is in progress
|
||||
if ($user->is_email_change_in_progress)
|
||||
{
|
||||
unset($data['email']);
|
||||
}
|
||||
|
||||
$user->fill($data);
|
||||
$user->enable_profile_page = (isset($data['enable_profile_page']) && strtolower($data['enable_profile_page']) == 'on');
|
||||
$user->save();
|
||||
|
||||
$request->session()->flash('success', trans('gallery.user_settings.settings_saved'));
|
||||
|
||||
return redirect(route('userSettings'));
|
||||
}
|
||||
|
||||
public function settings(Request $request)
|
||||
{
|
||||
return Theme::render('gallery.user_settings', [
|
||||
'info' => $request->session()->get('info'),
|
||||
'success' => $request->session()->get('success'),
|
||||
'user' => $this->getUser()
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(Request $request, $idOrAlias)
|
||||
{
|
||||
// If a user has a profile alias set, their profile page cannot be accessed by the ID
|
||||
@ -198,4 +299,13 @@ class UserController extends Controller
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
private function sendEmailChangeConfirmationEmail(User $user, $newEmailAddress)
|
||||
{
|
||||
$oldEmailAddress = $user->email;
|
||||
$user->email = $newEmailAddress;
|
||||
|
||||
Mail::to($user)->send(new UserChangeEmailRequired($user));
|
||||
$user->email = $oldEmailAddress;
|
||||
}
|
||||
}
|
33
app/Http/Requests/SaveUserSettingsRequest.php
Normal file
33
app/Http/Requests/SaveUserSettingsRequest.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class SaveUserSettingsRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => 'required|max:255',
|
||||
'email' => 'required|email|max:255|unique:users,email,' . Auth::user()->id,
|
||||
'profile_alias' => 'sometimes|max:255|unique:users,profile_alias,' . Auth::user()->id
|
||||
];
|
||||
}
|
||||
}
|
46
app/Mail/UserChangeEmailRequired.php
Normal file
46
app/Mail/UserChangeEmailRequired.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Facade\Theme;
|
||||
use App\Facade\UserConfig;
|
||||
use App\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class UserChangeEmailRequired extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$subject = trans('email.change_email_required_subject', ['app_name' => UserConfig::get('app_name')]);
|
||||
|
||||
return $this
|
||||
->subject($subject)
|
||||
->markdown(Theme::viewName('email.user_change_email_required'))
|
||||
->with([
|
||||
'subject' => $subject,
|
||||
'user' => $this->user
|
||||
]);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddUserEmailChangeColumns extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table)
|
||||
{
|
||||
$table->boolean('is_email_change_in_progress')->default(false);
|
||||
$table->string('new_email_address')->nullable(true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table)
|
||||
{
|
||||
$table->dropColumn('is_email_change_in_progress');
|
||||
$table->dropColumn('new_email_address');
|
||||
});
|
||||
}
|
||||
}
|
@ -20,6 +20,9 @@ return [
|
||||
'and password you provided when you registered.',
|
||||
'activation_required_message' => 'An e-mail containing an activation link has been sent to the e-mail address you provided. ' .
|
||||
'Please click the link in this e-mail to activate your account.',
|
||||
'change_email_required_message' => 'An e-mail containing an activation link has been sent to the e-mail address you provided. ' .
|
||||
'Please click the link in this e-mail to confirm your new e-mail address.',
|
||||
'change_email_success_message' => 'Your e-mail address change has been confirmed. You will now need to login with your new e-mail address.',
|
||||
'change_password_action' => 'Change password',
|
||||
'change_password_title' => 'Change your password',
|
||||
'email_password_login' => 'Alternatively, login with your e-mail address and password:',
|
||||
|
@ -4,6 +4,9 @@ return [
|
||||
'activation_required_p2' => 'To confirm your e-mail address and activate your account, please click the link below. ' .
|
||||
'You may also need to copy + paste this into your browser\'s address bar if your e-mail reader has split this line.',
|
||||
'activation_required_subject' => 'Activate your :app_name account',
|
||||
'change_email_required_p1' => 'A change was requested to your e-mail address on :app_name.',
|
||||
'change_email_required_p2' => 'To confirm this e-mail address is valid and update the e-mail address on your account, please click the button below.',
|
||||
'change_email_required_subject' => 'Confirm the e-mail change to your :app_name account',
|
||||
'generic_intro' => 'Hi :user_name,',
|
||||
'generic_regards' => 'Regards,',
|
||||
'test_email_subject' => 'Test e-mail from :app_name'
|
||||
|
@ -14,6 +14,7 @@ return [
|
||||
'bulk_edit_photos_placeholder' => 'Select an action',
|
||||
'cancel_action' => 'Cancel',
|
||||
'close_action' => 'Close',
|
||||
'confirm_email_action' => 'Confirm e-mail address',
|
||||
'continue_action' => 'Continue',
|
||||
'create_action' => 'Create',
|
||||
'create_album_label' => 'Create a new album:',
|
||||
@ -24,6 +25,7 @@ return [
|
||||
'download_action' => 'Download',
|
||||
'edit_action' => 'Edit',
|
||||
'email_label' => 'E-mail address:',
|
||||
'enable_profile_page_label' => 'Allow others to see my profile page',
|
||||
'labels_label' => 'Labels:',
|
||||
'login_action' => 'Login',
|
||||
'name_label' => 'Name:',
|
||||
@ -33,6 +35,8 @@ return [
|
||||
'password_confirm_label' => 'Confirm password:',
|
||||
'please_select' => '- Select an Option -',
|
||||
'private_album_label' => 'Private album (only visible to me)',
|
||||
'profile_alias_label' => 'Alias:',
|
||||
'profile_alias_help' => 'The profile alias is used to create a unique URL direct to your profile page.',
|
||||
'quick_upload_file_label' => 'Photo:',
|
||||
'realname_label' => 'Your name:',
|
||||
'register_action' => 'Create account',
|
||||
|
@ -77,5 +77,13 @@ return [
|
||||
'cameras' => 'Cameras',
|
||||
'no_albums_p1' => 'No Photo Albums',
|
||||
'no_albums_p2' => ':user_name has not created any albums yet.'
|
||||
],
|
||||
'user_settings' => [
|
||||
'cancel_email_change' => 'Don\'t change e-mail address',
|
||||
'change_email_in_progress' => 'To confirm your new e-mail address, please click on the "confirm" link in the e-mail that was sent to: <b>:new_email_address</b>.',
|
||||
'change_email_resend' => 'Re-send confirmation e-mail.',
|
||||
'change_password' => 'Change password',
|
||||
'settings_saved' => 'Your settings were updated successfully.',
|
||||
'title' => 'Change my settings'
|
||||
]
|
||||
];
|
@ -36,6 +36,7 @@ return [
|
||||
'public_profile_page' => 'My public profile',
|
||||
'quick_post' => 'Quick Upload',
|
||||
'register' => 'Register',
|
||||
'statistics' => 'Statistics'
|
||||
'statistics' => 'Statistics',
|
||||
'user_settings' => 'Change my settings'
|
||||
]
|
||||
];
|
@ -0,0 +1,17 @@
|
||||
@component('mail::message')
|
||||
@lang('email.generic_intro', ['user_name' => $user->name])
|
||||
|
||||
|
||||
@lang('email.change_email_required_p1', ['app_name' => UserConfig::get('app_name')])
|
||||
|
||||
|
||||
@lang('email.change_email_required_p2')
|
||||
|
||||
@component('mail::button', ['url' => route('userSettings.confirmEmailChangeState'), 'color' => 'blue'])
|
||||
@lang('forms.confirm_email_action')
|
||||
@endcomponent
|
||||
|
||||
@lang('email.generic_regards')<br/>
|
||||
{{ UserConfig::get('app_name') }}<br/>
|
||||
<a href="{{ route('home') }}">{{ route('home') }}</a>
|
||||
@endcomponent
|
103
resources/views/themes/base/gallery/user_settings.blade.php
Normal file
103
resources/views/themes/base/gallery/user_settings.blade.php
Normal file
@ -0,0 +1,103 @@
|
||||
@extends(Theme::viewName('layout'))
|
||||
@section('title', trans('gallery.user_settings.title'))
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 mr-lg-auto ml-lg-auto">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<ul class="nav nav-tabs card-header-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="{{ url('/password/change') }}">@yield('title')</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if ($user->is_email_change_in_progress)
|
||||
<div class="alert alert-warning mb-4" role="alert">
|
||||
<p>@lang('gallery.user_settings.change_email_in_progress', ['new_email_address' => $user->new_email_address])</p>
|
||||
<form action="{{ route('userSettings.resetEmailChangeState') }}" method="post">
|
||||
{{ csrf_field() }}
|
||||
<button type="submit" class="btn btn-outline-info" name="resend_email">@lang('gallery.user_settings.change_email_resend')</button>
|
||||
<button type="submit" class="btn btn-outline-info" name="cancel_change">@lang('gallery.user_settings.cancel_email_change')</button>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('saveUserSettings') }}" method="post">
|
||||
{{ csrf_field() }}
|
||||
|
||||
<div class="form-group row{{ $errors->has('name') ? ' has-danger' : '' }}">
|
||||
<label class="col-md-4 col-form-label text-md-right" for="user-name">@lang('forms.name_label')</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" id="user-name" name="name" value="{{ old('name', $user->name) }}">
|
||||
|
||||
@if ($errors->has('name'))
|
||||
<div class="invalid-feedback">
|
||||
<strong>{{ $errors->first('name') }}</strong>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row{{ $errors->has('email') ? ' has-danger' : '' }}">
|
||||
<label class="col-md-4 col-form-label text-md-right" for="user-email">@lang('forms.email_label')</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" id="user-email" name="email" value="{{ old('email', $user->email) }}"{{ $user->is_email_change_in_progress ? ' readonly="readonly"' : '' }}>
|
||||
|
||||
@if ($errors->has('email'))
|
||||
<div class="invalid-feedback">
|
||||
<strong>{{ $errors->first('email') }}</strong>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<a href="{{ route('auth.changePassword') }}" class="btn btn-link"><i class="fa fa-lock"></i> @lang('gallery.user_settings.change_password')</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<fieldset class="mt-4">
|
||||
<legend class="ml-md-5">Public profile</legend>
|
||||
|
||||
<div class="form-group row{{ $errors->has('profile_alias') ? ' has-danger' : '' }}">
|
||||
<label class="col-md-4 col-form-label text-md-right" for="profile-alias">@lang('forms.profile_alias_label')</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control{{ $errors->has('profile_alias') ? ' is-invalid' : '' }}" id="profile-alias" name="profile_alias" value="{{ old('profile_alias', $user->profile_alias) }}">
|
||||
<small id="emailHelp" class="form-text text-muted">@lang('forms.profile_alias_help')</small>
|
||||
|
||||
@if ($errors->has('profile_alias'))
|
||||
<div class="invalid-feedback">
|
||||
<strong>{{ $errors->first('profile_alias') }}</strong>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="enable-profile-page" name="enable_profile_page"@if (old('enable_profile_page', $user->enable_profile_page)) checked="checked"@endif>
|
||||
<label class="form-check-label" for="enable-profile-page">@lang('forms.enable_profile_page_label')</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="text-right mt-5">
|
||||
<a href="{{ route('home') }}" class="btn btn-link">@lang('forms.cancel_action')</a>
|
||||
<button type="submit" class="btn btn-success"><i class="fa fa-fw fa-check"></i> @lang('forms.save_action')</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
@ -2,9 +2,8 @@
|
||||
@if (UserConfig::isSocialMediaLoginEnabled())
|
||||
<p>@lang('auth.social_login')</p>
|
||||
@include(Theme::viewName('partials.social_login_providers'))
|
||||
<p class="mt-5 mb-4">@lang('auth.email_password_login')</p>
|
||||
@endif
|
||||
|
||||
<p class="mt-5 mb-4">@lang('auth.email_password_login')</p>
|
||||
@else
|
||||
<p>@lang('auth.email_password_login_sso')</p>
|
||||
<p class="mb-5">@lang('auth.email_password_login_sso_2')</p>
|
||||
|
@ -78,8 +78,9 @@
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
@if (UserConfig::get('social_user_profiles') && Auth::user()->enable_profile_page)
|
||||
<a class="dropdown-item" href="{{ Auth::user()->profileUrl() }}">@lang('navigation.navbar.public_profile_page')</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
@endif
|
||||
<a class="dropdown-item" href="{{ route('userSettings') }}">@lang('navigation.navbar.user_settings')</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="{{ route('auth.changePassword') }}">@lang('navigation.navbar.change_password')</a>
|
||||
<a class="dropdown-item" href="{{ url('/logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">@lang('navigation.navbar.logout')</a>
|
||||
<form id="logout-form" action="{{ url('/logout') }}" method="POST" style="display: none;">
|
||||
|
@ -2,9 +2,8 @@
|
||||
@if (UserConfig::isSocialMediaLoginEnabled())
|
||||
<p>@lang('auth.social_register')</p>
|
||||
@include(Theme::viewName('partials.social_login_providers'))
|
||||
<p class="mt-5 mb-4">@lang('auth.email_password_register')</p>
|
||||
@endif
|
||||
|
||||
<p class="mt-5 mb-4">@lang('auth.email_password_register')</p>
|
||||
@else
|
||||
<p class="mb-4">@lang('auth.email_password_register_sso')</p>
|
||||
@endif
|
||||
|
@ -114,6 +114,18 @@ Route::get('i/{albumUrlAlias}/{photoFilename}', 'Gallery\PhotoController@downloa
|
||||
Route::get('label/{labelAlias}', 'Gallery\LabelController@show')
|
||||
->name('viewLabel')
|
||||
->where('labelAlias', '.*');
|
||||
Route::get('user/{idOrAlias}', 'Gallery\UserController@show')
|
||||
Route::get('u/{idOrAlias}', 'Gallery\UserController@show')
|
||||
->name('viewUser')
|
||||
->where('idOrAlias', '.*');
|
||||
->where('idOrAlias', '.*');
|
||||
Route::get('me/confirm-email-change', 'Gallery\UserController@confirmEmailChangeState')
|
||||
->name('userSettings.confirmEmailChangeState')
|
||||
->middleware('auth');
|
||||
Route::post('me/reset-email-change', 'Gallery\UserController@resetEmailChangeState')
|
||||
->name('userSettings.resetEmailChangeState')
|
||||
->middleware('auth');
|
||||
Route::get('me/settings', 'Gallery\UserController@settings')
|
||||
->name('userSettings')
|
||||
->middleware('auth');
|
||||
Route::post('me/save-settings', 'Gallery\UserController@saveSettings')
|
||||
->name('saveUserSettings')
|
||||
->middleware('auth');
|
Loading…
Reference in New Issue
Block a user