<?php
namespace App\Service\Bus\Publisher;
use App\Message\AVOMessage;
use App\Service\Bus\Publisher\Exception\AnalogueNotPublished;
use App\Service\Bus\Publisher\Exception\BrandNotPublished;
use App\Service\Bus\Publisher\Exception\BundleNotPublished;
use App\Service\Bus\Publisher\Exception\CategoryNotPublished;
use App\Service\Bus\Publisher\Exception\CollectionNotPublished;
use App\Service\Bus\Publisher\Exception\LabelNotPublished;
use App\Service\Enum\LanguageEnum;
use Carbon\Carbon;
use Exception;
use Pimcore\Model\DataObject\Category;
use Pimcore\Model\DataObject\Product;
use Pimcore\Model\DataObject\PropertyDescriptor;
use Pimcore\Tool;
use Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpStamp;
class ProductPublisher extends BasePublisher
{
/**
* @param object $object
* @return void
* @throws Exception
*/
public function create(object $object): void
{
$this->update($object);
}
public function update(object $object): void
{
/**
* @var Product $product
*/
/**
* Нам надо находить RP чтобы понимать служебное оно или нет
*/
$product = $object;
$this->checkPublicity($product);
$avo = new AVOMessage([
'action' => 'create',
'data' => [
'timestamp' => ($product->getReleaseDate() ?? (new Carbon())->addDay())->getTimestamp(),
'product_guid' => (string) $product->getGuid(),
'vendor_code' => (string) $product->getArticle(),
//'same_product_guid'=> (string) $product->getSame()?->
'barcode' => (string) $product->getBarCode(),
'name'=> array_filter(array_map(function ($lang) use ($product) {
return ['text'=>$product->getName($lang), 'lang'=>$lang];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return !is_null($item['text']);
}),
'is_available'=> array_map(function ($lang) use ($product) {
return ['value'=>$product->getIsAviable($lang)??false, 'lang'=>$lang];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())),
'brand_name'=> $product->getBrand()->getName(),
'brand_guid'=> $product->getBrand()->getGuid(),
'collection_name'=> $product->getCollection()?->getName(),
'collection_guid'=> $product->getCollection()?->getGuid(),
'categories' => array_map(function ($cat){
return [
'name'=>$cat->getName('en'),
'guid'=>$cat->getGuid()
];
}, $product->getCategories()),
'awards'=>array_map(function ($award){
return [
'guid' => $award->getGuid(),
'name'=> $award->getName('en')
];
}, $product->getAwards()),
'marketing'=>[
'first_preview'=> $product->getPreviewOne()?Tool::getHostUrl().$product->getPreviewOne()?->getFullPath():null,
'second_preview'=> $product->getPreviewTwo()?Tool::getHostUrl().$product->getPreviewTwo()?->getFullPath():null,
'international_gallery'=>array_filter(array_map(function ($image){
return ['url'=> !is_null($image)?Tool::getHostUrl().$image->getImage()?->getFullPath():''];
}, $product->getInternationalGallery()->getItems()), function ($item){
return is_array($item) && $item['url']!=0;
}),
'gallery'=>array_filter(array_map(function ($lang) use ($product) {
return [
'lang'=>$lang,
'items'=> array_map(function ($image) use ($lang){
return ['url'=> Tool::getHostUrl().$image?->getImage()?->getFullPath()];
}, $product->getGallery($lang)?->getItems()??[])
];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return is_array($item) && count($item['items'])>0;
}),
'highlights' => array_filter(array_map(function ($lang) use ($product) {
return [
'lang'=>$lang,
'items'=> array_map(function ($highlight){
return $highlight['highlight']?->getData()??'';
}, $product->getHighlights($lang)??[])
];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return is_array($item) && count($item['items'])>0;
}),
'description' => array_filter(array_map(function ($lang) use ($product) {
return ['text'=>$product->getDescription($lang), 'lang'=>$lang];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return !is_null($item['text']);
}),
'video' => array_filter(array_map(function ($lang) use ($product) {
return [
'url'=>$product->getVideo($lang)?Tool::getHostUrl().$product->getVideo($lang)->getData()?->getFullPath():'',
'lang'=>$lang
];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return $item['url']!='';
}),
],
'parameters'=>[
'warranty'=>$product->getWarranty(),
'dimensions'=>[
'width'=>$product->getWidth(),
'height'=>$product->getHeight(),
'depth'=>$product->getDepth(),
'packageWidth'=>$product->getPackageWidth(),
'packageHeight'=>$product->getPackageHeight(),
'packageDepth'=>$product->getPackageDepth(),
'weight'=>$product->getWeight(),
],
],
'categoryParameters'=>array_map(function ($item){
return [
'code'=>$item->getFieldDefinition()->getName(),
'title'=>array_map(function ($lang) use ($item){
$pd = new PropertyDescriptor\Listing();
$pd->setCondition('classificationStoreField=?', [$item->getConfiguration()->getName()]);
$pd->setLimit(1);
if (array_key_exists(0,$pd->getData())) {
$propertyDescriptor = $pd->getData()[0];
return ['lang'=>$lang, 'text'=>$propertyDescriptor->getTitle($lang)];
}
return ['lang'=>$lang, 'text'=>$item->getFieldDefinition()->getTitle()];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())),
'text'=>$item->getValue(),
];
}, current($product->getCategoryParameters()->getGroups())?current($product->getCategoryParameters()->getGroups())->getKeys():[]),
'properties'=>[
'brandCountry'=>array_values(array_filter(array_map(function ($lang) use ($product) {
return ['text'=>$product->getBrandCountry($lang), 'lang'=>$lang];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return !is_null($item['text']);
})),
'manufacturerCountry'=>array_values(array_filter(array_map(function ($lang) use ($product) {
return ['text'=>$product->getManufacturerCountry($lang), 'lang'=>$lang];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return !is_null($item['text']);
})),
'material'=>array_values(array_filter(array_map(function ($lang) use ($product) {
return ['text'=>$product->getMaterial($lang), 'lang'=>$lang];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return !is_null($item['text']);
})),
'complectation'=>array_values(array_filter(array_map(function ($lang) use ($product) {
return ['text'=>$product->getComplectation($lang), 'lang'=>$lang];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return !is_null($item['text']);
})),
'colour'=>array_values(array_filter(array_map(function ($lang) use ($product) {
return ['text'=>$product->getColour($lang), 'lang'=>$lang];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return !is_null($item['text']);
})),
'style'=>array_values(array_filter(array_map(function ($lang) use ($product) {
return ['text'=>$product->getStyle($lang), 'lang'=>$lang];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return !is_null($item['text']);
})),
],
'categoryProperties'=>array_values(array_filter(array_map(function ($lang) use ($product){
return [
'lang'=>$lang,
'items'=>array_filter(array_map(function ($item) use ($lang){
return [
'code'=>$item->getFieldDefinition()->getName(),
'title'=>array_map(function ($lang) use ($item){
$pd = new PropertyDescriptor\Listing();
$pd->setCondition('classificationStoreField=?', [$item->getConfiguration()->getName()]);
$pd->setLimit(1);
if (array_key_exists(0,$pd->getData())) {
$propertyDescriptor = $pd->getData()[0];
return ['lang'=>$lang, 'text'=>$propertyDescriptor->getTitle($lang)];
}
return ['lang'=>$lang, 'text'=>$item->getFieldDefinition()->getTitle()];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())),
'text'=>$item->getValue($lang),
];
}, current($product->getCategoryParameters()->getGroups())?current($product->getCategoryParameters()->getGroups())->getKeys():[]), function ($item){
return !is_null($item['text']);
})
];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return is_array($item) && count($item['items'])>0;
})),
'technical'=>[
'manuals'=>array_map(function ($asset){
return ['url'=> Tool::getHostUrl().$asset->getFullPath()];
}, $product->getManuals()),
'schemes'=>array_map(function ($image){
return ['url'=> Tool::getHostUrl().$image?->getImage()->getFullPath()];
}, $product->getSchemes()->getItems()),
'stickers'=>array_filter(array_map(function ($lang) use ($product) {
return [
'lang'=>$lang,
'items'=> array_map(function ($image) use ($lang){
return ['url'=> Tool::getHostUrl().$image?->getImage()->getFullPath()];
}, $product->getStickers($lang)?->getItems()??[])
];
}, array_map(fn($case) => $case->value, LanguageEnum::cases())), function ($item){
return is_array($item) && count($item['items'])>0;
}),
]
],
'model' => 'EuProductRelease',
'timestamp' => $product->getModificationDate(),
]);
if (count($product->getSame())>0) {
/**
* @var Product $sp
*/
$sp = $product->getSame()[0];
$avo->data['same_product_guid'] = $sp->getGuid();
}
$this->bus->dispatch(
$avo->getDataModel(),
[
new AmqpStamp('release.product')
]
);
}
/**
* @param Product $product
* @return void
* @throws AnalogueNotPublished
* @throws BrandNotPublished
* @throws BundleNotPublished
* @throws CategoryNotPublished
* @throws CollectionNotPublished
* @throws LabelNotPublished
*/
protected function checkPublicity(Product $product)
{
$notPublished = [];
$brand = $product->getBrand();
if (is_null($brand))
throw new BrandNotPublished("Бренд не заполнен");
if (!$brand->isPublished())
throw new BrandNotPublished("Бренд {$brand->getGuid()} не опубликован");
$collection = $product->getCollection();
/**
* @warning Коллекция у нас необязательна для товара, но если есть, то она должна быть опубликована;
*/
if ( !is_null($collection) && !$collection->isPublished() )
throw new CollectionNotPublished("Коллекция {$collection->getGuid()}\n не опубликована");
$categories = $product->getCategories();
if (count($categories) < 2)
throw new CategoryNotPublished('Не заполнены категории');
$secondLevelNotExist = true;
foreach ($categories as $category){
if ($category->getParent() instanceof Category)
$secondLevelNotExist = false;
if (!$category->isPublished())
$notPublished[] = "Категория {$category->getGuid()} не опубликована\n";
}
if (count($notPublished) > 0)
throw new CategoryNotPublished( implode(', ', $notPublished) );
if ($secondLevelNotExist)
throw new CategoryNotPublished('Отсутствует категория второго уровня');
}
}