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