<?php
namespace App\EventListener;
use Exception;
use Pimcore\Event\Model\DataObjectEvent;
use Pimcore\Event\Model\ElementEventInterface;
use Pimcore\Model\Asset;
use Pimcore\Model\Asset\Image;
use Pimcore\Model\DataObject\Folder;
use Pimcore\Model\DataObject\Product;
use Pimcore\Model\WebsiteSetting;
class SyncDataObjectsWithAlgoliaListener extends BaseAlgoliaListener
{
/**
* @throws Exception
*/
public function onPostUpdate(ElementEventInterface $e)
{
// only if algolia is enabled
if ($this->isAlgoliaEnabled()) {
if ($e instanceof DataObjectEvent) {
$obj = $e->getObject();
if ($obj instanceof Product) {
// don't allow products starting with specific existing path
if ($excludedWs = WebsiteSetting::getByName("excludePathFromAlgoliaIndexing")) {
$excludedPath = $excludedWs->getData();
if (str_starts_with($obj->getPath(), $excludedPath)) {
$folder = Folder::getByPath($excludedPath);
if ($folder instanceof Folder) {
// remove from index because it should be excluded
$this->getIndex()->deleteObject($obj->getId());
return;
}
}
}
// don't allow product parents
if ($obj->hasChildren()) {
return;
}
$images = [];
$documents = [];
// get product images
foreach ($obj->getImages()->getItems() as $item) {
if ($image = $item->getImage()) {
if ($image instanceof Image) {
// push only active images for algolia indexing
if ($image->getHasMetaData() && $image->getMetadata("indexAlgolia")) {
$images[] = [
"thumbnail" => !is_string($item->getThumbnail()) ? $item->getThumbnail("printdefault")->getPath() : "",
"originalImage" => $image->getFullPath() ?? "",
"fileSize" => $image->getFileSize() ?? ""
];
}
}
}
}
// get product documents
foreach ($obj->getDocuments() as $document) {
// allow all assets
if ($document instanceof Asset) {
// push only active images for algolia indexing
if ($document->getHasMetaData() && $document->getMetadata("indexAlgolia")) {
$documents[] = [
"document" => $document->getFullPath() ?? "",
"filename" => $document->getFilename() ?? "",
"fileSize" => $document->getFileSize() ?? ""
];
}
}
}
// if no images and documents found; or product is unpublished, remove product from index and cancel further processing
if ((sizeof($images) <= 0 && sizeof($documents) <= 0) || !$obj->getPublished()) {
$this->getIndex()->deleteObject($obj->getId());
return;
}
$indexableData = [
"description" => $obj->getDesignations('de'), // TODO-dkfn20 allgemeine translation statt immer 'de'?
"images" => $images,
"documents" => $documents,
"orderno" => $obj->getOrdernumber(),
"longnumber" => $obj->getLongnumber()
];
// Has to be assigned separately before saveObject() call to prevent unique objectID error!
$indexableData['objectID'] = $obj->getId();
$this->getIndex()->saveObject($indexableData);
}
}
}
}
/**
* @throws Exception
*/
public function onPostDelete(ElementEventInterface $e)
{
if ($e instanceof DataObjectEvent) {
$obj = $e->getObject();
if ($obj instanceof Product) {
if ($this->getIndex()) {
$this->getIndex()->deleteObject($obj->getId());
}
}
}
}
}