webworld888/app/Http/Controllers/User/UserController.php
2021-10-26 19:14:12 +09:00

572 lines
17 KiB
PHP

<?php
/**
* UserController.php
*
* PHP version 7
*
* @category Controllers
* @package App\Http\Controllers\User
* @author XE Developers <developers@xpressengine.com>
* @copyright 2020 Copyright XEHub Corp. <https://www.xehub.io>
* @license http://www.gnu.org/licenses/lgpl-3.0-standalone.html LGPL
* @link https://xpressengine.io
*/
namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller;
use Auth;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use XeDB;
use XePresenter;
use XeTheme;
use Xpressengine\Support\Exceptions\InvalidArgumentException;
use Xpressengine\Support\Exceptions\InvalidArgumentHttpException;
use Xpressengine\User\Exceptions\CannotDeleteMainEmailOfUserException;
use Xpressengine\User\Exceptions\CannotDeleteUserHavingSuperRatingException;
use Xpressengine\User\Exceptions\DisplayNameAlreadyExistsException;
use Xpressengine\User\Exceptions\InvalidConfirmationCodeException;
use Xpressengine\User\Exceptions\InvalidDisplayNameException;
use Xpressengine\User\Exceptions\InvalidPasswordException;
use Xpressengine\User\Exceptions\PendingEmailAlreadyExistsException;
use Xpressengine\User\Exceptions\PendingEmailNotExistsException;
use Xpressengine\User\HttpUserException;
use Xpressengine\User\Repositories\PendingEmailRepositoryInterface;
use Xpressengine\User\Repositories\UserAccountRepositoryInterface;
use Xpressengine\User\Repositories\UserEmailRepositoryInterface;
use Xpressengine\User\UserHandler;
/**
* Class UserController
*
* @category Controllers
* @package App\Http\Controllers\User
* @author XE Developers <developers@xpressengine.com>
* @copyright 2020 Copyright XEHub Corp. <https://www.xehub.io>
* @license http://www.gnu.org/licenses/lgpl-3.0-standalone.html LGPL
* @link https://xpressengine.io
*/
class UserController extends Controller
{
/**
* @var \Xpressengine\User\Repositories\UserRepositoryInterface
*/
protected $users;
/**
* @var \Xpressengine\User\Repositories\UserGroupRepositoryInterface
*/
protected $groups;
/**
* @var UserEmailRepositoryInterface
*/
protected $emails;
/**
* @var UserHandler
*/
protected $handler;
/**
* @var PendingEmailRepositoryInterface
*/
protected $pendingMails;
/**
* @var UserAccountRepositoryInterface
*/
protected $accounts;
/**
* UserController constructor.
*/
public function __construct()
{
$this->handler = app('xe.user');
$this->users = app('xe.users');
$this->groups = app('xe.user.groups');
$this->emails = app('xe.user.emails');
$this->pendingMails = app('xe.user.pendingEmails');
$this->accounts = app('xe.user.accounts');
XeTheme::selectSiteTheme();
XePresenter::setSkinTargetId('user/settings');
$this->middleware('auth');
}
/**
* Show section for user setting.
*
* @param Request $request request
* @param string $section section
* @return \Xpressengine\Presenter\Presentable
*/
public function show(Request $request, $section = 'settings')
{
// get sections
$menus = $this->handler->getSettingsSections();
// get Selected section
if (isset($menus[$section]) === false) {
throw new NotFoundHttpException();
}
$menus[$section]['selected'] = true;
$selectedSection = $menus[$section];
// get current user
$user = $request->user();
$content = $selectedSection['content'];
$selectedSection['selected'] = true;
$tabContent = $content instanceof \Closure ? $content($user) : $content;
expose_trans('xe::validatorMin');
expose_trans('xe::passwordIncludeNumber');
expose_trans('xe::passwordIncludeCharacter');
expose_trans('xe::passwordIncludeSpecialCharacter');
expose_trans('xe::enterPasswordConfirmation');
return XePresenter::make('index', compact('user', 'menus', 'tabContent'));
}
/**
* Update display name of user.
*
* @param Request $request
* @return \Xpressengine\Presenter\Presentable
* @throws Exception
*/
public function updateDisplayName(Request $request)
{
$displayName = $request->get('name');
$displayName = str_replace(' ', ' ', trim($displayName));
XeDB::beginTransaction();
try {
$this->handler->update($request->user(), ['display_name' => $displayName]);
} catch (\Exception $e) {
XeDB::rollback();
throw $e;
}
XeDB::commit();
return XePresenter::makeApi(
['type' => 'success', 'message' => 'success', 'displayName' => $displayName]
);
}
/**
* Validate display name of user.
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
* @throws Exception
*/
public function validateDisplayName(Request $request)
{
$name = $request->get('name');
$name = trim($name);
$valid = true;
try {
$this->handler->validateDisplayName($name);
$message = xe_trans('xe::usableDisplayName');
} catch (DisplayNameAlreadyExistsException $e) {
$valid = false;
$message = $e->getMessage();
} catch (InvalidDisplayNameException $e) {
$valid = false;
$message = xe_trans('xe::invalidDisplayName');
} catch (\Exception $e) {
throw $e;
}
return XePresenter::makeApi(
['type' => 'success', 'message' => $message, 'displayName' => $name, 'valid' => $valid]
);
}
/**
* Update password of user.
*
* @param Request $request request
* @throws Exception
* @return \Xpressengine\Presenter\Presentable
*/
public function updatePassword(Request $request)
{
$this->validate($request, ['password' => 'required|confirmed|password']);
$result = true;
$message = 'success';
$target = null;
if ($request->user()->getAuthPassword() !== "") {
$credentials = [
'id' => $request->user()->getId(),
'password' => $request->get('current_password')
];
if (Auth::validate($credentials) === false) {
$message = xe_trans('xe::currentPasswordIncorrect');
$target = 'current_password';
$result = false;
}
}
$password = $request->get('password');
XeDB::beginTransaction();
try {
// save password
$this->handler->update($request->user(), compact('password'));
} catch (InvalidPasswordException $e) {
XeDB::rollback();
throw new HttpException(422, $e->getMessage(), $e);
} catch (\Exception $e) {
XeDB::rollback();
throw $e;
}
XeDB::commit();
return XePresenter::makeApi(
['type' => 'success', 'result' => $result, 'message' => $message, 'target' => $target]
);
}
/**
* Validate password of user.
*
* @param Request $request request
* @throws Exception
* @return \Xpressengine\Presenter\Presentable
*/
public function validatePassword(Request $request)
{
try {
$this->validate($request, ['password' => 'password']);
return XePresenter::makeApi(
['type' => 'success', 'message' => 'success', 'valid' => true]
);
} catch (ValidationException $e) {
return XePresenter::makeApi(
['type' => 'success', 'message' => app('xe.password.validator')->getMessage(), 'valid' => false]
);
} catch (\Exception $e) {
throw $e;
}
}
/**
* Update user's main email address.
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
*/
public function updateMainMail(Request $request)
{
$address = $request->get('address');
if ($request->user()->email === $address) {
$e = new InvalidArgumentException();
$e->setMessage(xe_trans('xe::SameAsMainEmail'));
throw $e;
}
$selected = null;
foreach ($request->user()->emails as $mail) {
if ($mail->address === $address) {
$selected = $mail;
break;
}
}
// 해당회원이 가진 이메일이 아닐 경우 예외처리한다.
if ($selected === null) {
$e = new InvalidArgumentException();
$e->setMessage(xe_trans('xe::emailNotFound'));
throw $e;
}
$request->user()->email = $address;
XeDB::beginTransaction();
try {
$this->users->update($request->user());
} catch (\Exception $e) {
XeDB::rollback();
}
XeDB::commit();
return XePresenter::makeApi(['message' => xe_trans('xe::saved')]);
}
/**
* Get emails of current user.
*
* @return \Xpressengine\Presenter\Presentable
*/
public function getMailList()
{
$user = request()->user();
$mails = $user->mails;
if ($mails === null) {
$mails = $this->emails->findByUserId($user->getId());
} else {
$mails = array_values($mails);
}
return XePresenter::makeApi(['mails' => $mails]);
}
/**
* Add email to user.
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
* @throws Exception
*/
public function addMail(Request $request)
{
$input = $request->only('address');
$this->validate($request, ['address' => 'email|required'], [], ['address' => xe_trans('xe::email')]);
// 이미 인증 요청중인 이메일이 있는지 확인한다.
$useEmailConfirm = app('xe.config')->getVal('user.common.guard_forced') === true;
if ($useEmailConfirm) {
if ($request->user()->getPendingEmail() !== null) {
$e = new PendingEmailAlreadyExistsException();
}
}
// 이미 존재하는 이메일이 있는지 확인한다.
$this->handler->validateEmail($input['address']);
XeDB::beginTransaction();
try {
$mail = $this->handler->createEmail($request->user(), $input, !$useEmailConfirm);
if ($useEmailConfirm) {
app('xe.auth.email')->sendEmailForAddingEmail($mail);
}
} catch (\Exception $e) {
XeDB::rollback();
throw $e;
}
XeDB::commit();
return XePresenter::makeApi(['message' => xe_trans('xe::saved')]);
}
/**
* Confirm email by given code.
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
* @throws Exception
*/
public function confirmMail(Request $request)
{
$code = $request->get('code');
$pendingMail = $request->user()->getPendingEmail();
if ($pendingMail === null) {
throw new PendingEmailNotExistsException();
}
XeDB::beginTransaction();
try {
app('xe.auth.email')->confirmEmail($pendingMail, $code);
} catch (InvalidConfirmationCodeException $e) {
$e = new InvalidArgumentHttpException();
$e->setMessage(xe_trans('xe::invalidConfirmationCodeCheckAndRetry'));
throw $e;
} catch (\Exception $e) {
XeDB::rollback();
throw $e;
}
XeDB::commit();
return XePresenter::makeApi(['message' => xe_trans('xe::confirmed')]);
}
/**
* Resend pending email.
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
*/
public function resendPendingMail(Request $request)
{
$pendingMail = $request->user()->getPendingEmail();
if ($pendingMail === null) {
throw new PendingEmailNotExistsException();
}
app('xe.auth.email')->sendEmailForAddingEmail($pendingMail);
return XePresenter::makeApi(['message' => xe_trans('xe::resended')]);
}
/**
* Delete a email.
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
* @throws Exception
*/
public function deleteMail(Request $request)
{
$address = $request->get('address');
// 해당회원이 가진 이메일을 찾는다.
$selected = null;
$pendingEmail = $request->user()->getPendingEmail();
if ($pendingEmail !== null && $pendingEmail->getAddress() === $address) {
$selected = $pendingEmail;
} else {
foreach ($request->user()->emails as $mail) {
if ($mail->address === $address) {
$selected = $mail;
break;
}
}
}
// 해당회원이 가진 이메일이 아닐 경우 예외처리한다.
if ($selected === null) {
$e = new InvalidArgumentException();
$e->setMessage(xe_trans('xe::emailNotFound'));
throw $e;
}
XeDB::beginTransaction();
try {
$this->handler->deleteEmail($selected);
} catch (CannotDeleteMainEmailOfUserException $e) {
XeDB::rollback();
$e = new HttpUserException([], 400, $e);
$e->setMessage('xe::cannotDeleteMainEmailOfUser');
throw $e;
} catch (\Exception $e) {
XeDB::rollback();
throw $e;
}
XeDB::commit();
return XePresenter::makeApi(['message' => xe_trans('xe::deleted')]);
}
/**
* Delete user's pending email
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
* @throws Exception
*/
public function deletePendingMail(Request $request)
{
return $this->deleteMail($request);
}
/**
* Leave the application.
*
* @param Request $request request
* @return \Illuminate\Http\RedirectResponse
* @throws Exception
*/
public function leave(Request $request)
{
$confirm = $request->get('confirm_leave');
if ($confirm !== 'Y') {
$e = new InvalidArgumentException();
$e->setMessage(xe_trans('xe::AgreementIsRequired'));
throw $e;
}
$id = $request->user()->getId();
XeDB::beginTransaction();
try {
$this->handler->leave($id);
} catch (CannotDeleteUserHavingSuperRatingException $e) {
XeDB::rollback();
$e = new HttpUserException([], 400, $e);
$e->setMessage('xe::cannotLeaveHaveSuperRatingUser');
throw $e;
} catch (\Exception $e) {
XeDB::rollback();
throw $e;
}
XeDB::commit();
Auth::logout();
return redirect()->to('/');
}
/**
* Show additional field for user.
*
* @param string $field field id
* @return \Xpressengine\Presenter\Presentable
*/
public function showAdditionField($field)
{
$dynamicField = app('xe.dynamicField');
$fieldType = $dynamicField->get('user', $field);
$user = request()->user();
$id = $field;
return api_render('show-field', compact('user', 'fieldType', 'id'), compact('id'));
}
/**
* Show edit form for additional field for user.
*
* @param string $field field id
* @return \Xpressengine\Presenter\Presentable
*/
public function editAdditionField($field)
{
$dynamicField = app('xe.dynamicField');
$fieldType = $dynamicField->get('user', $field);
$user = request()->user();
$id = $field;
return api_render('edit-field', compact('user', 'fieldType', 'id'), ['id' => $id]);
}
/**
* Update additional field for user.
*
* @param Request $request request
* @param string $field field id
* @return \Xpressengine\Presenter\Presentable
*/
public function updateAdditionField(Request $request, $field)
{
$inputs = $request->except('_token');
$this->handler->update($request->user(), $inputs);
$showUrl = route('user.settings.additions.show', ['field' => $field]);
return XePresenter::makeApi(
['type' => 'success', 'message' => 'success', 'field' => $field, 'showUrl' => $showUrl]
);
}
}