fix cs and add EntityToIdTransformer

This commit is contained in:
Julien Fastré 2022-05-20 15:52:02 +02:00
parent dba0e84781
commit b6e0379583
14 changed files with 308 additions and 97 deletions

View File

@ -39,18 +39,18 @@ class CalendarController extends AbstractController
{ {
private AuthorizationHelper $authorizationHelper; private AuthorizationHelper $authorizationHelper;
private CalendarRepository $calendarRepository;
private EventDispatcherInterface $eventDispatcher; private EventDispatcherInterface $eventDispatcher;
private LoggerInterface $logger; private LoggerInterface $logger;
private PaginatorFactory $paginator; private PaginatorFactory $paginator;
private SerializerInterface $serializer;
private CalendarRepository $calendarRepository;
private RemoteCalendarConnectorInterface $remoteCalendarConnector; private RemoteCalendarConnectorInterface $remoteCalendarConnector;
private SerializerInterface $serializer;
private UserRepository $userRepository; private UserRepository $userRepository;
public function __construct( public function __construct(
@ -282,6 +282,7 @@ class CalendarController extends AbstractController
// } // }
$entity = new Calendar(); $entity = new Calendar();
if ($request->query->has('mainUser')) { if ($request->query->has('mainUser')) {
$entity->setMainUser($this->userRepository->find($request->query->getInt('mainUser'))); $entity->setMainUser($this->userRepository->find($request->query->getInt('mainUser')));
} }

View File

@ -15,13 +15,13 @@ use Chill\CalendarBundle\Repository\CalendarRangeRepository;
use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Serializer\Model\Collection; use Chill\MainBundle\Serializer\Model\Collection;
use DateTimeImmutable;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use function count; use Symfony\Component\Routing\Annotation\Route;
class CalendarRangeAPIController extends ApiController class CalendarRangeAPIController extends ApiController
{ {
@ -47,8 +47,10 @@ class CalendarRangeAPIController extends ApiController
throw new BadRequestHttpException('You must provide a dateFrom parameter'); throw new BadRequestHttpException('You must provide a dateFrom parameter');
} }
if (false === $dateFrom = \DateTimeImmutable::createFromFormat(\DateTimeImmutable::ATOM, if (false === $dateFrom = DateTimeImmutable::createFromFormat(
$request->query->get('dateFrom'))) { DateTimeImmutable::ATOM,
$request->query->get('dateFrom')
)) {
throw new BadRequestHttpException('dateFrom not parsable'); throw new BadRequestHttpException('dateFrom not parsable');
} }
@ -56,15 +58,22 @@ class CalendarRangeAPIController extends ApiController
throw new BadRequestHttpException('You must provide a dateTo parameter'); throw new BadRequestHttpException('You must provide a dateTo parameter');
} }
if (false === $dateTo = \DateTimeImmutable::createFromFormat(\DateTimeImmutable::ATOM, if (false === $dateTo = DateTimeImmutable::createFromFormat(
$request->query->get('dateTo'))) { DateTimeImmutable::ATOM,
$request->query->get('dateTo')
)) {
throw new BadRequestHttpException('dateTo not parsable'); throw new BadRequestHttpException('dateTo not parsable');
} }
$total = $this->calendarRangeRepository->countByAvailableRangesForUser($user, $dateFrom, $dateTo); $total = $this->calendarRangeRepository->countByAvailableRangesForUser($user, $dateFrom, $dateTo);
$paginator = $this->getPaginatorFactory()->create($total); $paginator = $this->getPaginatorFactory()->create($total);
$ranges = $this->calendarRangeRepository->findByAvailableRangesForUser($user, $dateFrom, $dateTo, $ranges = $this->calendarRangeRepository->findByAvailableRangesForUser(
$paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber()); $user,
$dateFrom,
$dateTo,
$paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber()
);
$collection = new Collection($ranges, $paginator); $collection = new Collection($ranges, $paginator);

View File

@ -27,11 +27,12 @@ use DateTimeImmutable;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use LogicException;
use Symfony\Component\Serializer\Annotation as Serializer; use Symfony\Component\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Range; use Symfony\Component\Validator\Constraints\Range;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use function in_array; use function in_array;
/** /**
@ -159,8 +160,8 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
public function addInvite(Invite $invite): self public function addInvite(Invite $invite): self
{ {
if ($invite->getCalendar() instanceof Calendar && $this !== $invite->getCalendar()) { if ($invite->getCalendar() instanceof Calendar && $invite->getCalendar() !== $this) {
throw new \LogicException('Not allowed to move an invitation to another Calendar'); throw new LogicException('Not allowed to move an invitation to another Calendar');
} }
$this->invites[] = $invite; $this->invites[] = $invite;
@ -169,29 +170,6 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
return $this; return $this;
} }
public function addUser(User $user): self
{
if (!$this->getUsers()->contains($user)) {
$this->addInvite((new Invite())->setUser($user));
}
return $this;
}
public function removeUser(User $user): self
{
if (!$this->getUsers()->contains($user)) {
return $this;
}
$invite = $this->invites
->filter(function (Invite $invite) use ($user) { return $invite->getUser() === $user; })
->first();
$this->removeInvite($invite);
return $this;
}
public function addPerson(Person $person): self public function addPerson(Person $person): self
{ {
$this->persons[] = $person; $this->persons[] = $person;
@ -206,6 +184,15 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
return $this; return $this;
} }
public function addUser(User $user): self
{
if (!$this->getUsers()->contains($user)) {
$this->addInvite((new Invite())->setUser($user));
}
return $this;
}
public function getAccompanyingPeriod(): ?AccompanyingPeriod public function getAccompanyingPeriod(): ?AccompanyingPeriod
{ {
return $this->accompanyingPeriod; return $this->accompanyingPeriod;
@ -334,7 +321,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
*/ */
public function getUsers(): Collection public function getUsers(): Collection
{ {
return $this->getInvites()->map(function (Invite $i) { return $i->getUser(); }); return $this->getInvites()->map(static function (Invite $i) { return $i->getUser(); });
} }
public static function loadValidatorMetadata(ClassMetadata $metadata): void public static function loadValidatorMetadata(ClassMetadata $metadata): void
@ -374,6 +361,20 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
return $this; return $this;
} }
public function removeUser(User $user): self
{
if (!$this->getUsers()->contains($user)) {
return $this;
}
$invite = $this->invites
->filter(static function (Invite $invite) use ($user) { return $invite->getUser() === $user; })
->first();
$this->removeInvite($invite);
return $this;
}
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
{ {
$this->accompanyingPeriod = $accompanyingPeriod; $this->accompanyingPeriod = $accompanyingPeriod;
@ -450,6 +451,4 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
return $this; return $this;
} }
} }

View File

@ -11,7 +11,6 @@ declare(strict_types=1);
namespace Chill\CalendarBundle\Entity; namespace Chill\CalendarBundle\Entity;
use Chill\CalendarBundle\Repository\CalendarRangeRepository;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait; use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;

View File

@ -18,6 +18,7 @@ use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait; use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use LogicException;
/** /**
* @ORM\Table(name="chill_calendar.invite") * @ORM\Table(name="chill_calendar.invite")
@ -98,7 +99,7 @@ class Invite implements TrackUpdateInterface, TrackCreationInterface
public function setUser(?User $user): self public function setUser(?User $user): self
{ {
if ($user instanceof User && $this->user instanceof User && $user !== $this->user) { if ($user instanceof User && $this->user instanceof User && $user !== $this->user) {
throw new \LogicException("Not allowed to associate an invite to a different user"); throw new LogicException('Not allowed to associate an invite to a different user');
} }
$this->user = $user; $this->user = $user;

View File

@ -14,9 +14,7 @@ namespace Chill\CalendarBundle\Form;
use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Entity\Calendar;
use Chill\CalendarBundle\Entity\CalendarRange; use Chill\CalendarBundle\Entity\CalendarRange;
use Chill\CalendarBundle\Entity\CancelReason; use Chill\CalendarBundle\Entity\CancelReason;
use Chill\CalendarBundle\Entity\Invite;
use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\Type\CommentType; use Chill\MainBundle\Form\Type\CommentType;
use Chill\MainBundle\Form\Type\PickUserDynamicType; use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
@ -126,6 +124,7 @@ class CalendarType extends AbstractType
if (null === $personsAsString) { if (null === $personsAsString) {
return []; return [];
} }
return array_map( return array_map(
fn (string $id): ?Person => $this->om->getRepository(Person::class)->findOneBy(['id' => (int) $id]), fn (string $id): ?Person => $this->om->getRepository(Person::class)->findOneBy(['id' => (int) $id]),
explode(',', $personsAsString) explode(',', $personsAsString)
@ -149,6 +148,7 @@ class CalendarType extends AbstractType
if (null === $thirdpartyAsString) { if (null === $thirdpartyAsString) {
return []; return [];
} }
return array_map( return array_map(
fn (string $id): ?ThirdParty => $this->om->getRepository(ThirdParty::class)->findOneBy(['id' => (int) $id]), fn (string $id): ?ThirdParty => $this->om->getRepository(ThirdParty::class)->findOneBy(['id' => (int) $id]),
explode(',', $thirdpartyAsString) explode(',', $thirdpartyAsString)

View File

@ -13,20 +13,16 @@ namespace Chill\CalendarBundle\Menu;
use Chill\CalendarBundle\Security\Voter\CalendarVoter; use Chill\CalendarBundle\Security\Voter\CalendarVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Knp\Menu\MenuItem; use Knp\Menu\MenuItem;
use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
{ {
private Security $security;
protected TranslatorInterface $translator; protected TranslatorInterface $translator;
private Security $security;
public function __construct( public function __construct(
Security $security, Security $security,
TranslatorInterface $translator TranslatorInterface $translator

View File

@ -35,7 +35,6 @@ class RemoteCalendarCompilerPass implements CompilerPassInterface
if ($config['remote_calendars_sync']['microsoft_graph']['enabled']) { if ($config['remote_calendars_sync']['microsoft_graph']['enabled']) {
$connector = MSGraphRemoteCalendarConnector::class; $connector = MSGraphRemoteCalendarConnector::class;
} else { } else {
// remove services which cannot be loaded // remove services which cannot be loaded
$container->removeDefinition(MapUserCalendarCommand::class); $container->removeDefinition(MapUserCalendarCommand::class);
@ -47,7 +46,6 @@ class RemoteCalendarCompilerPass implements CompilerPassInterface
$container->setAlias(Azure::class, 'knpu.oauth2.provider.azure'); $container->setAlias(Azure::class, 'knpu.oauth2.provider.azure');
} }
if (null === $connector) { if (null === $connector) {
throw new RuntimeException('Could not configure remote calendar'); throw new RuntimeException('Could not configure remote calendar');
} }

View File

@ -13,14 +13,10 @@ namespace Chill\CalendarBundle\Repository;
use Chill\CalendarBundle\Entity\CalendarRange; use Chill\CalendarBundle\Entity\CalendarRange;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Persistence\ObjectRepository; use Doctrine\Persistence\ObjectRepository;
use Monolog\DateTimeImmutable;
use UnexpectedValueException;
class CalendarRangeRepository implements ObjectRepository class CalendarRangeRepository implements ObjectRepository
{ {
@ -31,6 +27,13 @@ class CalendarRangeRepository implements ObjectRepository
$this->repository = $entityManager->getRepository(CalendarRange::class); $this->repository = $entityManager->getRepository(CalendarRange::class);
} }
public function countByAvailableRangesForUser(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to): int
{
return $this->buildQueryAvailableRangesForUser($user, $from, $to)
->select('COUNT(cr)')
->getQuery()->getSingleScalarResult();
}
public function find($id): ?CalendarRange public function find($id): ?CalendarRange
{ {
return $this->repository->find($id); return $this->repository->find($id);
@ -44,7 +47,6 @@ class CalendarRangeRepository implements ObjectRepository
return $this->repository->findAll(); return $this->repository->findAll();
} }
/** /**
* @return array|CalendarRange[] * @return array|CalendarRange[]
*/ */
@ -53,23 +55,6 @@ class CalendarRangeRepository implements ObjectRepository
return $this->repository->findBy($criteria, $orderBy, $limit, $offset); return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
} }
public function findOneBy(array $criteria): ?CalendarRange
{
return $this->repository->findOneBy($criteria);
}
public function getClassName(): string
{
return CalendarRange::class;
}
public function countByAvailableRangesForUser(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to): int
{
return $this->buildQueryAvailableRangesForUser($user, $from, $to)
->select('COUNT(cr)')
->getQuery()->getSingleScalarResult();
}
/** /**
* @return array|CalendarRange[] * @return array|CalendarRange[]
*/ */
@ -82,17 +67,27 @@ class CalendarRangeRepository implements ObjectRepository
): array { ): array {
$qb = $this->buildQueryAvailableRangesForUser($user, $from, $to); $qb = $this->buildQueryAvailableRangesForUser($user, $from, $to);
if ($limit !== null) { if (null !== $limit) {
$qb->setMaxResults($limit); $qb->setMaxResults($limit);
} }
if ($offset !== null) { if (null !== $offset) {
$qb->setFirstResult($offset); $qb->setFirstResult($offset);
} }
return $qb->getQuery()->getResult(); return $qb->getQuery()->getResult();
} }
public function findOneBy(array $criteria): ?CalendarRange
{
return $this->repository->findOneBy($criteria);
}
public function getClassName(): string
{
return CalendarRange::class;
}
private function buildQueryAvailableRangesForUser(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to): QueryBuilder private function buildQueryAvailableRangesForUser(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to): QueryBuilder
{ {
$qb = $this->repository->createQueryBuilder('cr'); $qb = $this->repository->createQueryBuilder('cr');
@ -110,9 +105,6 @@ class CalendarRangeRepository implements ObjectRepository
'user' => $user, 'user' => $user,
'startDate' => $from, 'startDate' => $from,
'endDate' => $to, 'endDate' => $to,
]) ]);
;
} }
} }

View File

@ -1,5 +1,14 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\CalendarBundle\Security\Voter; namespace Chill\CalendarBundle\Security\Voter;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter; use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
@ -7,8 +16,8 @@ use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
use Chill\MainBundle\Security\Authorization\VoterHelperInterface; use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use LogicException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
@ -16,12 +25,10 @@ class CalendarVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
{ {
public const SEE = 'CHILL_CALENDAR_CALENDAR_SEE'; public const SEE = 'CHILL_CALENDAR_CALENDAR_SEE';
private Security $security; private Security $security;
private VoterHelperInterface $voterHelper; private VoterHelperInterface $voterHelper;
public function __construct( public function __construct(
Security $security, Security $security,
VoterHelperFactoryInterface $voterHelperFactory VoterHelperFactoryInterface $voterHelperFactory
@ -33,11 +40,6 @@ class CalendarVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
->build(); ->build();
} }
public function getRolesWithHierarchy(): array
{
return ['Calendar' => $this->getRoles()];
}
public function getRoles(): array public function getRoles(): array
{ {
return [ return [
@ -45,6 +47,11 @@ class CalendarVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
]; ];
} }
public function getRolesWithHierarchy(): array
{
return ['Calendar' => $this->getRoles()];
}
public function getRolesWithoutScope(): array public function getRolesWithoutScope(): array
{ {
return []; return [];
@ -60,20 +67,18 @@ class CalendarVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
if ($subject instanceof AccompanyingPeriod) { if ($subject instanceof AccompanyingPeriod) {
switch ($attribute) { switch ($attribute) {
case self::SEE: case self::SEE:
if ($subject->getStep() === AccompanyingPeriod::STEP_DRAFT) { if ($subject->getStep() === AccompanyingPeriod::STEP_DRAFT) {
return false; return false;
} }
// we first check here that the user has read access to the period // we first check here that the user has read access to the period
return $this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject); return $this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject);
default: default:
throw new \LogicException('subject not implemented'); throw new LogicException('subject not implemented');
} }
} }
throw new \LogicException('attribute not implemented'); throw new LogicException('attribute not implemented');
} }
} }

View File

@ -1,12 +1,25 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\CalendarBundle\Tests\Entity; namespace Chill\CalendarBundle\Tests\Entity;
use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Entity\Calendar;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class CalendarTest extends TestCase /**
* @internal
* @coversNothing
*/
final class CalendarTest extends TestCase
{ {
public function testAddUser() public function testAddUser()
{ {
@ -40,5 +53,4 @@ class CalendarTest extends TestCase
$this->assertCount(0, $calendar->getInvites()); $this->assertCount(0, $calendar->getInvites());
$this->assertCount(0, $calendar->getUsers()); $this->assertCount(0, $calendar->getUsers());
} }
} }

View File

@ -0,0 +1,82 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\MainBundle\Form\DataTransformer;
use Closure;
use Doctrine\Persistence\ObjectRepository;
use Symfony\Component\Form\DataTransformerInterface;
use function call_user_func;
/**
* @template T
*/
class IdToEntityDataTransformer implements DataTransformerInterface
{
private Closure $getId;
private bool $multiple = false;
private ObjectRepository $repository;
/**
* @param Closure $getId
*/
public function __construct(ObjectRepository $repository, bool $multiple = false, ?callable $getId = null)
{
$this->repository = $repository;
$this->multiple = $multiple;
$this->getId = $getId ?? static function (object $o) { return $o->getId(); };
}
/**
* @param string $value
*
* @return array|object[]|T[]|T|object
*/
public function reverseTransform($value)
{
if ($this->multiple) {
if (null === $value | '' === $value) {
return [];
}
return array_map(
fn (string $id): ?object => $this->repository->findOneBy(['id' => (int) $id]),
explode(',', $value)
);
}
if (null === $value | '' === $value) {
return null;
}
return $this->repository->findOneBy(['id' => (int) $value]);
}
/**
* @param object|T|object[]|T[] $value
*/
public function transform($value): string
{
if ($this->multiple) {
$ids = [];
foreach ($value as $v) {
$ids[] = call_user_func($this->getId, $v);
}
return implode(',', $ids);
}
return call_user_func($this->getId, $value);
}
}

View File

@ -13,7 +13,6 @@ namespace Chill\MainBundle\Repository;
use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Location;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
/** /**

View File

@ -0,0 +1,118 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Form\DataTransformer;
use Chill\MainBundle\Form\DataTransformer\IdToEntityDataTransformer;
use Doctrine\Persistence\ObjectRepository;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use stdClass;
/**
* @internal
* @coversNothing
*/
final class IdToEntityDataTransformerTest extends TestCase
{
use ProphecyTrait;
public function testReverseTransformMulti()
{
$o1 = new stdClass();
$o2 = new stdClass();
$repository = $this->prophesize(ObjectRepository::class);
$repository->findOneBy(Argument::exact(['id' => 1]))->willReturn($o1);
$repository->findOneBy(Argument::exact(['id' => 2]))->willReturn($o2);
$transformer = new IdToEntityDataTransformer(
$repository->reveal(),
true
);
$this->assertEquals([], $transformer->reverseTransform(null));
$this->assertEquals([], $transformer->reverseTransform(''));
$r = $transformer->reverseTransform('1,2');
$this->assertIsArray($r);
$this->assertSame($o1, $r[0]);
$this->assertSame($o2, $r[1]);
}
public function testReverseTransformSingle()
{
$o = new stdClass();
$repository = $this->prophesize(ObjectRepository::class);
$repository->findOneBy(Argument::exact(['id' => 1]))->willReturn($o);
$transformer = new IdToEntityDataTransformer(
$repository->reveal(),
false
);
$this->assertEquals(null, $transformer->reverseTransform(null));
$this->assertEquals(null, $transformer->reverseTransform(''));
$r = $transformer->reverseTransform('1');
$this->assertSame($o, $r);
}
public function testTransformMulti()
{
$o1 = new class() {
public function getId()
{
return 1;
}
};
$o2 = new class() {
public function getId()
{
return 2;
}
};
$repository = $this->prophesize(ObjectRepository::class);
$transformer = new IdToEntityDataTransformer(
$repository->reveal(),
true
);
$this->assertEquals(
'1,2',
$transformer->transform([$o1, $o2])
);
}
public function testTransformSingle()
{
$o = new class() {
public function getId()
{
return 1;
}
};
$repository = $this->prophesize(ObjectRepository::class);
$transformer = new IdToEntityDataTransformer(
$repository->reveal(),
false
);
$this->assertEquals(
'1',
$transformer->transform($o)
);
}
}