Merge branch 'master' into 292_activity_acl

This commit is contained in:
2021-12-13 09:21:32 +01:00
80 changed files with 2202 additions and 927 deletions

View File

@@ -26,8 +26,8 @@ class LoadCivility extends Fixture implements FixtureGroupInterface
public function load(ObjectManager $manager): void
{
$civilities = [
['name' => ['fr' => 'Monsieur'], 'abbrev' => ['fr' => 'M.']],
['name' => ['fr' => 'Madame'], 'abbrev' => ['fr' => 'Mme']],
['name' => ['fr' => 'Monsieur'], 'abbrev' => ['fr' => 'M.']],
['name' => ['fr' => 'Docteur'], 'abbrev' => ['fr' => 'Dr']],
['name' => ['fr' => 'Professeur'], 'abbrev' => ['fr' => 'Pr']],
['name' => ['fr' => 'Madame la Directrice'], 'abbrev' => ['fr' => 'Mme']],

View File

@@ -38,8 +38,9 @@ class Center implements HasCenterInterface
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @Serializer\Groups({"docgen:read"})
*/
private $id;
private ?int $id = null;
/**
* @ORM\Column(type="string", length=255)

View File

@@ -22,7 +22,8 @@ class Civility
{
/**
* @ORM\Column(type="json")
* @Serializer\Groups({"read"})
* @Serializer\Groups({"read", "docgen:read"})
* @Serializer\Context({"is-translatable": true}, groups={"docgen:read"})
*/
private array $abbreviation = [];
@@ -35,13 +36,14 @@ class Civility
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Serializer\Groups({"read"})
* @Serializer\Groups({"read", "docgen:read"})
*/
private $id;
private ?int $id = null;
/**
* @ORM\Column(type="json")
* @Serializer\Groups({"read"})
* @Serializer\Groups({"read", "docgen:read"})
* @Serializer\Context({"is-translatable": true}, groups={"docgen:read"})
*/
private array $name = [];

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Context;
use Symfony\Component\Serializer\Annotation\Groups;
/**
@@ -25,12 +26,11 @@ use Symfony\Component\Serializer\Annotation\Groups;
class Country
{
/**
* @var string
*
* @ORM\Column(type="string", length=3)
* @groups({"read"})
* @groups({"read", "docgen:read"})
* @Context({"is-translatable": true}, groups={"docgen:read"})
*/
private $countryCode;
private string $countryCode = '';
/**
* @var int
@@ -38,15 +38,16 @@ class Country
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @groups({"read"})
* @groups({"read", "docgen:read"})
*/
private $id;
private ?int $id = null;
/**
* @var string
*
* @ORM\Column(type="json")
* @groups({"read"})
* @groups({"read", "docgen:read"})
* @Context({"is-translatable": true}, groups={"docgen:read"})
*/
private $name;

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
/**
* Language.
@@ -28,15 +29,18 @@ class Language
*
* @ORM\Id
* @ORM\Column(type="string")
* @Serializer\Groups({"docgen:read"})
*/
private $id;
private ?string $id = null;
/**
* @var string array
*
* @ORM\Column(type="json")
* @Serializer\Groups({"docgen:read"})
* @Serializer\Context({"is-translatable": true}, groups={"docgen:read"})
*/
private $name;
private array $name = [];
/**
* Get id.

View File

@@ -14,6 +14,7 @@ namespace Chill\MainBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Context;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation\Groups;
@@ -28,24 +29,21 @@ use Symfony\Component\Serializer\Annotation\Groups;
class Scope
{
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @Groups({"read", "docgen:read"})
*/
private $id;
private ?int $id = null;
/**
* translatable names.
*
* @var array
*
* @ORM\Column(type="json")
* @Groups({"read", "docgen:read"})
* @Context({"is-translatable": true}, groups={"docgen:read"})
*/
private $name = [];
private array $name = [];
/**
* @var Collection
@@ -65,31 +63,27 @@ class Scope
$this->roleScopes = new ArrayCollection();
}
public function addRoleScope(RoleScope $roleScope)
public function addRoleScope(RoleScope $roleScope): self
{
$this->roleScopes->add($roleScope);
return $this;
}
/**
* @return int
*/
public function getId()
public function getId(): ?int
{
return $this->id;
}
/**
* @return array
*/
public function getName()
public function getName(): array
{
return $this->name;
}
/**
* @return Collection
*/
public function getRoleScopes()
public function getRoleScopes(): Collection
{
return $this->roleScopes;
}
@@ -99,7 +93,7 @@ class Scope
*
* @return $this
*/
public function setName($name)
public function setName(array $name): self
{
$this->name = $name;

View File

@@ -55,7 +55,6 @@ class User implements AdvancedUserInterface
* @var string
*
* @ORM\Column(type="string", length=150, nullable=true)
* @Serializer\Groups({"docgen:read"})
*/
private ?string $email = null;
@@ -83,7 +82,6 @@ class User implements AdvancedUserInterface
/**
* @ORM\Column(type="string", length=200)
* @Serializer\Groups({"docgen:read"})
*/
private string $label = '';
@@ -95,7 +93,6 @@ class User implements AdvancedUserInterface
/**
* @ORM\ManyToOne(targetEntity=Center::class)
* @Serializer\Groups({"docgen:read"})
*/
private ?Center $mainCenter = null;
@@ -189,7 +186,7 @@ class User implements AdvancedUserInterface
/**
* @return string
*/
public function getEmail()
public function getEmail(): ?string
{
return $this->email;
}

View File

@@ -32,14 +32,14 @@ class UserJob
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @Serializer\Groups({"read"})
* @Serializer\Groups({"read", "docgen:read"})
*/
protected ?int $id = null;
/**
* @var array|string[]A
* @ORM\Column(name="label", type="json")
* @Serializer\Groups({"read"})
* @Serializer\Groups({"read", "docgen:read"})
*/
protected array $label = [];

View File

@@ -80,7 +80,7 @@ class ScopePickerType extends AbstractType
{
$items = $this->authorizationHelper->getReachableScopes(
$this->security->getUser(),
$options['role'],
$options['role']->getRole(),
$options['center']
);

View File

@@ -81,7 +81,7 @@ class UserPickerType extends AbstractType
->setAllowedTypes('scope', [Scope::class, 'array', 'null'])
->setNormalizer('choices', function (Options $options) {
$users = $this->userACLAwareRepository
->findUsersByReachedACL($options['role'], $options['center'], $options['scope'], true);
->findUsersByReachedACL($options['role']->getRole(), $options['center'], $options['scope'], true);
if (null !== $options['having_permissions_group_flag']) {
return $this->userRepository

View File

@@ -260,7 +260,7 @@ class PhonenumberHelper
return null;
}
$validation = json_decode($response->getBody())->carrier->type;
$validation = json_decode($response->getBody()->getContents())->carrier->type;
$item
->set($validation)

View File

@@ -12,13 +12,11 @@
* extended_infos bool add extra informations (step, floor, etc.)
#}
{% macro raw(address, options) %}
{% macro raw(address, options, streetLine) %}
{% if address.street is not empty %}
<p class="street">{{ address.street }}
{% if address.streetNumber is not empty %}
<span class="streetnumber">{{ address.streetNumber }}</span>
{% endif %}
</p>
<p>{{ streetLine }}</p>
{% endif %}
{% if options['extended_infos'] %}
{{ _self.extended(address, options) }}
@@ -56,7 +54,7 @@
{% endif %}
{% endmacro %}
{% macro inline(address, options) %}
{% macro inline(address, options, streetLine) %}
{% if options['has_no_address'] == true and address.isNoAddress == true %}
{% if address.postCode is not empty %}
<p class="postcode">
@@ -70,7 +68,7 @@
</span>
{% else %}
<span class="address{% if options['multiline'] %} multiline{% endif %}{% if options['with_delimiter'] %} delimiter{% endif %}">
{{ _self.raw(address, options) }}
{{ _self.raw(address, options, streetLine) }}
</span>
{% endif %}
{{ _self.validity(address, options) }}
@@ -99,7 +97,7 @@
{% if options['with_picto'] %}
<i class="fa fa-li fa-map-marker"></i>
{% endif %}
{{ _self.inline(address, options) }}
{{ _self.inline(address, options, streetLine) }}
</li>
{%- endif -%}
@@ -108,7 +106,7 @@
{% if options['with_picto'] %}
<i class="fa fa-fw fa-map-marker"></i>
{% endif %}
{{ _self.inline(address, options) }}
{{ _self.inline(address, options, streetLine) }}
</span>
{%- endif -%}
@@ -133,7 +131,7 @@
{% if options['with_picto'] %}
<i class="fa fa-fw fa-map-marker"></i>
{% endif %}
{{ _self.raw(address, options) }}
{{ _self.raw(address, options, streetLine) }}
</div>
{% endif %}
{{ _self.validity(address, options) }}

View File

@@ -11,55 +11,125 @@ declare(strict_types=1);
namespace Chill\MainBundle\Serializer\Normalizer;
use Chill\DocGeneratorBundle\Serializer\Helper\NormalizeNullValueHelper;
use Chill\MainBundle\Entity\Address;
use DateTimeInterface;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class AddressNormalizer implements NormalizerAwareInterface, NormalizerInterface
class AddressNormalizer implements ContextAwareNormalizerInterface, NormalizerAwareInterface
{
use NormalizerAwareTrait;
private const NULL_POSTCODE_COUNTRY = [
'id', 'name', 'code',
];
private const NULL_VALUE = [
'address_id',
'text',
'street',
'streetNumber',
'postcode',
'country',
'floor',
'corridor',
'steps',
'flat',
'buildingName',
'distribution',
'extra',
'validFrom' => DateTimeInterface::class,
'validTo' => DateTimeInterface::class,
];
/**
* @param Address $address
*/
public function normalize($address, ?string $format = null, array $context = [])
{
return [
'address_id' => $address->getId(),
'text' => $address->isNoAddress() ? '' : $address->getStreetNumber() . ', ' . $address->getStreet(),
'street' => $address->getStreet(),
'streetNumber' => $address->getStreetNumber(),
'postcode' => [
'id' => $address->getPostCode()->getId(),
'name' => $address->getPostCode()->getName(),
'code' => $address->getPostCode()->getCode(),
],
'country' => [
'id' => $address->getPostCode()->getCountry()->getId(),
'name' => $address->getPostCode()->getCountry()->getName(),
'code' => $address->getPostCode()->getCountry()->getCountryCode(),
],
'floor' => $address->getFloor(),
'corridor' => $address->getCorridor(),
'steps' => $address->getSteps(),
'flat' => $address->getFlat(),
'buildingName' => $address->getBuildingName(),
'distribution' => $address->getDistribution(),
'extra' => $address->getExtra(),
'validFrom' => $address->getValidFrom(),
'validTo' => $address->getValidTo(),
'addressReference' => $this->normalizer->normalize(
$address->getAddressReference(),
$format,
[AbstractNormalizer::GROUPS => ['read']]
),
];
if ($address instanceof Address) {
$text = $address->isNoAddress() ? '' : $address->getStreet() . ', ' . $address->getStreetNumber();
if (null !== $address->getPostCode()->getCountry()->getCountryCode()) {
if ($address->getPostCode()->getCountry()->getCountryCode() === 'FR') {
$text = $address->isNoAddress() ? '' : $address->getStreetNumber() . ', ' . $address->getStreet();
} else {
$text = $address->isNoAddress() ? '' : $address->getStreetNumber() . ', ' . $address->getStreet();
}
}
$data = [
'address_id' => $address->getId(),
'text' => $text,
'street' => $address->getStreet(),
'streetNumber' => $address->getStreetNumber(),
'postcode' => [
'id' => $address->getPostCode()->getId(),
'name' => $address->getPostCode()->getName(),
'code' => $address->getPostCode()->getCode(),
],
'country' => [
'id' => $address->getPostCode()->getCountry()->getId(),
'name' => $address->getPostCode()->getCountry()->getName(),
'code' => $address->getPostCode()->getCountry()->getCountryCode(),
],
'floor' => $address->getFloor(),
'corridor' => $address->getCorridor(),
'steps' => $address->getSteps(),
'flat' => $address->getFlat(),
'buildingName' => $address->getBuildingName(),
'distribution' => $address->getDistribution(),
'extra' => $address->getExtra(),
];
if ('json' === $format) {
$data['addressReference'] = $this->normalizer->normalize(
$address->getAddressReference(),
$format,
[AbstractNormalizer::GROUPS => ['read']]
);
$data['validFrom'] = $address->getValidFrom();
$data['validTo'] = $address->getValidTo();
} elseif ('docgen' === $format) {
$dateContext = array_merge($context, ['docgen:expects' => DateTimeInterface::class]);
$data['validFrom'] = $this->normalizer->normalize($address->getValidFrom(), $format, $dateContext);
$data['validTo'] = $this->normalizer->normalize($address->getValidTo(), $format, $dateContext);
}
return $data;
}
if (null === $address) {
$helper = new NormalizeNullValueHelper($this->normalizer);
return array_merge(
$helper->normalize(self::NULL_VALUE, $format, $context),
[
'postcode' => $helper->normalize(self::NULL_POSTCODE_COUNTRY, $format, $context),
'country' => $helper->normalize(self::NULL_POSTCODE_COUNTRY, $format, $context),
]
);
}
throw new UnexpectedValueException();
}
public function supportsNormalization($data, ?string $format = null)
public function supportsNormalization($data, ?string $format = null, array $context = []): bool
{
return $data instanceof Address;
if ('json' === $format) {
return $data instanceof Address;
}
if ('docgen' === $format) {
return
$data instanceof Address
|| (null === $data && Address::class === ($context['docgen:expects'] ?? null));
}
return false;
}
}

View File

@@ -11,16 +11,28 @@ declare(strict_types=1);
namespace Chill\MainBundle\Serializer\Normalizer;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Templating\Entity\UserRender;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class UserNormalizer implements NormalizerAwareInterface, NormalizerInterface
class UserNormalizer implements ContextAwareNormalizerInterface, NormalizerAwareInterface
{
use NormalizerAwareTrait;
public const NULL_USER = [
'type' => 'user',
'id' => '',
'username' => '',
'text' => '',
'label' => '',
'email' => '',
];
private UserRender $userRender;
public function __construct(UserRender $userRender)
@@ -31,20 +43,50 @@ class UserNormalizer implements NormalizerAwareInterface, NormalizerInterface
public function normalize($user, ?string $format = null, array $context = [])
{
/** @var User $user */
$userJobContext = array_merge(
$context,
['docgen:expects' => UserJob::class, 'groups' => 'docgen:read']
);
$scopeContext = array_merge(
$context,
['docgen:expects' => Scope::class, 'groups' => 'docgen:read']
);
$centerContext = array_merge(
$context,
['docgen:expects' => Center::class, 'groups' => 'docgen:read']
);
if (null === $user && 'docgen' === $format) {
return array_merge(self::NULL_USER, [
'user_job' => $this->normalizer->normalize(null, $format, $userJobContext),
'main_center' => $this->normalizer->normalize(null, $format, $centerContext),
'main_scope' => $this->normalizer->normalize(null, $format, $scopeContext),
]);
}
return [
'type' => 'user',
'id' => $user->getId(),
'username' => $user->getUsername(),
'text' => $this->userRender->renderString($user, []),
'label' => $user->getLabel(),
'user_job' => $this->normalizer->normalize($user->getUserJob(), $format, $context),
'main_center' => $this->normalizer->normalize($user->getMainCenter(), $format, $context),
'main_scope' => $this->normalizer->normalize($user->getMainScope(), $format, $context),
'email' => (string) $user->getEmail(),
'user_job' => $this->normalizer->normalize($user->getUserJob(), $format, $userJobContext),
'main_center' => $this->normalizer->normalize($user->getMainCenter(), $format, $centerContext),
'main_scope' => $this->normalizer->normalize($user->getMainScope(), $format, $scopeContext),
];
}
public function supportsNormalization($data, ?string $format = null): bool
public function supportsNormalization($data, ?string $format = null, array $context = []): bool
{
return $data instanceof User && ('json' === $format || 'docgen' === $format);
if ($data instanceof User && ('json' === $format || 'docgen' === $format)) {
return true;
}
if (null === $data && 'docgen' === $format && User::class === ($context['docgen:expects'] ?? null)) {
return true;
}
return false;
}
}

View File

@@ -46,6 +46,7 @@ class AddressRender implements ChillEntityRenderInterface
return $this->templating
->render('@ChillMain/Entity/address.html.twig', [
'address' => $addr,
'streetLine' => $this->renderStreetLine($addr),
'render' => $options['render'] ?? 'bloc',
'options' => $options,
]);
@@ -59,13 +60,7 @@ class AddressRender implements ChillEntityRenderInterface
{
$lines = [];
if (!empty($addr->getStreet())) {
$lines[0] = $addr->getStreet();
}
if (!empty($addr->getStreetNumber())) {
$lines[0] .= ', ' . $addr->getStreetNumber();
}
$lines[0] = $this->renderStreetLine($addr);
if (!empty($addr->getPostcode())) {
$lines[1] = strtr('{postcode} {label}', [
@@ -81,4 +76,33 @@ class AddressRender implements ChillEntityRenderInterface
{
return $entity instanceof Address;
}
private function renderStreetLine($addr): string
{
if (!empty($addr->getStreet())) {
$street = $addr->getStreet();
} else {
$street = '';
}
if (!empty($addr->getStreetNumber())) {
$streetNumber = $addr->getStreetNumber();
} else {
$streetNumber = '';
}
$res = trim($street . ', ' . $streetNumber, ', ');
if (null !== $addr->getPostCode()->getCountry()->getCountryCode()) {
if ($addr->getPostCode()->getCountry()->getCountryCode() === 'FR') {
$res = trim($streetNumber . ', ' . $street, ', ');
}
}
if (',' === $res) {
$res = '';
}
return $res;
}
}