Bootstrap encoder for documents

This commit is contained in:
2021-11-22 09:05:15 +00:00
parent 46a4afe1b3
commit d0bf47e0d5
25 changed files with 992 additions and 91 deletions

View File

@@ -1,19 +1,19 @@
<?php
/*
*
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -23,12 +23,11 @@ namespace Chill\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Serializer\Annotation as Serializer;
/**
* @ORM\Entity
* @ORM\Table(name="centers")
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class Center implements HasCenterInterface
{
@@ -46,9 +45,10 @@ class Center implements HasCenterInterface
* @var string
*
* @ORM\Column(type="string", length=255)
* @Serializer\Groups({"docgen:read"})
*/
private $name;
private string $name = '';
/**
* @var Collection
*
@@ -58,8 +58,8 @@ class Center implements HasCenterInterface
* )
*/
private $groupCenters;
/**
* Center constructor.
*/
@@ -67,7 +67,7 @@ class Center implements HasCenterInterface
{
$this->groupCenters = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* @return string
*/
@@ -75,7 +75,7 @@ class Center implements HasCenterInterface
{
return $this->name;
}
/**
* @param $name
* @return $this
@@ -85,7 +85,7 @@ class Center implements HasCenterInterface
$this->name = $name;
return $this;
}
/**
* @return int
*/
@@ -93,7 +93,7 @@ class Center implements HasCenterInterface
{
return $this->id;
}
/**
* @return ArrayCollection|Collection
*/
@@ -101,7 +101,7 @@ class Center implements HasCenterInterface
{
return $this->groupCenters;
}
/**
* @param GroupCenter $groupCenter
* @return $this
@@ -111,7 +111,7 @@ class Center implements HasCenterInterface
$this->groupCenters->add($groupCenter);
return $this;
}
/**
* @return string
*/
@@ -119,7 +119,7 @@ class Center implements HasCenterInterface
{
return $this->getName();
}
/**
* @return $this|Center
*/

View File

@@ -8,7 +8,7 @@ use Doctrine\Common\Collections\ArrayCollection;
use Chill\MainBundle\Entity\UserJob;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation as Serializer;
/**
* User
@@ -16,7 +16,7 @@ use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
* @ORM\Entity
* @ORM\Table(name="users")
* @ORM\Cache(usage="NONSTRICT_READ_WRITE", region="acl_cache_region")
* @DiscriminatorMap(typeProperty="type", mapping={
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
* "user"=User::class
* })
*/
@@ -51,6 +51,7 @@ class User implements AdvancedUserInterface {
/**
* @ORM\Column(type="string", length=200)
* @Serializer\Groups({"docgen:read"})
*/
private string $label = '';
@@ -58,8 +59,9 @@ class User implements AdvancedUserInterface {
* @var string
*
* @ORM\Column(type="string", length=150, nullable=true)
* @Serializer\Groups({"docgen:read"})
*/
private $email;
private ?string $email = null;
/**
* @var string
@@ -123,6 +125,7 @@ class User implements AdvancedUserInterface {
/**
* @var Center|null
* @ORM\ManyToOne(targetEntity=Center::class)
* @Serializer\Groups({"docgen:read"})
*/
private ?Center $mainCenter = null;

View File

@@ -1,18 +1,18 @@
<?php
/*
*
*
* Copyright (C) 2014-2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -27,7 +27,7 @@ use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
/**
*
*
*
*/
class CenterNormalizer implements NormalizerInterface, DenormalizerInterface
@@ -52,7 +52,7 @@ class CenterNormalizer implements NormalizerInterface, DenormalizerInterface
public function supportsNormalization($data, string $format = null): bool
{
return $data instanceof Center;
return $data instanceof Center && $format === 'json';
}
public function denormalize($data, string $type, string $format = null, array $context = [])

View File

@@ -19,23 +19,78 @@
namespace Chill\MainBundle\Serializer\Normalizer;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
class DateNormalizer implements NormalizerInterface, DenormalizerInterface
class DateNormalizer implements ContextAwareNormalizerInterface, DenormalizerInterface
{
private RequestStack $requestStack;
private ParameterBagInterface $parameterBag;
public function __construct(RequestStack $requestStack, ParameterBagInterface $parameterBag)
{
$this->requestStack = $requestStack;
$this->parameterBag = $parameterBag;
}
public function normalize($date, string $format = null, array $context = array())
{
/** @var \DateTimeInterface $date */
return [
'datetime' => $date->format(\DateTimeInterface::ISO8601)
];
switch($format) {
case 'json':
return [
'datetime' => $date->format(\DateTimeInterface::ISO8601)
];
case 'docgen':
if (null === $date) {
return [
'long' => '', 'short' => ''
];
}
$hasTime = $date->format('His') !== "000000";
$request = $this->requestStack->getCurrentRequest();
$locale = null !== $request ? $request->getLocale() : $this->parameterBag->get('kernel.default_locale');
$formatterLong = \IntlDateFormatter::create(
$locale,
\IntlDateFormatter::LONG,
$hasTime ? \IntlDateFormatter::SHORT: \IntlDateFormatter::NONE
);
$formatterShort = \IntlDateFormatter::create(
$locale,
\IntlDateFormatter::SHORT,
$hasTime ? \IntlDateFormatter::SHORT: \IntlDateFormatter::NONE
);
return [
'short' => $formatterShort->format($date),
'long' => $formatterLong->format($date)
];
}
}
public function supportsNormalization($data, string $format = null): bool
public function supportsNormalization($data, string $format = null, array $context = []): bool
{
return $data instanceof \DateTimeInterface;
if ($format === 'json') {
return $data instanceof \DateTimeInterface;
} elseif ($format === 'docgen') {
return $data instanceof \DateTimeInterface || (
$data === null
&& \array_key_exists('docgen:expects', $context)
&& (
$context['docgen:expects'] === \DateTimeInterface::class
|| $context['docgen:expects'] === \DateTime::class
|| $context['docgen:expects'] === \DateTimeImmutable::class
)
);
}
return false;
}
public function denormalize($data, string $type, string $format = null, array $context = [])

View File

@@ -52,6 +52,6 @@ class UserNormalizer implements NormalizerInterface, NormalizerAwareInterface
public function supportsNormalization($data, string $format = null): bool
{
return $data instanceof User;
return $format === 'json' && $data instanceof User;
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Serializer\Normalizer;
use Chill\MainBundle\Serializer\Normalizer\DateNormalizer;
use Prophecy\Prophet;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
class DateNormalizerTest extends KernelTestCase
{
private Prophet $prophet;
public function setUp()
{
$this->prophet = new Prophet();
}
public function testSupports()
{
$this->assertTrue($this->buildDateNormalizer()->supportsNormalization(new \DateTime(), 'json'));
$this->assertTrue($this->buildDateNormalizer()->supportsNormalization(new \DateTimeImmutable(), 'json'));
$this->assertTrue($this->buildDateNormalizer()->supportsNormalization(new \DateTime(), 'docgen'));
$this->assertTrue($this->buildDateNormalizer()->supportsNormalization(new \DateTimeImmutable(), 'docgen'));
$this->assertTrue($this->buildDateNormalizer()->supportsNormalization(null, 'docgen', ['docgen:expects' => \DateTimeImmutable::class]));
$this->assertTrue($this->buildDateNormalizer()->supportsNormalization(null, 'docgen', ['docgen:expects' => \DateTimeInterface::class]));
$this->assertTrue($this->buildDateNormalizer()->supportsNormalization(null, 'docgen', ['docgen:expects' => \DateTime::class]));
$this->assertFalse($this->buildDateNormalizer()->supportsNormalization(new \stdClass(), 'docgen'));
$this->assertFalse($this->buildDateNormalizer()->supportsNormalization(new \DateTime(), 'xml'));
}
/**
* @dataProvider generateDataNormalize
*/
public function testNormalize($expected, $date, $format, $locale, $msg)
{
$this->assertEquals($expected, $this->buildDateNormalizer($locale)->normalize($date, $format, []), $msg);
}
private function buildDateNormalizer(string $locale = null): DateNormalizer
{
$requestStack = $this->prophet->prophesize(RequestStack::class);
$parameterBag = new ParameterBag();
$parameterBag->set('kernel.default_locale', 'fr');
if ($locale === null) {
$requestStack->getCurrentRequest()->willReturn(null);
} else {
$request = $this->prophet->prophesize(Request::class);
$request->getLocale()->willReturn($locale);
$requestStack->getCurrentRequest()->willReturn($request->reveal());
}
return new DateNormalizer($requestStack->reveal(), $parameterBag);
}
public function generateDataNormalize()
{
$datetime = \DateTime::createFromFormat('Y-m-d H:i:sO', '2021-06-05 15:05:01+02:00');
$date = \DateTime::createFromFormat('Y-m-d H:i:sO', '2021-06-05 00:00:00+02:00');
yield [
['datetime' => '2021-06-05T15:05:01+0200'],
$datetime, 'json', null, 'simple normalization to json'
];
yield [
['long' => '5 juin 2021', 'short' => '05/06/2021'],
$date, 'docgen', 'fr', 'normalization to docgen for a date, with current request'
];
yield [
['long' => '5 juin 2021', 'short' => '05/06/2021'],
$date, 'docgen', null, 'normalization to docgen for a date, without current request'
];
yield [
['long' => '5 juin 2021 à 15:05', 'short' => '05/06/2021 15:05'],
$datetime, 'docgen', null, 'normalization to docgen for a datetime, without current request'
];
yield [
['long' => '', 'short' => ''],
null, 'docgen', null, 'normalization to docgen for a null datetime'
];
}
}