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

573 lines
16 KiB
PHP

<?php
/**
* UserController.php
*
* PHP version 7
*
* @category Controllers
* @package App\Http\Controllers\User\Settings
* @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\Settings;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Symfony\Component\HttpKernel\Exception\HttpException;
use XeDB;
use XePresenter;
use Xpressengine\Http\Request;
use Xpressengine\Support\Exceptions\InvalidArgumentHttpException;
use Xpressengine\User\Exceptions\EmailAlreadyExistsException;
use Xpressengine\User\Exceptions\EmailNotFoundException;
use Xpressengine\User\Models\User;
use Xpressengine\User\Rating;
use Xpressengine\User\Repositories\UserRepository;
use Xpressengine\User\UserException;
use Xpressengine\User\UserHandler;
use Xpressengine\User\UserInterface;
/**
* Class UserController
*
* @category Controllers
* @package App\Http\Controllers\User\Settings
* @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 UserHandler
*/
protected $handler;
/**
* UserController constructor.
*
* @param UserHandler $handler user handler
*/
public function __construct(UserHandler $handler)
{
$this->handler = $handler;
}
/**
* Show user list
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
*/
public function index(Request $request)
{
$query = $this->handler->users()->query();
$allUserCount = $query->count();
if ($startDate = $request->get('startDate')) {
$query = $query->where('created_at', '>=', $startDate . ' 00:00:00');
}
if ($endDate = $request->get('endDate')) {
$query = $query->where('created_at', '<=', $endDate . ' 23:59:59');
}
// resolve group
if ($group = $request->get('group')) {
$query = $query->whereHas(
'groups',
function (Builder $q) use ($group) {
$q->where('group_id', $group);
}
);
}
// resolve status
if ($status = $request->get('status')) {
$query = $query->where('status', $status);
}
// resolve rating
if ($rating = $request->get('rating')) {
$query = $query->where('rating', $rating);
}
// resolve search keyword
// keyfield가 지정되지 않을 경우 email, display_name, login_id를 대상으로 검색함
$field = $request->get('keyfield') ?: 'email,display_name,login_id';
if ($keyword = trim($request->get('keyword'))) {
$query = $query->where(
function (Builder $q) use ($field, $keyword) {
foreach (explode(',', $field) as $f) {
$q->orWhere($f, 'like', '%'.$keyword.'%');
}
}
);
}
$users = $query->orderBy('created_at', 'desc')->paginate()->appends(request()->query());
// get all groups
$groups = $this->handler->groups()->all();
// get all ratings
$ratings = Rating::getUsableAll();
$ratingNames = [
Rating::USER => xe_trans('xe::userRatingNormal'),
Rating::MANAGER => xe_trans('xe::userRatingManager'),
Rating::SUPER => xe_trans('xe::userRatingAdministrator'),
];
foreach ($ratings as $key => $rating) {
$ratings[$key] = [
'value' => $rating,
'text' => $ratingNames[$rating],
];
}
$selectedGroup = null;
if ($group !== null) {
$selectedGroup = $this->handler->groups()->find($group);
}
$config = app('xe.config')->get('user.register');
return XePresenter::make(
'user.settings.user.index',
compact('users', 'groups', 'selectedGroup', 'allUserCount', 'ratings', 'config')
);
}
/**
* Show user creation page.
*
* @return \Xpressengine\Presenter\Presentable
*/
public function create()
{
$ratings = Rating::getUsableAll();
$ratingNames = [
Rating::USER => xe_trans('xe::userRatingNormal'),
Rating::MANAGER => xe_trans('xe::userRatingManager'),
Rating::SUPER => xe_trans('xe::userRatingAdministrator'),
];
foreach ($ratings as $key => $rating) {
$ratings[$key] = [
'value' => $rating,
'text' => $ratingNames[$rating],
];
}
$groupList = $this->handler->groups()->all();
$groups = $this->getGroupInfo($groupList);
$status = $this->getUserStatus();
// dynamic field
$dynamicField = app('xe.dynamicField');
$fieldTypes = $dynamicField->gets('user');
return XePresenter::make('user.settings.user.create', compact('ratings', 'groups', 'status', 'fieldTypes'));
}
/**
* Store user.
*
* @param Request $request request
* @return \Illuminate\Http\RedirectResponse
* @throws Exception
*/
public function store(Request $request)
{
$rules = [
'email' => 'email|required',
'login_id' => 'required|login_id',
'password' => 'required|password',
];
if (app('xe.config')->getVal('user.register.use_display_name') === true) {
$rules['display_name'] = 'required';
}
$this->validate($request, $rules);
$userData = $request->except('_token');
$userData['emailConfirmed'] = 1;
XeDB::beginTransaction();
try {
$this->handler->create($userData);
} catch (\Exception $e) {
XeDB::rollback();
throw $e;
}
XeDB::commit();
return redirect()->route('settings.user.index')->with(
'alert',
['type' => 'success', 'message' => xe_trans('xe::saved')]
);
}
/**
* Show user editing page.
*
* @param string $id identifier
* @return \Xpressengine\Presenter\Presentable
*/
public function edit($id)
{
$user = $this->handler->users()->with('groups', 'emails', 'accounts')->find($id);
if ($user === null) {
$e = new InvalidArgumentHttpException();
$e->setMessage(xe_trans('xe::userNotFound'));
throw $e;
}
$ratings = Rating::getUsableAll();
$ratingNames = [
Rating::USER => xe_trans('xe::userRatingNormal'),
Rating::MANAGER => xe_trans('xe::userRatingManager'),
Rating::SUPER => xe_trans('xe::userRatingAdministrator'),
];
foreach ($ratings as $key => $rating) {
$ratings[$key] = [
'value' => $rating,
'text' => $ratingNames[$rating],
];
if ($rating === $user->rating) {
$ratings[$key]['selected'] = 'selected';
}
}
$groupList = $this->handler->groups()->all();
$groups = $this->getGroupInfo($groupList);
foreach ($user->groups as $group) {
$groups[$group->id]['checked'] = 'checked';
}
$status = $this->getUserStatus();
$status[$user->status]['selected'] = 'selected';
// profileImage config
$profileImgSize = config('xe.user.profileImage.size');
// dynamic field
$dynamicField = app('xe.dynamicField');
$fieldTypes = $dynamicField->gets('user');
return XePresenter::make(
'user.settings.user.edit',
compact(
'user',
'ratings',
'groups',
'status',
'fieldTypes',
'profileImgSize'
)
);
}
/**
* Update user.
*
* @param Request $request request
* @param string $id user id
* @return \Illuminate\Http\RedirectResponse
* @throws Exception
*/
public function update(Request $request, $id)
{
/** @var UserInterface $user */
$user = $this->handler->users()->with('groups', 'emails', 'accounts')->find($id);
if ($user === null) {
$e = new InvalidArgumentHttpException();
$e->setMessage(xe_trans('xe::userNotFound'));
throw $e;
}
$rules = [
'email' => 'email',
'login_id' => 'required|login_id',
'rating' => 'required',
'status' => 'required',
];
if (app('xe.config')->getVal('user.register.use_display_name') === true) {
$rules['display_name'] = 'required';
}
$this->validate($request, $rules);
if ($user->isAdmin() &&
($request->get('status') === User::STATUS_DENIED || $request->get('rating') !== Rating::SUPER)
) {
$cnt = $this->handler->users()
->where('rating', Rating::SUPER)
->where('status', User::STATUS_ACTIVATED)
->count();
if ($cnt === 1) {
throw new HttpException(422, xe_trans('xe::msgUnableToChangeStatusForSuperUser'));
}
}
$userData = $request->except('_token');
if (array_get($userData, 'profile_img_file') === '__delete_file__') {
$userData['profile_img_file'] = false;
}
$userData['group_id'] = $request->get('group_id') ?: [];
XeDB::beginTransaction();
try {
$this->handler->update($user, $userData);
} catch (UserException $e) {
XeDB::rollback();
throw new HttpException('400', $e->getMessage());
} catch (\Exception $e) {
XeDB::rollback();
throw $e;
}
XeDB::commit();
return redirect()->back()->with('alert', ['type' => 'success', 'message' => xe_trans('xe::saved')]);
}
/**
* get user status list
*
* @return array
*/
protected function getUserStatus()
{
return [
User::STATUS_ACTIVATED => ['value' => User::STATUS_ACTIVATED, 'text' => xe_trans('xe::permitted')],
User::STATUS_DENIED => ['value' => User::STATUS_DENIED, 'text' => xe_trans('xe::rejected')],
User::STATUS_PENDING_ADMIN => [
'value' => User::STATUS_PENDING_ADMIN,
'text' => xe_trans('xe::pending_admin')
],
User::STATUS_PENDING_EMAIL => [
'value' => User::STATUS_PENDING_EMAIL,
'text' => xe_trans('xe::pending_email')
]
];
}
/**
* Response user's email list.
*
* @return \Xpressengine\Presenter\Presentable
*/
public function getMailList(Request $request)
{
$this->validate($request, ['userId' => 'required']);
$id = $request->get('userId');
$mails = $this->handler->emails()->where(['user_id' => $id])->get();
return XePresenter::makeApi(['mails' => $mails]);
}
/**
* Add email.
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
* @throws Exception
*/
public function postAddMail(Request $request)
{
$this->validate($request, [
'userId' => 'required',
'address' => 'required|email'
]);
$userId = $request->get('userId');
$address = $request->get('address');
try {
$this->handler->validateEmail($address);
} catch (EmailAlreadyExistsException $e) {
throw new HttpException(400, xe_trans('xe::emailAlreadyExists'), $e);
}
$user = $this->handler->users()->find($userId);
XeDB::beginTransaction();
try {
$data = [
'user_id' => $user->id,
'address' => $address,
];
$email = $this->handler->createEmail($user, $data);
} catch (Exception $e) {
XeDB::rollBack();
throw $e;
}
XeDB::commit();
return XePresenter::makeApi(['mail' => $email]);
}
/**
* Confirm email
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
* @throws Exception
*/
public function postConfirmMail(Request $request)
{
$pendingEmail = $this->handler->pendingEmails()->find($request->get('id'));
if ($pendingEmail === null) {
$e = new InvalidArgumentHttpException();
$e->setMessage(xe_trans('xe::EmailNotExistOrAlreadyConfirmed'));
throw $e;
}
$user = $pendingEmail->user;
$address = $pendingEmail->address;
XeDB::beginTransaction();
try {
// create email
$email = $this->handler->createEmail($user, compact('address'));
// remove pending email
$this->handler->deleteEmail($pendingEmail);
} catch (Exception $e) {
XeDB::rollBack();
throw $e;
}
XeDB::commit();
return XePresenter::makeApi(['mail' => $email]);
}
/**
* Delete a mail.
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
* @throws Exception
*/
public function postDeleteMail(Request $request)
{
$this->validate($request, [
'userId' => 'required',
'address' => 'required'
]);
$address = $request->get('address');
$mail = $this->handler->emails()->findByAddress($address);
if ($mail === null) {
throw new EmailNotFoundException();
}
XeDB::beginTransaction();
try {
$this->handler->deleteEmail($mail);
} catch (Exception $e) {
XeDB::rollBack();
throw $e;
}
XeDB::commit();
return XePresenter::makeApi(['type' => 'success', 'address' => $address]);
}
/**
* Show confirm for delete a user.
*
* @param Request $request request
* @return \Xpressengine\Presenter\Presentable
*/
public function deletePage(Request $request)
{
$userIds = $request->get('userIds');
$userIds = explode(',', $userIds);
$users = $this->handler->users()->whereIn('id', $userIds)->where('rating', '<>', Rating::SUPER)->get();
return api_render('user.settings.user.delete', compact('users'));
}
/**
* Delete a user.
*
* @param Request $request request
* @return \Illuminate\Http\RedirectResponse
* @throws Exception
*/
public function destroy(Request $request)
{
$userIds = $request->get('userId', []);
XeDB::beginTransaction();
try {
$this->handler->leave($userIds);
} catch (Exception $e) {
XeDB::rollBack();
throw $e;
}
XeDB::commit();
return redirect()->back()->with('alert', ['type' => 'success', 'message' => xe_trans('xe::deleted')]);
}
/**
* Search user.
*
* @param string|null $keyword keyword
* @return \Xpressengine\Presenter\Presentable
*/
public function search($keyword = null)
{
/** @var UserRepository $users */
$users = $this->handler->users();
if ($keyword === null) {
return XePresenter::makeApi([]);
}
$matchedUserList = $users->query()->where('display_name', 'like', '%'.$keyword.'%')
->paginate(null, ['id', 'display_name', 'email'])->items();
return XePresenter::makeApi($matchedUserList);
}
/**
* Get group information
*
* @param \Xpressengine\User\Models\UserGroup[] $groupList groups
* @return array
*/
protected function getGroupInfo($groupList)
{
$groups = [];
foreach ($groupList as $key => $group) {
$groups[$group->id] = [
'value' => $group->id,
'text' => $group->name,
];
}
return $groups;
}
}