src/Util/Seo.php line 107

Open in your IDE?
  1. <?php
  2. namespace App\Util;
  3. use App\Annotations\Seo\Meta;
  4. use App\Entity\Asset;
  5. use App\Entity\MetaTemplates;
  6. use App\Entity\OgImage;
  7. use App\Entity\OpenGraphInterface;
  8. use App\Entity\Page;
  9. use App\Model\Seo\SerializationContext;
  10. use DateTimeInterface;
  11. use Doctrine\Common\Annotations\AnnotationReader;
  12. use Leogout\Bundle\SeoBundle\Provider\SeoGeneratorProvider;
  13. use Liip\ImagineBundle\Imagine\Cache\CacheManager;
  14. use ReflectionClass;
  15. use ReflectionException;
  16. use ReflectionProperty;
  17. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use Symfony\Component\HttpFoundation\RequestStack;
  20. use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
  21. class Seo
  22. {
  23.     /**
  24.      * @var SeoGeneratorProvider
  25.      */
  26.     protected $seoGenerator;
  27.     /**
  28.      * @var CacheManager
  29.      */
  30.     protected $cacheManager;
  31.     /**
  32.      * @var UploaderHelper
  33.      */
  34.     protected $uploaderHelper;
  35.     /**
  36.      * @var Request
  37.      */
  38.     protected $request;
  39.     /**
  40.      * @var ParameterBagInterface
  41.      */
  42.     private $parameterBag;
  43.     /**
  44.      * Seo constructor.
  45.      */
  46.     public function __construct(
  47.         SeoGeneratorProvider $seoGenerator,
  48.         CacheManager $cacheManager,
  49.         UploaderHelper $uploaderHelper,
  50.         RequestStack $requestStack,
  51.         ParameterBagInterface $parameterBag
  52.     ) {
  53.         $this->seoGenerator $seoGenerator;
  54.         $this->cacheManager $cacheManager;
  55.         $this->uploaderHelper $uploaderHelper;
  56.         $this->request $requestStack->getCurrentRequest();
  57.         $this->parameterBag $parameterBag;
  58.     }
  59.     public function setSeoInformationForPage(array $metaDataPage $page, ?OgImage $defaultOgImage)
  60.     {
  61.         $pageTitle $metaData['metaTitle'] ?? null;
  62.         if (!$pageTitle) {
  63.             $pageTitle $page->getMetaTitle();
  64.         }
  65.         if (!$pageTitle) {
  66.             $pageTitle $page->getTitle();
  67.         }
  68.         $ogImage = !empty($metaData['ogImage']) ? $metaData['ogImage'] : null;
  69.         if (\is_object($ogImage) && (is_subclass_of($ogImageAsset::class) || Asset::class === \get_class($ogImage))) {
  70.             /** @var Asset $ogImageAsset */
  71.             $ogImageAsset $metaData['ogImage'];
  72.             $ogImageAssetPath $this->uploaderHelper->asset($ogImageAsset'assetFile');
  73.             if ($ogImageAssetPath) {
  74.                 $ogImage $this->cacheManager->getBrowserPath(
  75.                     $this->uploaderHelper->asset($ogImageAsset'assetFile'),
  76.                     'w1200'
  77.                 );
  78.             }
  79.         }
  80.         if (empty($ogImage)) {
  81.             if ($defaultOgImage instanceof OgImage &&
  82.                 $defaultOgImage->getImage() instanceof Asset &&
  83.                 null !== $defaultOgImage->getImage()->getFileName()) {
  84.                 $ogImage $this->cacheManager->getBrowserPath(
  85.                     $this->uploaderHelper->asset($defaultOgImage->getImage(), 'assetFile'),
  86.                     'w1200'
  87.                 );
  88.             }
  89.         }
  90.         $this->seoGenerator->get('gn_og')
  91.             ->setTitle(sprintf('%s | %s'$pageTitle$this->parameterBag->get('site_company_name')))
  92.             ->setDescription(
  93.                 strip_tags(!empty($metaData['metaDescription']) ? $metaData['metaDescription'] : $page->getMetaDescription())
  94.             )
  95.             ->setUrl($this->request->getUri())
  96.             ->setImageWithSize(\is_string($ogImage) ? $ogImage '')
  97.             ->setType('website')
  98.         ;
  99.     }
  100.     /**
  101.      * @return string|null
  102.      */
  103.     public function renderOgImage(OgImage $ogImage, ?object $object)
  104.     {
  105.         $getter 'get'.$ogImage->getField();
  106.         if (!method_exists($object$getter)) {
  107.             return $this->cacheManager->getBrowserPath(
  108.                 $this->uploaderHelper
  109.                     ->asset($ogImage->getImage(), 'assetFile'),
  110.                 'w1200'
  111.             );
  112.         }
  113.         $options = [
  114.             'text' => $object->{$getter}(),
  115.         ];
  116.         if ($ogImage->getTextSize()) {
  117.             $options['text_size'] = $ogImage->getTextSize();
  118.         }
  119.         if ($ogImage->getTextColor()) {
  120.             $options['text_color'] = $ogImage->getTextColor();
  121.         }
  122.         if ($ogImage->getTextPosition()) {
  123.             $options['position'] = $ogImage->getTextPosition();
  124.         }
  125.         return $this->cacheManager->getBrowserPath(
  126.             $this->uploaderHelper
  127.                 ->asset($ogImage->getImage(), 'assetFile'),
  128.             'text_overlay',
  129.             ['text_overlay' => $options]
  130.         );
  131.     }
  132.     /**
  133.      * @param OpenGraphInterface $entity
  134.      *
  135.      * @return array
  136.      */
  137.     public function extractMetaData(MetaTemplates $templatesobject $entity)
  138.     {
  139.         $context = new SerializationContext();
  140.         if (null !== $templates->getDateFormat()) {
  141.             $context->dateFormat $templates->getDateFormat();
  142.         }
  143.         $values $this->calculateFieldValues(
  144.             $entity,
  145.             $context
  146.         );
  147.         $callback = function ($result) use ($values) {
  148.             if (isset($result[1])) {
  149.                 $key trim($result[1]);
  150.                 return !empty($values[$key]) ? $values[$key] : '';
  151.             }
  152.             return '';
  153.         };
  154.         $regex '/\{{([a-zA-Z0-9\s_-]+?)\}}/';
  155.         $metaTitle preg_replace_callback(
  156.             $regex,
  157.             $callback,
  158.             $templates->getTitleTemplate()
  159.         );
  160.         $metaDescription preg_replace_callback(
  161.             $regex,
  162.             $callback,
  163.             $templates->getDescriptionTemplate()
  164.         );
  165.         return [$metaTitle$metaDescription];
  166.     }
  167.     public function calculateFields(string $objectClass): array
  168.     {
  169.         $fields = [];
  170.         /** @var ReflectionProperty $reflectionProperty */
  171.         foreach ($this->getMetaProperties($objectClass) as $reflectionProperty) {
  172.             /** @var Meta $annotation */
  173.             $fieldName $reflectionProperty->getName();
  174.             if (!empty($annotation->name)) {
  175.                 $fieldName $annotation->name;
  176.             }
  177.             $fields[] = $fieldName;
  178.         }
  179.         return $fields;
  180.     }
  181.     private function calculateFieldValues(object $entitySerializationContext $context): array
  182.     {
  183.         $reader = new AnnotationReader();
  184.         $fields = [];
  185.         /** @var ReflectionProperty $metaProperty */
  186.         foreach ($this->getMetaProperties(\get_class($entity)) as $metaProperty) {
  187.             /** @var Meta $annotation */
  188.             $annotation $reader->getPropertyAnnotation($metaPropertyMeta::class);
  189.             $propertyGetter 'get'.$metaProperty->getName();
  190.             if ($entity->$propertyGetter() instanceof DateTimeInterface) {
  191.                 $fields[$metaProperty->getName()] = $entity->$propertyGetter()->format($context->dateFormat);
  192.             } else {
  193.                 $fields[$metaProperty->getName()] = (string) $entity->$propertyGetter();
  194.             }
  195.             if ($annotation->supersededBy) {
  196.                 $getter 'get'.$annotation->supersededBy;
  197.                 if (!method_exists($entity$getter)) {
  198.                     throw new \RuntimeException(sprintf('Function %s for superseding property %s must exist'$getter$annotation->supersededBy));
  199.                 }
  200.                 $supersededValue $entity->$getter();
  201.                 if (!empty($supersededValue)) {
  202.                     $fields[$metaProperty->getName()] = $supersededValue;
  203.                 }
  204.             }
  205.             if ($annotation->name) {
  206.                 $fields[$annotation->name] = $fields[$metaProperty->getName()];
  207.             }
  208.         }
  209.         return $fields;
  210.     }
  211.     private function getMetaProperties(string $objectClass): array
  212.     {
  213.         $reader = new AnnotationReader();
  214.         try {
  215.             $reflectionClass = new ReflectionClass($objectClass);
  216.         } catch (ReflectionException $e) {
  217.             return [];
  218.         }
  219.         $properties = [];
  220.         foreach ($reflectionClass->getProperties() as $reflectionProperty) {
  221.             $annotation $reader->getPropertyAnnotation($reflectionPropertyMeta::class);
  222.             if (!$annotation) {
  223.                 continue;
  224.             }
  225.             $properties[] = $reflectionProperty;
  226.         }
  227.         return $properties;
  228.     }
  229. }