<?php
namespace WAM\Bundle\RoutingBundle\Enhancer;
use Doctrine\Persistence\ObjectManager;
use Sonata\SeoBundle\Seo\SeoPageInterface;
use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request;
use WAM\Bundle\RoutingBundle\Entity\Interfaces\SeoMetaInterface;
use WAM\Bundle\RoutingBundle\Entity\Interfaces\SeoMetaReadInterface;
use WAM\Bundle\RoutingBundle\Entity\Interfaces\SeoMetaWriteInterface;
use WAM\Bundle\RoutingBundle\Sitemap\Interfaces\AlternatesGeneratorInterface;
/**
* This enhancer inject seo data from Router SeoMetaData field to Sonata SeoPage.
*
* @author Miguel Vilata <mvilata@wearemarketing.com>
*/
class SeoContentRouteEnhancer implements RouteEnhancerInterface
{
protected SeoPageInterface $seoPage;
protected AlternatesGeneratorInterface $alternateRoutesGenerator;
protected ObjectManager $om;
/**
* @param SeoPageInterface $seoPage
* @param AlternatesGeneratorInterface $alternateRoutesGenerator
*/
public function __construct(SeoPageInterface $seoPage, AlternatesGeneratorInterface $alternateRoutesGenerator, ObjectManager $om)
{
$this->seoPage = $seoPage;
$this->alternateRoutesGenerator = $alternateRoutesGenerator;
$this->om = $om;
}
/**
* Return seo data present in route object and update it if neccesary
* from content object attached.
*
* @param array $defaults
* @param Request $request
*
* @return array
*/
public function enhance(array $defaults, Request $request)
{
$routeObject = $defaults[RouteObjectInterface::ROUTE_OBJECT];
$contentObject = $routeObject->getContent();
if ($contentObject instanceof SeoMetaReadInterface && $routeObject instanceof SeoMetaWriteInterface) {
$this->updateRouteSeoIfEmpty($contentObject, $routeObject);
}
if ($routeObject instanceof SeoMetaReadInterface) {
$this->updateSeoPage($routeObject);
}
// Set alternate routes
foreach ($this->getAlternateRoutes($routeObject) as $alternateRoute) {
$this->seoPage->addLangAlternate($alternateRoute['url'], $alternateRoute['hreflang']);
}
return $defaults;
}
/**
* @param SeoMetaReadInterface $contentObject
* @param SeoMetaWriteInterface $routeObject
*/
private function updateRouteSeoIfEmpty(SeoMetaReadInterface $contentObject, SeoMetaWriteInterface $routeObject)
{
$contentObjectSeoMetaData = [
SeoMetaInterface::SEO_META_TITLE => $contentObject->getSeoTitle(),
SeoMetaInterface::SEO_META_DESCRIPTION => $contentObject->getSeoDescription(),
];
$routeSeoMetaData = $routeObject->getSeoMetaData();
$isMetadataUpdated = $contentObjectSeoMetaData == $routeSeoMetaData;
if ($isMetadataUpdated && ($routeObject->setSeoMetaDataIfEmpty($contentObjectSeoMetaData))) {
$this->om->persist(($routeObject));
$this->om->flush();
}
}
/**
* @param SeoMetaReadInterface $object
*/
private function updateSeoPage(SeoMetaReadInterface $object)
{
$this->seoPage
->setTitle($object->getSeoTitle())
->addMeta('name', 'description', $object->getSeoDescription());
if ($object->hasSeoMetaRobots()) {
$this->seoPage->addMeta('name', 'robots', $object->getSeoMetaRobots());
}
}
/**
* @param $routeObject
*
* @return mixed
*/
private function getAlternateRoutes($routeObject)
{
return $this->alternateRoutesGenerator->getAlternateRoutes($routeObject);
}
}