extends User entity + alter admin (WIP)

This commit is contained in:
Julien Fastré 2021-09-03 17:28:03 +02:00
parent 960bac8c37
commit 9b38e486df
10 changed files with 413 additions and 42 deletions

View File

@ -19,6 +19,8 @@
namespace Chill\MainBundle\DependencyInjection; namespace Chill\MainBundle\DependencyInjection;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Form\UserJobType;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\HttpKernel\DependencyInjection\Extension;
@ -264,6 +266,27 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
protected function prependCruds(ContainerBuilder $container) protected function prependCruds(ContainerBuilder $container)
{ {
$container->prependExtensionConfig('chill_main', [ $container->prependExtensionConfig('chill_main', [
'cruds' => [
[
'class' => UserJob::class,
'name' => 'admin_user_job',
'base_path' => '/admin/main/user-job',
'base_role' => 'ROLE_ADMIN',
'form_class' => UserJobType::class,
'actions' => [
'index' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillMain/UserJob/index.html.twig',
],
'new' => [
'role' => 'ROLE_ADMIN'
],
'edit' => [
'role' => 'ROLE_ADMIN'
]
],
],
],
'apis' => [ 'apis' => [
[ [
'class' => \Chill\MainBundle\Entity\Address::class, 'class' => \Chill\MainBundle\Entity\Address::class,

View File

@ -5,6 +5,7 @@ namespace Chill\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Chill\MainBundle\Entity\UserJob;
use Symfony\Component\Security\Core\User\AdvancedUserInterface; use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap; use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
@ -47,6 +48,11 @@ class User implements AdvancedUserInterface {
*/ */
private $usernameCanonical; private $usernameCanonical;
/**
* @ORM\Column(type="string", length=200)
*/
private string $label = '';
/** /**
* @var string * @var string
* *
@ -113,6 +119,24 @@ class User implements AdvancedUserInterface {
*/ */
private $attributes; private $attributes;
/**
* @var Center|null
* @ORM\ManyToOne(targetEntity=Center::class)
*/
private ?Center $mainCenter = null;
/**
* @var Scope|null
* @ORM\ManyToOne(targetEntity=Scope::class)
*/
private ?Scope $mainScope = null;
/**
* @var UserJob|null
* @ORM\ManyToOne(targetEntity=UserJob::class)
*/
private ?UserJob $userJob = null;
/** /**
* User constructor. * User constructor.
*/ */
@ -126,7 +150,7 @@ class User implements AdvancedUserInterface {
*/ */
public function __toString() public function __toString()
{ {
return $this->getUsername(); return $this->getLabel();
} }
/** /**
@ -149,6 +173,10 @@ class User implements AdvancedUserInterface {
{ {
$this->username = $name; $this->username = $name;
if (empty($this->getLabel())) {
$this->setLabel($name);
}
return $this; return $this;
} }
@ -384,4 +412,76 @@ class User implements AdvancedUserInterface {
return $this->attributes; return $this->attributes;
} }
/**
* @return string
*/
public function getLabel(): string
{
return $this->label;
}
/**
* @param string $label
* @return User
*/
public function setLabel(string $label): User
{
$this->label = $label;
return $this;
}
/**
* @return Center|null
*/
public function getMainCenter(): ?Center
{
return $this->mainCenter;
}
/**
* @param Center|null $mainCenter
* @return User
*/
public function setMainCenter(?Center $mainCenter): User
{
$this->mainCenter = $mainCenter;
return $this;
}
/**
* @return Scope|null
*/
public function getMainScope(): ?Scope
{
return $this->mainScope;
}
/**
* @param Scope|null $mainScope
* @return User
*/
public function setMainScope(?Scope $mainScope): User
{
$this->mainScope = $mainScope;
return $this;
}
/**
* @return UserJob|null
*/
public function getUserJob(): ?UserJob
{
return $this->userJob;
}
/**
* @param UserJob|null $userJob
* @return User
*/
public function setUserJob(?UserJob $userJob): User
{
$this->userJob = $userJob;
return $this;
}
} }

View File

@ -0,0 +1,76 @@
<?php
namespace Chill\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table("chill_main_user_job")
*/
class UserJob
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected ?int $id = null;
/**
* @var array|string[]A
* @ORM\Column(name="label", type="json")
*/
protected array $label = [];
/**
* @var bool
* @ORM\Column(name="active", type="boolean")
*/
protected bool $active = true;
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* @return array|string[]
*/
public function getLabel(): array
{
return $this->label;
}
/**
* @param array|string[] $label
* @return UserJob
*/
public function setLabel(array $label): UserJob
{
$this->label = $label;
return $this;
}
/**
* @return bool
*/
public function isActive(): bool
{
return $this->active;
}
/**
* @param bool $active
* @return UserJob
*/
public function setActive(bool $active): UserJob
{
$this->active = $active;
return $this;
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Chill\MainBundle\Form;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
class UserJobType extends \Symfony\Component\Form\AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('label', TranslatableStringFormType::class, [
'label' => 'Label',
'required' => true
])
->add('active', ChoiceType::class, [
'choices' => [
'Active' => true,
'Inactive' => false
]
])
;
}
}

View File

@ -2,7 +2,15 @@
namespace Chill\MainBundle\Form; namespace Chill\MainBundle\Form;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@ -16,6 +24,16 @@ use Chill\MainBundle\Form\UserPasswordType;
class UserType extends AbstractType class UserType extends AbstractType
{ {
private TranslatableStringHelper $translatableStringHelper;
/**
* @param TranslatableStringHelper $translatableStringHelper
*/
public function __construct(TranslatableStringHelper $translatableStringHelper)
{
$this->translatableStringHelper = $translatableStringHelper;
}
/** /**
* @param FormBuilderInterface $builder * @param FormBuilderInterface $builder
* @param array $options * @param array $options
@ -24,7 +42,40 @@ class UserType extends AbstractType
{ {
$builder $builder
->add('username') ->add('username')
->add('email') ->add('email', EmailType::class, [
'required' => true
])
->add('label', TextType::class)
->add('mainCenter', EntityType::class, [
'label' => 'main center',
'required' => false,
'placeholder' => 'choose a main center',
'class' => Center::class,
'query_builder' => function (EntityRepository $er) {
$qb = $er->createQueryBuilder('c');
$qb->addOrderBy('c.name');
return $qb;
}
])
->add('mainScope', EntityType::class, [
'label' => 'Choose a main scope',
'required' => false,
'placeholder' => 'choose a main scope',
'class' => Scope::class,
'choice_label' => function (Scope $c) {
return $this->translatableStringHelper->localize($c->getName());
},
])
->add('userJob', EntityType::class, [
'label' => 'Choose a job',
'required' => false,
'placeholder' => 'choose a job',
'class' => UserJob::class,
'choice_label' => function (UserJob $c) {
return $this->translatableStringHelper->localize($c->getLabel());
},
])
; ;
if ($options['is_creation']) { if ($options['is_creation']) {
$builder->add('plainPassword', RepeatedType::class, array( $builder->add('plainPassword', RepeatedType::class, array(

View File

@ -0,0 +1,8 @@
{% extends '@ChillMain/Admin/layout.html.twig' %}
{% block title %}{{ ('crud.' ~ crud_name ~ '.index.title')|trans({'%crud_name%': crud_name}) }}{% endblock %}
{% block content %}
{% embed '@ChillMain/CRUD/_index.html.twig' %}
{% endembed %}
{% endblock content %}

View File

@ -0,0 +1,26 @@
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
{% block content %}
{% embed '@ChillMain/CRUD/_index.html.twig' %}
{% block table_entities_thead_tr %}
<th>id</th>
<th>label</th>
<th>&nbsp;</th>
{% endblock %}
{% block table_entities_tbody %}
{% for entity in entities %}
<tr>
<td>{{ entity.id }}</td>
<td>{{ entity.label|localize_translatable_string }}</td>
<td>
<ul class="record_actions">
<li>
<a href="{{ chill_path_add_return_path('chill_crud_admin_user_job_edit', { 'id': entity.id}) }}" class="btn btn-sm btn-edit btn-mini"></a>
</li>
</ul>
</td>
</tr>
{% endfor %}
{% endblock %}
{% endembed %}
{% endblock content %}

View File

@ -113,6 +113,10 @@ services:
tags: tags:
- { name: form.type } - { name: form.type }
Chill\MainBundle\Form\UserType:
autowire: true
autoconfigure: true
Chill\MainBundle\Form\PermissionsGroupType: Chill\MainBundle\Form\PermissionsGroupType:
tags: tags:
- { name: form.type } - { name: form.type }
@ -123,3 +127,4 @@ services:
- "@security.token_storage" - "@security.token_storage"
tags: tags:
- { name: form.type } - { name: form.type }

View File

@ -18,6 +18,8 @@ Chill\MainBundle\Entity\User:
min: 3 min: 3
email: email:
- Email: ~ - Email: ~
label:
- NotBlank: ~
constraints: constraints:
- Callback: - Callback:
callback: isGroupCenterPresentOnce callback: isGroupCenterPresentOnce

View File

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace Chill\Migrations\Main;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add metadata on users
*/
final class Version20210903144853 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add metadata on users';
}
public function up(Schema $schema): void
{
$this->addSql('CREATE SEQUENCE chill_main_user_job_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE chill_main_user_job (id INT NOT NULL, label JSON NOT NULL, active BOOLEAN NOT NULL, PRIMARY KEY(id))');
$this->addSql('ALTER TABLE users ADD label VARCHAR(200) NULL DEFAULT NULL');
$this->addSql('UPDATE users SET label=username');
$this->addSql('ALTER TABLE users ALTER label DROP DEFAULT');
$this->addSql('ALTER TABLE users ALTER label SET NOT NULL');
$this->addSql('ALTER TABLE users ADD mainCenter_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE users ADD mainScope_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE users ADD userJob_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE users ALTER usernamecanonical SET NOT NULL');
$this->addSql('ALTER TABLE users ADD CONSTRAINT FK_1483A5E92C2125C1 FOREIGN KEY (mainCenter_id) REFERENCES centers (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE users ADD CONSTRAINT FK_1483A5E9115E73F3 FOREIGN KEY (mainScope_id) REFERENCES scopes (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE users ADD CONSTRAINT FK_1483A5E964B65C5B FOREIGN KEY (userJob_id) REFERENCES chill_main_user_job (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_1483A5E92C2125C1 ON users (mainCenter_id)');
$this->addSql('CREATE INDEX IDX_1483A5E9115E73F3 ON users (mainScope_id)');
$this->addSql('CREATE INDEX IDX_1483A5E964B65C5B ON users (userJob_id)');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE users DROP CONSTRAINT FK_1483A5E964B65C5B');
$this->addSql('DROP SEQUENCE chill_main_user_job_id_seq CASCADE');
$this->addSql('DROP TABLE chill_main_user_job');
$this->addSql('ALTER TABLE users DROP CONSTRAINT FK_1483A5E92C2125C1');
$this->addSql('ALTER TABLE users DROP CONSTRAINT FK_1483A5E9115E73F3');
$this->addSql('ALTER TABLE users DROP label');
$this->addSql('ALTER TABLE users DROP mainCenter_id');
$this->addSql('ALTER TABLE users DROP mainScope_id');
$this->addSql('ALTER TABLE users DROP userJob_id');
$this->addSql('ALTER TABLE users ALTER usernameCanonical DROP NOT NULL');
}
}