<?php declare(strict_types=1);
namespace Acris\ProductVideo\Storefront\Subscriber;
use Acris\ProductVideo\Custom\ProductVideoEntity;
use Shopware\Core\Content\Media\MediaCollection;
use Shopware\Core\Content\Product\Aggregate\ProductMedia\ProductMediaCollection;
use Shopware\Core\Content\Product\Aggregate\ProductMedia\ProductMediaEntity;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\Struct\ArrayEntity;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductPageSubscriber implements EventSubscriberInterface
{
/**
* @var SystemConfigService
*/
private $systemConfigService;
public function __construct(SystemConfigService $systemConfigService)
{
$this->systemConfigService = $systemConfigService;
}
public static function getSubscribedEvents(): array
{
return [
ProductPageCriteriaEvent::class => 'onProductCriteriaLoaded',
ProductPageLoadedEvent::class => 'onProductPageLoaded'
];
}
public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
if($event->getPage()->getProduct()->hasExtension('acrisVideos') !== true) {
return;
}
$urlMetaData = [];
/** @var ProductVideoEntity $element */
foreach ($event->getPage()->getProduct()->getExtension('acrisVideos')->getElements() as $element)
{
if ($element && !empty($element->getTranslated()) && array_key_exists('link', $element->getTranslated()) && !empty($element->getTranslated()['link'])) {
$link = $element->getTranslated()['link'];
$videoId = explode('/', $link);
$videoId = end($videoId);
$urlData = $this->createYoutubeWatchUrl($videoId);
$urlMetaData[$element->getId()] = $urlData;
}
}
if (!empty($urlMetaData)) {
$event->getPage()->addExtension('acrisProductVideo', new ArrayEntity([
'metaData' => $urlMetaData
]));
}
// add first product to product slider
/** @var ProductVideoEntity $element */
foreach ($event->getPage()->getProduct()->getExtension('acrisVideos')->getElements() as $key => $element)
{
$productMedia = new ProductMediaEntity();
$productMedia->setMedia($element);
$productMedia->setUniqueIdentifier($element->getId());
$mediaCollection = $event->getPage()->getProduct()->getMedia();
if (empty($mediaCollection)) $mediaCollection = new ProductMediaCollection();
if($mediaCollection->count() > 1) {
if ($this->systemConfigService->get('AcrisProductVideoCS.config.displayPosition', $event->getSalesChannelContext()->getSalesChannel()->getId()) === 'first') {
$mediaCollection->insert(0, $productMedia);
} elseif ($this->systemConfigService->get('AcrisProductVideoCS.config.displayPosition', $event->getSalesChannelContext()->getSalesChannel()->getId()) === 'second') {
$mediaCollection->insert(1, $productMedia);
} elseif ($this->systemConfigService->get('AcrisProductVideoCS.config.displayPosition', $event->getSalesChannelContext()->getSalesChannel()->getId()) === 'last') {
$mediaCollection->add($productMedia);
}
} else {
if ($this->systemConfigService->get('AcrisProductVideoCS.config.displayPosition', $event->getSalesChannelContext()->getSalesChannel()->getId()) === 'first') {
$mediaCollection->insert(0, $productMedia);
} elseif($this->systemConfigService->get('AcrisProductVideoCS.config.displayPosition', $event->getSalesChannelContext()->getSalesChannel()->getId()) !== 'noDisplay') {
$mediaCollection->add($productMedia);
}
}
if($this->systemConfigService->get('AcrisProductVideoCS.config.displayAllVideosInImageSlider', $event->getSalesChannelContext()->getSalesChannel()->getId()) !== true) {
break;
}
}
}
public function onProductCriteriaLoaded(ProductPageCriteriaEvent $event): void
{
if(empty($event->getSalesChannelContext()->getSalesChannel())) {
return;
}
$sorting = $this->getVideoSorting($event->getSalesChannelContext()->getSalesChannel()->getId());
$event->getCriteria()->addAssociation('acrisVideos');
$event->getCriteria()->getAssociation('acrisVideos')->addSorting(new FieldSorting('priority', $sorting, true));
}
private function getVideoSorting(string $salesChannelId): string
{
if($this->systemConfigService->get('AcrisProductVideoCS.config.highestPriorityFirst', $salesChannelId) === true) {
return FieldSorting::DESCENDING;
} else {
return FieldSorting::ASCENDING;
}
}
public function createYoutubeWatchUrl($videoId)
{
$url = 'https://www.youtube.com/watch?v='.$videoId;
$urlData = $this->getYoutubeMetaData($url);
$metaDescription = get_meta_tags($url);
if (!empty($urlData) && !empty($metaDescription) && array_key_exists('description', $metaDescription)) {
$urlData['description'] = $metaDescription['description'];
}
return $urlData;
}
public function getYoutubeMetaData($url){
$youtube = "https://www.youtube.com/oembed?url=". $url ."&format=json";
$curl = curl_init($youtube);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($curl);
curl_close($curl);
return json_decode($return, true);
}
}