src/Misc/TransformDataHelper.php line 26

Open in your IDE?
  1. <?php
  2. namespace App\Misc;
  3. use App\Exception\BadRequestException;
  4. use App\Annotation\TransformAnnotation;
  5. use AutoMapperPlus\AutoMapperInterface;
  6. use Doctrine\ORM\EntityManagerInterface;
  7. use League\Flysystem\FilesystemOperator;
  8. use Doctrine\Common\Annotations\AnnotationReader;
  9. use Symfony\Component\HttpFoundation\File\UploadedFile;
  10. class TransformDataHelper
  11. {
  12.     /**
  13.      * @var EntityManagerInterface
  14.      */
  15.     private $entityManager;
  16.     /**
  17.      * @var AutoMapperInterface
  18.      */
  19.     private $autoMapper;
  20.     public function __construct(
  21.         EntityManagerInterface $entityManager,
  22.         AutoMapperInterface $autoMapper,
  23.         \Psr\Container\ContainerInterface $serviceLocator,
  24.         private FilesystemOperator $uploadsStorage
  25.     ) {
  26.         $this->entityManager $entityManager;
  27.         $this->autoMapper $autoMapper;
  28.         $this->serviceLocator $serviceLocator;
  29.     }
  30.     public function transform($object$inputProperties)
  31.     {
  32.         $reflectionClass = new \ReflectionClass(get_class($object));
  33.         $properties $reflectionClass->getProperties();
  34.         $reader = new AnnotationReader();
  35.         foreach ($properties as $property) {
  36.             // @todo: check property readable
  37.             $propertyName $property->getName();
  38.             $propertyValue $object->{$propertyName};
  39.             /*
  40.             if(!in_array($propertyName, $inputProperties)) {
  41.                 unset($object->{$propertyName});
  42.                 continue;
  43.             }
  44.             */
  45.             /** @var TransformAnnotation $transformAnnotation */
  46.             $transformAnnotation $reader->getPropertyAnnotation($propertyTransformAnnotation::class);
  47.             if (!$transformAnnotation) {
  48.                 continue;
  49.             }
  50.             $newValue $this->transformValue(
  51.                 $propertyValue,
  52.                 $transformAnnotation,
  53.                 $object
  54.             );
  55.             $object->{$propertyName} = $newValue;
  56.         }
  57.     }
  58.     private function transformValue($valueTransformAnnotation $annotation$object null)
  59.     {
  60.         switch ($annotation->type) {
  61.             case 'int':
  62.             case 'integer':
  63.                 return (int)$value;
  64.             case 'string':
  65.                 return (string) is_array($value) ? 'yes' $value;
  66.             case 'bool':
  67.             case 'boolean':
  68.                 return filter_var($valueFILTER_VALIDATE_BOOLEAN);
  69.             case 'datetime':
  70.                 if ($annotation->keepTimezone) return new \DateTime($value);
  71.                 return is_null($value) ? null $this->castDateTimeToEntity($value);
  72.             case 'date':
  73.                 if ($annotation->format)
  74.                     return $value == '' null \DateTime::createFromFormat(
  75.                         'Y-m-d',
  76.                         date("Y-m-d"strtotime(str_replace('/''-'$value)))
  77.                     );
  78.                 return $value == '' null \DateTime::createFromFormat('Y-m-d'date("Y-m-d"strtotime($value)));
  79.             case 'time':
  80.                 return $value == '' null \DateTime::createFromFormat('H:i:s'$value);
  81.             case 'float':
  82.                 return (float) $value;
  83.             case 'strip_tags':
  84.                 // 9 is directory interview
  85.                 // 8 is discussion
  86.                 $isPost = isset($object->type) && ($object->type == || $object->type == 8);
  87.                 $isRichText = isset($annotation->isRichText) && $annotation->isRichText === 'true';
  88.                 $containsHTML $value != strip_tags($value);
  89.                 if (($isPost || $isRichText) && $containsHTML) {
  90.                     return $this->strip_tags_secured($value, [
  91.                         'a''p''strong''u',
  92.                         'h1''h2''h3',
  93.                         'ul''li''ol',
  94.                         'wrapquestion',
  95.                         'question1''question2''question3',
  96.                         'question4''question5''question6',
  97.                         'question7''directorname''directorposition',
  98.                         'img''iframe'
  99.                     ]);
  100.                 } else {
  101.                     return strip_tags($value);
  102.                 }
  103.             case 'entity':
  104.                 return $this->castValueToEntity($value$annotation->class);
  105.             case 'entityEditable':
  106.                 return $this->castValueToEntityEditable($value$annotation);
  107.             case 'collectionEntity':
  108.                 return $this->castValueToCollectionEntity($value$annotation);
  109.             case 'collectionEntityEditable':
  110.                 return $this->castValueToCollectionEntityEditable($value$annotation);
  111.             case 'collectionObject':
  112.                 return $this->castValueToObject($value$annotation->class);
  113.             case 'imageBase64':
  114.                 return $this->caseValueToImgBase64($value);
  115.             case 'slug':
  116.                 return $this->setSlugToEntity($object$annotation);
  117.             case 'mediaEntity':
  118.                 return $this->castValueToMediaEntity($value$annotation->class);
  119.             case 'mediaCollectionEntity':
  120.                 return $this->castValueToMediaCollectionEntity($value$annotation);
  121.         }
  122.         return $value;
  123.     }
  124.     private function castValueToEntity($identifier$class)
  125.     {
  126.         if (!isset($identifier)) {
  127.             return null;
  128.         }
  129.         if ($identifier === 'isNull' || $identifier === '') {
  130.             return 'isNull';
  131.         }
  132.         if (is_numeric($identifier)) {
  133.             $identifier = (int) $identifier;
  134.         } else if (isset($identifier['id'])) {
  135.             $identifier $identifier['id'];
  136.         }
  137.         $repository $this->entityManager->getRepository($class);
  138.         $entity $repository->find($identifier);
  139.         if (is_null($entity)) {
  140.             $parts explode('\\'$class);
  141.             $entityName $parts[count($parts) - 1];
  142.             throw new BadRequestException(
  143.                 BadRequestException::NO_ENTITY,
  144.                 null,
  145.                 $entityName,
  146.                 $identifier
  147.             );
  148.         }
  149.         return $entity;
  150.     }
  151.     private function castValueToEntityEditable($value$annotation)
  152.     {
  153.         if (!is_array($value) || $value === '') {
  154.             return [];
  155.         }
  156.         $commonService $this->serviceLocator->get('App\Service\CommonService');
  157.         $serviceName $commonService->getClassName($annotation->classtrue);
  158.         $requestDTO 'App\DTO\\' $serviceName '\Add' $serviceName 'Input';
  159.         $service $this->serviceLocator->get('App\Service\\' $serviceName 'Service');
  160.         $service->logger->info('value', [$value]);
  161.         $entity null;
  162.         if (!empty($value['id'])) {
  163.             $entity $service->get($value['id']);
  164.         }
  165.         $object $service->inputResolver($value$requestDTOnull$serviceName);
  166.         $entity $service->objectToEntity($object$serviceName$entitytrue);
  167.         return $entity;
  168.     }
  169.     private function castValueToCollectionEntity($value$annotation)
  170.     {
  171.         if (!is_array($value) || $value === '') {
  172.             return [];
  173.         }
  174.         try {
  175.             $repository $this->entityManager->getRepository($annotation->class);
  176.             if (isset($annotation->field)) {
  177.                 $filter = [];
  178.                 $filter[$annotation->field] = $value;
  179.                 $entityCollection $repository->findBy($filter);
  180.             } else {
  181.                 $entityCollection $repository->findBy([
  182.                     'id' => $value
  183.                 ]);
  184.             }
  185.             return $entityCollection;
  186.         } catch (\Exception $exception) {
  187.             dd($exception->getMessage());
  188.         }
  189.         return $value;
  190.     }
  191.     private function castValueToCollectionEntityEditable($value$annotation)
  192.     {
  193.         if (!is_array($value) || $value === '') {
  194.             return [];
  195.         }
  196.         $commonService $this->serviceLocator->get('App\Service\CommonService');
  197.         $serviceName $commonService->getClassName($annotation->classtrue);
  198.         $requestDTO 'App\DTO\\' $serviceName '\Add' $serviceName 'Input';
  199.         $service $this->serviceLocator->get('App\Service\\' $serviceName 'Service');
  200.         $collection = [];
  201.         $service->logger->info('value', [$value]);
  202.         foreach ($value as $arrayData) {
  203.             $entity null;
  204.             if (!empty($arrayData['id'])) {
  205.                 $entity $service->get($arrayData['id']);
  206.             }
  207.             $object $service->inputResolver($arrayData$requestDTOnull$serviceName);
  208.             $entity $service->objectToEntity($object$serviceName$entitytrue);
  209.             $collection[] = $entity;
  210.         }
  211.         return $collection;
  212.     }
  213.     private function castValueToObject($value$class)
  214.     {
  215.         if (!class_exists($class)) {
  216.             return $value;
  217.         }
  218.         $newArr = [];
  219.         foreach ($value as $key => $attributes) {
  220.             $newArr[$key] = $this->autoMapper->map($attributes$class);
  221.         }
  222.         return $newArr;
  223.     }
  224.     private function caseValueToImgBase64($value)
  225.     {
  226.         if (!$value) {
  227.             return null;
  228.         }
  229.         $pureBase64 Base64FileExtractor::extractBase64String($value);
  230.         if (!$pureBase64) {
  231.             return null;
  232.         }
  233.         return new UploadedBase64File($pureBase64'image');
  234.     }
  235.     private function setSlugToEntity($object$annotation)
  236.     {
  237.         $field = isset($annotation->field) ? $annotation->field 'name';
  238.         $commonService $this->serviceLocator->get('App\Service\CommonService');
  239.         return $commonService->slugify($object->{$field});
  240.     }
  241.     function strip_tags_secured(
  242.         $html_str,
  243.         $allowed_tags = [],
  244.         $allowed_attrs = ['href''alt''src''frameborder''allowfullscreen']
  245.     ) {
  246.         $xml = new \DOMDocument();
  247.         //Suppress warnings: proper error handling is beyond scope of example
  248.         libxml_use_internal_errors(true);
  249.         if (!strlen($html_str)) {
  250.             return false;
  251.         }
  252.         $html_str mb_convert_encoding($html_str'HTML-ENTITIES'"UTF-8");
  253.         if ($xml->loadHTML($html_strLIBXML_HTML_NOIMPLIED LIBXML_HTML_NODEFDTD)) {
  254.             foreach ($xml->getElementsByTagName("*") as $tag) {
  255.                 if (!in_array($tag->tagName$allowed_tags)) {
  256.                     $tag->parentNode->removeChild($tag);
  257.                 } else {
  258.                     foreach ($tag->attributes as $attr) {
  259.                         if (!in_array($attr->nodeName$allowed_attrs)) {
  260.                             $tag->removeAttribute($attr->nodeName);
  261.                         }
  262.                     }
  263.                 }
  264.             }
  265.         }
  266.         return trim($xml->saveHTML());
  267.     }
  268.     public function castDateTimeToEntity($value)
  269.     {
  270.         if ($value === '' || $value === 'isNull') return 'isNull';
  271.         $requestService $this->serviceLocator->get('App\Service\RequestService');
  272.         $datetime = new \DateTime(str_replace('Z'''str_replace('T'' 'str_replace('/''-'$value))), new \DateTimeZone($requestService->timezone));
  273.         $datetime->setTimezone(new \DateTimeZone('UTC'));
  274.         return $datetime;
  275.     }
  276.     public function castValueToMediaEntity($file$class)
  277.     {
  278.         $mediaService $this->serviceLocator->get('App\Service\MediaService');
  279.         if ($file instanceof UploadedFile) {
  280.             $newFile $mediaService->uploadFile($file'media');
  281.             return $mediaService->add($newFilenullnull'ENTITY');
  282.         }
  283.         return $this->getEntityFromId($file$class);
  284.     }
  285.     private function castValueToMediaCollectionEntity($value$annotation)
  286.     {
  287.         if (!is_array($value) || $value === '') {
  288.             return [];
  289.         }
  290.         
  291.         $mediaService $this->serviceLocator->get('App\Service\MediaService');
  292.         $mediaService->logger->info('value', [$value]);
  293.         $collection = [];
  294.         foreach ($value as $file) {
  295.             if ($file instanceof UploadedFile) {
  296.                 $newFile $mediaService->uploadFile($file'media');
  297.                 $collection[] = $mediaService->add($newFilenullnull'ENTITY');
  298.             } else {
  299.                 $collection[] = $this->getEntityFromId($file$annotation->class);
  300.             }
  301.         }
  302.         return $collection;
  303.     }
  304.     public function getEntityFromId($identifier$class)
  305.     {
  306.         if (!isset($identifier)) {
  307.             return null;
  308.         }
  309.         if ($identifier === 'isNull' || $identifier === '') {
  310.             return 'isNull';
  311.         }
  312.         if (is_numeric($identifier)) {
  313.             $identifier = (int) $identifier;
  314.         } else if (isset($identifier['id'])) {
  315.             $identifier $identifier['id'];
  316.         }
  317.         $repository $this->entityManager->getRepository($class);
  318.         $entity $repository->find($identifier);
  319.         if (is_null($entity)) {
  320.             $parts explode('\\'$class);
  321.             $entityName $parts[count($parts) - 1];
  322.             throw new BadRequestException(
  323.                 BadRequestException::NO_ENTITY,
  324.                 null,
  325.                 $entityName,
  326.                 $identifier
  327.             );
  328.         }
  329.         return $entity;
  330.     }
  331. }