src/Service/BaseService.php line 622

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Entity\User;
  4. use Doctrine\DBAL\LockMode;
  5. use Psr\Log\LoggerInterface;
  6. use App\Misc\AppMappingOperation;
  7. use App\Misc\TransformDataHelper;
  8. use Symfony\Component\Mime\Email;
  9. use App\Repository\BaseRepository;
  10. use App\Exception\CacheHitResponse;
  11. use Symfony\Component\Mime\Address;
  12. use App\Exception\ValidateException;
  13. use App\Exception\BadRequestException;
  14. use App\Annotation\TransformAnnotation;
  15. use AutoMapperPlus\AutoMapperInterface;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use League\Flysystem\FilesystemOperator;
  18. use Doctrine\ORM\Mapping\ClassMetadataInfo;
  19. use Symfony\Contracts\Cache\CacheInterface;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\Mailer\MailerInterface;
  22. use Symfony\Component\HttpFoundation\UrlHelper;
  23. use Doctrine\Common\Annotations\AnnotationReader;
  24. use Symfony\Component\Cache\Adapter\RedisAdapter;
  25. use Symfony\Contracts\HttpClient\HttpClientInterface;
  26. use Symfony\Component\Mime\Exception\RfcComplianceException;
  27. use Symfony\Component\Validator\Validator\ValidatorInterface;
  28. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  29. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  30. use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
  31. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  32. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  33. class BaseService
  34. {
  35.     public function __construct(
  36.         \Symfony\Component\DependencyInjection\ContainerInterface $container,
  37.         CommonService $commonService,
  38.         AutoMapperInterface $autoMapper,
  39.         TransformDataHelper $transformDataHelper,
  40.         ValidatorInterface $validator,
  41.         TokenStorageInterface $tokenStorage,
  42.         ParameterBagInterface $params,
  43.         BaseRepository $baseRepository,
  44.         UrlHelper $urlHelper,
  45.         CacheInterface $appCache,
  46.         \Psr\Container\ContainerInterface $serviceLocator,
  47.         LoggerInterface $logger,
  48.         AppMappingOperation $appMappingOperation,
  49.         HttpClientInterface $httpClient,
  50.         UrlGeneratorInterface $urlGenerator,
  51.         MailerInterface $mailer,
  52.         FilesystemOperator $uploadsStorage
  53.     ) {
  54.         $this->container $container;
  55.         $this->commonService $commonService;
  56.         $this->autoMapper $autoMapper;
  57.         $this->autoMapper->getConfiguration()->getOptions()->setDefaultMappingOperation($appMappingOperation);
  58.         $this->transformDataHelper $transformDataHelper;
  59.         $this->validator $validator;
  60.         $this->tokenStorage $tokenStorage;
  61.         $this->params $params;
  62.         $this->entityManager $baseRepository->getEntityManager();
  63.         $this->urlHelper $urlHelper;
  64.         $this->cache $appCache;
  65.         $this->serviceLocator $serviceLocator;
  66.         $this->logger $logger;
  67.         $this->httpClient $httpClient;
  68.         $this->urlGenerator $urlGenerator;
  69.         $this->mailer $mailer;
  70.         $this->uploadsStorage $uploadsStorage;
  71.     }
  72.     public function reflectFromParent($parent)
  73.     {
  74.         $this->container $parent->container;
  75.         $this->commonService $parent->commonService;
  76.         $this->autoMapper $parent->autoMapper;
  77.         $this->transformDataHelper $parent->transformDataHelper;
  78.         $this->validator $parent->validator;
  79.         $this->tokenStorage $parent->tokenStorage;
  80.         $this->params $parent->params;
  81.         $this->entityManager $parent->entityManager;
  82.         $this->cache $parent->cache;
  83.         $this->urlHelper $parent->urlHelper;
  84.         $this->serviceLocator $parent->serviceLocator;
  85.         $this->logger $parent->logger;
  86.         $this->httpClient $parent->httpClient;
  87.         $this->urlGenerator $parent->urlGenerator;
  88.         $this->mailer $parent->mailer;
  89.         $this->uploadsStorage $parent->uploadsStorage;
  90.     }
  91.     public function getProperty($propertyName)
  92.     {
  93.         return $this->$propertyName;
  94.     }
  95.     public function getContainer()
  96.     {
  97.         return $this->container;
  98.     }
  99.     /**
  100.      * @return EntityManagerInterface
  101.      */
  102.     public function getEntityManager()
  103.     {
  104.         return $this->entityManager;
  105.     }
  106.     public function add(
  107.         $request,
  108.         array $inputs null,
  109.         String $requestDTO null,
  110.         String $responseDTO null,
  111.         Bool $inTransaction false,
  112.         array $checkExists = [],
  113.         Bool $includeRelations false,
  114.         callable $beforeMappingCallback null
  115.     ) {
  116.         $serviceName $this->commonService->getClassName($thistrue);
  117.         if (empty($requestDTO)) {
  118.             $requestDTO 'App\DTO\\' $serviceName '\Add' $serviceName 'Input';
  119.         }
  120.         $this->logger->info('serviceName in add', [$serviceName]);
  121.         $object $this->inputResolver($request$requestDTO$inputs$serviceName$checkExists);
  122.         $this->logger->info('object', (array) $object);
  123.         $entity $this->objectToEntity($object$serviceNamenull$includeRelations);
  124.         $this->logger->info('entity', (array) $entity);
  125.         $this->repository->save($entity$inTransaction);
  126.         if (empty($responseDTO)) {
  127.             $responseDTO 'App\DTO\\' $serviceName '\\' $serviceName 'Output';
  128.         }
  129.         if (strtolower($responseDTO) == 'entity') {
  130.             return $entity;
  131.         }
  132.         if (!is_null($beforeMappingCallback)) {
  133.             call_user_func($beforeMappingCallback$entity);
  134.         }
  135.         $objectDTO $this->autoMapper->map($entity$responseDTO);
  136.         $this->logger->info('after output mapping', (array) $objectDTO);
  137.         return $objectDTO;
  138.     }
  139.     public function update(
  140.         $entity null,
  141.         $request null,
  142.         array $inputs null,
  143.         String $requestDTO null,
  144.         String $responseDTO null,
  145.         Bool $inTransaction false,
  146.         Bool $includeRelations false,
  147.         callable $beforeMappingCallback null
  148.     ) {
  149.         $serviceName $this->commonService->getClassName($thistrue);
  150.         if (empty($requestDTO)) {
  151.             $requestDTO 'App\DTO\\' $serviceName '\Update' $serviceName 'Input';
  152.             if (!class_exists($requestDTO)) {
  153.                 $requestDTO 'App\DTO\\' $serviceName '\Add' $serviceName 'Input';
  154.             }
  155.         }
  156.         if (is_null($entity)) {
  157.             if (is_array($request) && isset($request['id'])) {
  158.                 $id $request['id'];
  159.             } else {
  160.                 $id array_merge(
  161.                     $request->request->all(),
  162.                     $request->query->all(),
  163.                     json_decode($request->getContent(), 1) ?? []
  164.                 )['id'];
  165.             }
  166.             $entity $this->get($id);
  167.         }
  168.         $this->logger->info('serviceName in update', [$serviceName]);
  169.         $object $this->inputResolver($request$requestDTO$inputs$serviceName);
  170.         $this->logger->info('object', [$object]);
  171.         $this->objectToEntity($object$serviceName$entity$includeRelations);
  172.         $this->repository->save($entity$inTransaction);
  173.         $this->logger->info('entity', [$entity]);
  174.         if (empty($responseDTO)) {
  175.             $responseDTO 'App\DTO\\' $serviceName '\\' $serviceName 'Output';
  176.         }
  177.         if ($responseDTO == 'ENTITY') {
  178.             return $entity;
  179.         }
  180.         if (!is_null($beforeMappingCallback)) {
  181.             call_user_func($beforeMappingCallback$entity);
  182.         }
  183.         $objectDTO $this->autoMapper->map($entity$responseDTO);
  184.         $this->logger->info('objectDTO', [$objectDTO]);
  185.         return $objectDTO;
  186.     }
  187.     public function delete(
  188.         $entity null,
  189.         $filters = [],
  190.         $strict true,
  191.         $inTransaction false
  192.     ) {
  193.         if (is_int($entity)) {
  194.             $entity $this->get($entity);
  195.         }
  196.         if (is_null($entity)) {
  197.             $entity $this->repository->findOneBy($filters);
  198.             if (is_null($entity)) {
  199.                 if ($strict) {
  200.                     $serviceName $this->commonService->getClassName($thistrue);
  201.                     throw new BadRequestException(
  202.                         BadRequestException::NO_ENTITY_TO_DELETE,
  203.                         null,
  204.                         $serviceName
  205.                     );
  206.                 } else {
  207.                     return false;
  208.                 }
  209.             }
  210.         }
  211.         $this->repository->delete($entity$inTransaction);
  212.         return true;
  213.     }
  214.     public function inputResolver(
  215.         $request,
  216.         $requestDTO,
  217.         $inputs null,
  218.         $serviceName null,
  219.         $checkExists = []
  220.     ) {
  221.         $this->logger->info('serviceName in inputResolver', [$serviceName]);
  222.         if ($request instanceof Request) {
  223.             $inputArr array_merge(
  224.                 $request->request->all(),
  225.                 $request->query->all(),
  226.                 json_decode($request->getContent(), 1) ?? []
  227.             );
  228.         } else {
  229.             $inputArr $request;
  230.         }
  231.         if (!empty($inputs)) {
  232.             $inputArr array_merge($inputArr$inputs);
  233.         }
  234.         if (count($checkExists) > 0) {
  235.             $checkExists array_intersect_key(
  236.                 $inputArr,
  237.                 array_flip($checkExists)
  238.             );
  239.             $existedEntity $this->repository->findOneBy($checkExists);
  240.             if (!is_null($existedEntity)) {
  241.                 throw new BadRequestException(
  242.                     BadRequestException::DUPLICATE_ENTITY,
  243.                     null,
  244.                     $serviceName
  245.                 );
  246.             }
  247.         }
  248.         $inputDTO $this->autoMapper->map($inputArr$requestDTO);
  249.         if (isset($inputArr['id'])) {
  250.             $inputDTO->id $inputArr['id'];
  251.         }
  252.         $properties array_keys($inputArr);
  253.         $this->logger->info('inputArr', [$inputArr]);
  254.         if (
  255.             $request instanceof Request
  256.             && $request->files->count()
  257.         ) {
  258.             foreach ($request->files->all() as $fieldName => $file) {
  259.                 $this->logger->info('fieldName', [$fieldName]);
  260.                 $this->logger->info('file', [$file]);
  261.                 if (is_array($file)) {
  262.                     if (!is_array($inputDTO->{$fieldName})) {
  263.                         $inputDTO->{$fieldName} = [];
  264.                     }
  265.                     foreach ($file as $index => $childFile) {
  266.                         if (is_array($childFile)) {
  267.                             $inputDTO->{$fieldName}[$index][array_keys($childFile)[0]] = array_values($childFile)[0];
  268.                         } else {
  269.                             if (!is_null($childFile)) {
  270.                                 $inputDTO->{$fieldName}[$index] = $childFile;
  271.                             }
  272.                         }
  273.                     }
  274.                 } else {
  275.                     if (!is_null($file)) {
  276.                         $inputDTO->{$fieldName} = $file;
  277.                         $properties[] = $fieldName;
  278.                     }
  279.                 }
  280.             }
  281.         }
  282.         $this->logger->info('after inputDTO', [(array)$inputDTO]);
  283.         $this->transformDataHelper->transform($inputDTO$properties);
  284.         $errors $this->validator->validate($inputDTO);
  285.         if (count($errors) > 0) {
  286.             $messages = [];
  287.             /** @var ConstraintViolation $error */
  288.             foreach ($errors as $error) {
  289.                 $messages[$error->getPropertyPath()] = $error->getMessage();
  290.             }
  291.             $this->logger->info('bad inputs', [$serviceName$messages]);
  292.             throw new BadRequestException(
  293.                 BadRequestException::WRONG_INPUT,
  294.                 null,
  295.                 $serviceName,
  296.                 null,
  297.                 $messages
  298.             );
  299.         }
  300.         return $inputDTO;
  301.     }
  302.     public function objectToEntity(
  303.         $object,
  304.         $entityName,
  305.         $entity null,
  306.         $includeRelations false
  307.     ) {
  308.         if (is_null($entity)) {
  309.             $entityClass 'App\\Entity\\' $entityName;
  310.             $entity = new $entityClass();
  311.         }
  312.         $metadata $this->getEntityManager()->getClassMetadata('App\\Entity\\' $entityName);
  313.         $typeMap = [];
  314.         foreach ($metadata->fieldMappings as $fieldData) {
  315.             $typeMap[$fieldData['fieldName']] = $fieldData['type'];
  316.         }
  317.         if ($includeRelations) {
  318.             foreach ($metadata->associationMappings as $associationMapping) {
  319.                 $typeMap[$associationMapping['fieldName']] = $associationMapping['type'];
  320.             }
  321.         }
  322.         $this->logger->info('object data', (array) $object);
  323.         $this->logger->info('typeMap', (array) $typeMap);
  324.         foreach ($object as $key => $value) {
  325.             if (is_null($value)) {
  326.                 continue;
  327.             }
  328.             if (
  329.                 isset($typeMap[$key])
  330.                 && ($typeMap[$key] == ClassMetadataInfo::MANY_TO_MANY
  331.                     || $typeMap[$key] == ClassMetadataInfo::ONE_TO_MANY
  332.                 )
  333.             ) {
  334.                 $singularizedKey null;
  335.                 $words preg_split('#([A-Z][^A-Z]*)#'ucwords($key), nullPREG_SPLIT_DELIM_CAPTURE PREG_SPLIT_NO_EMPTY);
  336.                 $lastUpperCaseWord $words[count($words) - 1];
  337.                 $lastUpperCaseWordSingle $this->commonService->singularize($lastUpperCaseWord);
  338.                 $singularizedKey str_replace($lastUpperCaseWord''ucwords($key)) . $lastUpperCaseWordSingle;
  339.                 if (!method_exists($entity'add' $singularizedKey)) {
  340.                     continue;
  341.                 }
  342.                 $oldRelations $entity->{'get' ucwords($key)}();
  343.                 $newRelations $value;
  344.                 $currentRelationIdList = [];
  345.                 foreach ($oldRelations as $oldRelation) {
  346.                     foreach ($newRelations as $newRelation) {
  347.                         if ($newRelation->getId() == $oldRelation->getId()) {
  348.                             $currentRelationIdList[] = $oldRelation->getId();
  349.                             continue 2;
  350.                         }
  351.                     }
  352.                     $entity->{'remove' $singularizedKey}($oldRelation);
  353.                 }
  354.                 foreach ($newRelations as $newRelation) {
  355.                     if ($newRelation->getId()) {
  356.                         foreach ($oldRelations as $oldRelation) {
  357.                             if (in_array($newRelation->getId(), $currentRelationIdList)) {
  358.                                 continue 2;
  359.                             }
  360.                         }
  361.                     }
  362.                     $entity->{'add' $singularizedKey}($newRelation);
  363.                 }
  364.                 continue;
  365.             }
  366.             if (!method_exists($entity'set' ucwords($key))) {
  367.                 continue;
  368.             }
  369.             if (
  370.                 isset($typeMap[$key])
  371.                 && ($typeMap[$key] == 'integer'
  372.                     || $typeMap[$key] == 'float'
  373.                     || $typeMap[$key] == 'smallint'
  374.                 )
  375.                 && $value === ''
  376.             ) {
  377.                 $entity->{'set' ucwords($key)}(null);
  378.                 continue;
  379.             }
  380.             // merge json update here
  381.             if (
  382.                 isset($typeMap[$key])
  383.                 && $typeMap[$key] === 'json'
  384.             ) {
  385.                 if ($value === 'isNull') {
  386.                     $entity->{'set' ucwords($key)}(null);
  387.                     continue;
  388.                 }
  389.                 $currentValue $entity->{'get' ucwords($key)}();
  390.                 if ($value && is_array($value)) {
  391.                     foreach ($value as $property => $v) {
  392.                         $currentValue[$property] = $v;
  393.                     }
  394.                     $entity->{'set' ucwords($key)}($currentValue);
  395.                 }
  396.                 continue;
  397.             }
  398.             if ($value === 'isNull') {
  399.                 $entity->{'set' ucwords($key)}(null);
  400.                 continue;
  401.             }
  402.             $entity->{'set' ucwords($key)}($value);
  403.         }
  404.         return $entity;
  405.     }
  406.     public function get($id$lock false)
  407.     {
  408.         $entity $this->repository->find($id$lock LockMode::OPTIMISTIC null);
  409.         if (!$entity) {
  410.             $serviceName $this->commonService->getClassName($thistrue);
  411.             throw new BadRequestException(
  412.                 BadRequestException::NO_ENTITY,
  413.                 null,
  414.                 $serviceName,
  415.                 $id
  416.             );
  417.         }
  418.         return $entity;
  419.     }
  420.     public function __get($propertyName)
  421.     {
  422.         preg_match('/([a-zA-Z0-9]+)Service/i'$propertyName$serviceMatches);
  423.         if (count($serviceMatches) > 0) {
  424.             return $this
  425.                 ->serviceLocator
  426.                 ->get('App\Service\\' ucfirst($serviceMatches[1]) . 'Service');
  427.         }
  428.         preg_match('/([a-zA-Z0-9]+)Repo/i'$propertyName$repositoryMatches);
  429.         if (count($repositoryMatches) > 0) {
  430.             return $this
  431.                 ->serviceLocator
  432.                 ->get('App\Service\\' ucfirst($repositoryMatches[1]) . 'Service')
  433.                 ->repository;
  434.         }
  435.         $entityName $this->commonService->getClassName($thistrue);
  436.         $cacheKey 'Const.' $entityName '.' $propertyName;
  437.         $cachedConstantItem $this->cache->getItem($cacheKey);
  438.         if ($cachedConstantItem->isHit()) {
  439.             return $cachedConstantItem->get();
  440.         }
  441.         $constant null;
  442.         if(defined('App\Entity\\' $entityName '::' $propertyName)) {
  443.             $constant constant('App\Entity\\' $entityName '::' $propertyName);
  444.         }
  445.         if (!is_null($constant)) {
  446.             $cachedConstantItem->set($constant);
  447.             $this->cache->save($cachedConstantItem);
  448.             return $constant;
  449.         }
  450.         $metas $this->entityManager->getMetadataFactory()->getAllMetadata();
  451.         foreach ($metas as $meta) {
  452.             $classPath $meta->getName();
  453.             $name strtoupper($this->commonService->toSnakeCase(str_replace('App\Entity\\'''$classPath)));
  454.             preg_match('/(' $name ')_(.+)/i'$propertyName$matches);
  455.             if (count($matches) > 0) {
  456.                 $prop $matches[2];
  457.                 if(defined($classPath '::' $prop)) {
  458.                     $constant = @constant($classPath '::' $prop);
  459.                 }
  460.                 if (!is_null($constant)) {
  461.                     $cachedConstantItem->set($constant);
  462.                     $this->cache->save($cachedConstantItem);
  463.                     return $constant;
  464.                 }
  465.             }
  466.         }
  467.         trigger_error('Could not found property ' $propertyName ' in ' $this->commonService->getClassName($this), E_USER_ERROR);
  468.     }
  469.     public function newEntity()
  470.     {
  471.         $entityName $this->commonService->getClassName($thistrue);
  472.         $entityClass 'App\\Entity\\' $entityName;
  473.         return new $entityClass();
  474.     }
  475.     public function getToken()
  476.     {
  477.         $token $this->tokenStorage->getToken();
  478.         if (is_null($token) || $token->getUser() === 'anon.') return null;
  479.         return $token;
  480.     }
  481.     public function getUser()
  482.     {
  483.         $token $this->getToken();
  484.         if (is_null($token)) return null;
  485.         return $token->getUser();
  486.     }
  487.     public function isLoggedIn()
  488.     {
  489.         return $this->getUser();
  490.     }
  491.     public function getClassProperties($className)
  492.     {
  493.         $reflectionClass = new \ReflectionClass($className);
  494.         $properties = [];
  495.         foreach ($reflectionClass->getProperties() as $property) {
  496.             $properties[] = $property->getName();
  497.         }
  498.         return $properties;
  499.     }
  500.     public function getClassData($className)
  501.     {
  502.         $reader = new AnnotationReader();
  503.         $reflectionClass = new \ReflectionClass($className);
  504.         $data = [
  505.             'properties'           => [],
  506.             'transformAnnotations' => []
  507.         ];
  508.         foreach ($reflectionClass->getProperties() as $property) {
  509.             $data['properties'][] = $property;
  510.             /** @var TransformAnnotation $transformAnnotation */
  511.             $transformAnnotation $reader->getPropertyAnnotation($propertyTransformAnnotation::class);
  512.             if (!$transformAnnotation) {
  513.                 continue;
  514.             }
  515.             $data['transformAnnotations'][$property->getName()] = $transformAnnotation;
  516.         }
  517.         return $data;
  518.     }
  519.     public function getRootDir()
  520.     {
  521.         return $this->params->get('kernel.project_dir');
  522.     }
  523.     public function getCollectionProp($collection$property 'Id')
  524.     {
  525.         $propertyList = [];
  526.         foreach ($collection as $entity) {
  527.             $propertyList[] = $entity->{'get' $property}();
  528.         }
  529.         return $propertyList;
  530.     }
  531.     /**
  532.      * Check user is a super admin
  533.      *
  534.      * @param $user
  535.      * @return bool
  536.      */
  537.     public function isSuperAdmin($user)
  538.     {
  539.         foreach ($user->getSubRoles() as $role) {
  540.             if ($role->getId() == User::ROLE_ADMINISTRATOR_SUPER) {
  541.                 return true;
  542.             }
  543.         }
  544.         return false;
  545.     }
  546.     /**
  547.      * Check user is a admin
  548.      *
  549.      * @param $user
  550.      * @return bool
  551.      */
  552.     public function isAdmin($user)
  553.     {
  554.         foreach ($user->getSubRoles() as $role) {
  555.             if ($role->getId() == User::ROLE_USER) {
  556.                 return false;
  557.             }
  558.         }
  559.         return true;
  560.     }
  561.     public function isClient($user)
  562.     {
  563.         foreach ($user->getSubRoles() as $role) {
  564.             if ($role->getId() == User::ROLE_CLIENT) {
  565.                 return true;
  566.             }
  567.         }
  568.         return false;
  569.     }
  570.     public function sendMail(array|string $recipients = [], string $subjectstring $contentstring $from nullstring $type 'html')
  571.     {
  572.         $email = (new Email())
  573.                 ->subject($subject)
  574.                 ->{$type}($content);
  575.         
  576.         $email->from(
  577.             new Address(
  578.                 !is_null($from) ? $from['address'] : $this->params->get('mail.no_reply.from_address'), 
  579.                 !is_null($from) ? $from['name'] : $this->params->get('mail.no_reply.from_name')
  580.             )
  581.         );
  582.         if(is_string($recipients)) {
  583.             $recipients = [$recipients];
  584.         }
  585.         foreach ($recipients as $recipient) {
  586.             try {
  587.                 $email->to($recipient);
  588.                 $this->mailer->send($email);
  589.             } catch(RfcComplianceException $ex) {
  590.                 
  591.             } catch(\Exception $ex) {
  592.                 $this
  593.                 ->requestService
  594.                 ->saveLog(
  595.                     500,
  596.                     $email->getTo()[0]->getAddress() . $ex->getMessage(),
  597.                     null,
  598.                     true
  599.                 );
  600.             }
  601.         }
  602.         return true;
  603.     }
  604.     public function flatening($entity)
  605.     {
  606.         $flatEntity = [];
  607.         $entityName $this->commonService->getClassName($entity);
  608.         $metadata $this->getEntityManager()->getClassMetadata('App\\Entity\\' $entityName);
  609.         foreach ($metadata->fieldMappings as $fieldName => $fieldData) {
  610.             $value $entity->{'get' .  ucwords($fieldName)}();
  611.             if ($fieldData['type'] === 'datetime') {
  612.                 if (!is_null($value)) {
  613.                     $flatEntity[$fieldName] = $value->format('Y-m-d H:i:s');
  614.                 } else {
  615.                     $flatEntity[$fieldName] = null;
  616.                 }
  617.             } else {
  618.                 $flatEntity[$fieldName] = $value;
  619.             }
  620.         }
  621.         foreach ($metadata->associationMappings as $fieldName => $associationMapping) {
  622.             $value $entity->{'get' .  ucwords($fieldName)}();
  623.             if ($associationMapping['type'] === ClassMetadataInfo::MANY_TO_ONE) {
  624.                 $flatEntity[$fieldName] = is_null($value) ? $value $value->getId();
  625.             }
  626.             if (
  627.                 $associationMapping['type'] === ClassMetadataInfo::MANY_TO_MANY
  628.                 || $associationMapping['type'] === ClassMetadataInfo::ONE_TO_MANY
  629.             ) {
  630.                 $idList = [];
  631.                 foreach ($value as $associateEntity) {
  632.                     $idList[] = $associateEntity->getId();
  633.                 }
  634.                 $flatEntity[$fieldName] = $idList;
  635.             }
  636.         }
  637.         return $flatEntity;
  638.     }
  639.     public function uploadPhotosContent($request)
  640.     {
  641.         $uploadPath $this->container->getParameter('dir.photo_content');
  642.         $fileUpload $request->files->get('upload');
  643.         if (!$fileUpload) {
  644.             throw new \Exception('File upload is required');
  645.         }
  646.         $newMedia $this->mediaService->uploadFile($fileUpload$uploadPath);
  647.         
  648.         return [
  649.             'file_name' => $newMedia['name'],
  650.             'uploaded' => 1,
  651.             'url' => $this->uploadsStorage->publicUrl($newMedia['path'])
  652.         ];
  653.     }
  654.     public function getYoutubeUrl($url)
  655.     {
  656.         $shortUrlRegex '/youtu.be\/([a-zA-Z0-9_-]+)\??/i';
  657.         $longUrlRegex '/youtube.com\/((?:embed)|(?:watch))((?:\?v\=)|(?:\/))([a-zA-Z0-9_-]+)/i';
  658.         $youtube_id null;
  659.         if (preg_match($longUrlRegex$url$matches)) {
  660.             $youtube_id $matches[count($matches) - 1];
  661.         }
  662.         if (preg_match($shortUrlRegex$url$matches)) {
  663.             $youtube_id $matches[count($matches) - 1];
  664.         }
  665.         if ($youtube_id) {
  666.             return 'https://www.youtube.com/watch?v=' $youtube_id;
  667.         }
  668.         return $youtube_id;
  669.     }
  670.     public function formatDate($datetime$locale null$timezone null)
  671.     {
  672.         if ($locale == 'fr' || $locale == null) {
  673.             $formatter = new \IntlDateFormatter('fr_FR'\IntlDateFormatter::FULL\IntlDateFormatter::NONE$timezone $timezone 'Europe/Paris');
  674.         } elseif ($locale == 'en') {
  675.             $formatter = new \IntlDateFormatter('en_GB'\IntlDateFormatter::FULL\IntlDateFormatter::NONE$timezone $timezone 'Europe/Paris');
  676.         }
  677.         return $formatter->format($datetime);
  678.     }
  679. }