<?php
namespace App\Admin;
use App\Entity\User;
use App\Security\Roles;
use DateTime;
use Doctrine\ORM\QueryBuilder;
use Exception;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Validator\Constraints\NotBlank;
class UserAdmin extends AbstractAdmin
{
/** @var UserManagerInterface */
private $userManager;
/** @var TokenGeneratorInterface */
private $tokenGenerator;
/**
* userAdmin constructor.
*
* @param string $code
* @param string $class
* @param string $baseControllerName
* @param UserManagerInterface $userManager
* @param TokenGeneratorInterface $tokenGenerator
*/
public function __construct(
string $code,
string $class,
string $baseControllerName,
UserManagerInterface $userManager,
TokenGeneratorInterface $tokenGenerator
) {
parent::__construct($code, $class, $baseControllerName);
$this->userManager = $userManager;
$this->tokenGenerator = $tokenGenerator;
}
/**
* @param ProxyQueryInterface $query
* @return ProxyQueryInterface
*/
protected function configureQuery(ProxyQueryInterface $query): ProxyQueryInterface
{
/** @var ProxyQueryInterface | QueryBuilder $query */
if (!$this->isSupervisor()) {
$alias = $query->getRootAliases()[0];
$field = sprintf('%s.%s', $alias, 'roles');
$query->andWhere($query->expr()->notLike($field, ':roles'))
->setParameter(':roles', '%'.Roles::ROLE_SUPERVISOR_ADMIN.'%');
}
return $query;
}
/**
* @param ListMapper $listMapper
*
* @return void
*/
protected function configureListFields(ListMapper $listMapper): void
{
$listMapper
->add('email')
->add(
'enabled',
null,
[
'header_style' => 'text-align: center',
'row_align' => 'center',
'editable' => true,
]
)
->add('lastLogin', null, [
'format' => 'Y-m-d',
])
->add(
'_action',
'actions',
[
'actions' => [
'edit' => [],
'delete' => [],
],
]
)
;
}
/**
* @param DatagridMapper $filter
*
* @return void
*/
protected function configureDatagridFilters(DatagridMapper $filter): void
{
$filter
->add('email')
->add('enabled');
}
/**
* @param FormMapper $form
*
* @return void
*/
protected function configureFormFields(FormMapper $form): void
{
$constraints = [];
/** @var User $subject */
$subject = $this->getSubject();
if (!$subject->getId()) {
$constraints[] = new NotBlank();
}
$form->tab('admin.form.section.user.base_settings', [
'label' => 'admin.form.section.user.base_settings'
]);
$form
->with('admin.form.section.user.basic_data', [
'class' => 'col-md-6',
'label' => 'admin.form.section.user.basic_data'
])
->add(
'email',
null,
[
'constraints' => [
new NotBlank(),
],
]
)
->end();
$form->with('admin.form.section.user.password', ['class' => 'col-md-6', 'label' => 'admin.form.section.user.password'])
->add(
'plainPassword',
RepeatedType::class,
[
'type' => PasswordType::class,
'required' => false,
'first_options' => ['label' => 'form.label_new_password'],
'second_options' => ['label' => 'form.label_new_password_confirmation'],
'invalid_message' => 'fos_user.password.mismatch',
'constraints' => $constraints,
]
)
->end();
$form
->with('admin.form.section.user.enabled', ['class' => 'col-md-6 pull-right', 'label' => 'admin.form.section.user.enabled'])
->add('enabled')
->end();
$form->end();
if ($this->isGrantedRole(Roles::ROLE_VINCOTECH_ADMIN)) {
$form->tab('admin.form.section.user.role_settings', ['label' => 'admin.form.section.user.role_settings']);
$form
->with('admin.form.section.user.roles', ['class' => 'col-md-6', 'label' => 'admin.form.section.user.roles'])
->add(
'roles',
ChoiceType::class,
[
'label' => false,
'multiple' => true,
'expanded' => true,
'choices' => Roles::getRolesWithTokenIds($this->isSupervisor()),
]
)
->end();
$form->end();
}
}
/**
* @param User $object
*
* @return void
*
* @throws Exception
*/
public function prePersist($object): void
{
$object
->setPassword('') // settings password by event listener automatically
->setConfirmationToken($this->tokenGenerator->generateToken())
->setPasswordRequestedAt(new DateTime())
->addRole(Roles::ROLE_ADMIN);
}
/**
* @param User $object
*
* @return void
*/
public function preUpdate($object): void
{
$object->addRole(Roles::ROLE_ADMIN);
if ($object->getPlainPassword()) {
$this->userManager->updatePassword($object);
}
}
}