<?php
namespace AppBundle\EventListeners;
use Pimcore\Event\Model\SearchBackendEvent;
use Pimcore\Model\DataObject\AbstractObject;
use Pimcore\Model\DataObject\Product;
use Pimcore\Model\Search\Backend\Data;
class SearchDataImprover
{
/**
* @param SearchBackendEvent $e
*/
public function improveData(SearchBackendEvent $e)
{
/** @var Data $element */
$element = $e->getData();
if ($element->getType() === 'object' && $element->getSubtype() === 'Product') {
$data = $this->getImprovedData($element);
if ($data) {
$element->data = $data;
}
}
}
/**
* @param Data $element
* @return string|void
*/
protected function getImprovedData(Data $element)
{
$product = Product::getById($element->getId()->getId());
if (!$product) {
return;
}
$data = '';
$getInheritedValues = AbstractObject::doGetInheritedValues();
AbstractObject::setGetInheritedValues(true);
foreach ($product->getClass()->getFieldDefinitions() as $key => $value) {
$data .= ' ' . $value->getDataForSearchIndex($product);
}
AbstractObject::setGetInheritedValues($getInheritedValues);
// replace all occurrences of @ to # because when using InnoDB @ is reserved for the @distance operator
$data = str_replace('@', '#', $data);
$pathWords = str_replace(['-', '_', '/', '.', '(', ')'], ' ', $element->getFullPath());
$data .= ' ' . $pathWords;
return 'ID: ' . $product->getId() . " \nPath: " . $element->getFullPath() . " \n" . $this->cleanupData($data);
}
/**
* @param $data
* @return string
*/
protected function cleanupData($data)
{
$data = html_entity_decode($data, ENT_QUOTES, 'UTF-8');
// we don't remove ".", otherwise it would be impossible to search for email addresses
$data = str_replace([',', ':', ';', "'", '"'], ' ', $data);
$data = str_replace("\r\n", ' ', $data);
$data = str_replace("\n", ' ', $data);
$data = str_replace("\r", ' ', $data);
$data = str_replace("\t", '', $data);
$data = preg_replace('#[ ]+#', ' ', $data);
// deduplication
$arr = explode(' ', $data);
$arr = array_unique($arr);
$data = implode(' ', $arr);
return $data;
}
}