<?php
/**
* Pimcore
*
* This source file is available under following license:
* - Pimcore Commercial License (PCL)
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license PCL
*/
namespace Pimcore\Bundle\DataHubSimpleRestBundle\Service;
use Pimcore\Bundle\DataHubBundle\Configuration;
use Pimcore\Bundle\DataHubBundle\Configuration\Dao;
use Pimcore\Bundle\DataHubSimpleRestBundle\Exception\InvalidRequestException;
use Pimcore\Bundle\DataHubSimpleRestBundle\MappingAndDataExtractor\AbstractMappingAndDataExtractor;
use Pimcore\Bundle\DataHubSimpleRestBundle\MappingAndDataExtractor\DataExtractorFactory;
use Pimcore\Bundle\DataHubSimpleRestBundle\Queue\QueueService;
use Pimcore\Model\Asset;
use Pimcore\Model\Asset\Folder;
use Pimcore\Model\DataObject\Concrete;
use Pimcore\Model\Element\ElementInterface;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Lock\LockFactory;
class AbstractService
{
use LoggerAwareTrait;
/**
* @var IndexHandler
*
*/
protected $indexHandler;
/**
* @var DataExtractorFactory
*/
protected $dataExtractorFactory;
/**
* @var array
*/
protected $dataExtractors;
/**
* @var QueueService
*/
protected $queueService;
/**
* @var string
*/
protected $indexNamePrefix;
/**
* @var array
*/
protected $dataHubConfig = null;
/**
* @var LockFactory
*/
protected $lockFactory;
public function __construct(
QueueService $queueService,
IndexHandler $indexHandler,
DataExtractorFactory $dataExtractorFactory,
string $indexNamePrefix,
/*LockFactory */ $lockFactory
) {
$this->queueService = $queueService;
$this->indexHandler = $indexHandler;
$this->dataExtractorFactory = $dataExtractorFactory;
$this->indexNamePrefix = $indexNamePrefix;
$this->lockFactory = $lockFactory;
}
/**
* @return array
*/
public function getDataHubConfig(): array
{
if ($this->dataHubConfig === null) {
$simpleRestConfigurations = [];
/**
* @var Configuration[] $allDataHubConfiguations
*/
$allDataHubConfiguations = Dao::getList();
foreach ($allDataHubConfiguations as $dataHubConfig) {
//TODO move this to config once more similar adapters are implemented
if (in_array($dataHubConfig->getType(), ['simpleRest', 'ciHub'])) {
$simpleRestConfigurations[$dataHubConfig->getName()] = $dataHubConfig->getConfiguration();
}
}
$this->dataHubConfig = $simpleRestConfigurations;
}
return $this->dataHubConfig;
}
/**
* @param array $dataHubConfig
*/
public function setDataHubConfig(array $dataHubConfig): void
{
$this->dataHubConfig = $dataHubConfig;
}
/**
* @param string|null $configName
* @param bool $forceDisabled
*
* @return array
*/
protected function getConfigsToProcess(string $configName = null, bool $forceDisabled = false): array
{
$configsToProcess = $configName;
if (empty($configsToProcess)) {
$configsToProcess = array_keys($this->getDataHubConfig());
}
if (!is_array($configsToProcess)) {
$configsToProcess = [$configsToProcess];
}
if (!$forceDisabled) {
$configsToProcess = array_filter($configsToProcess, function ($config) {
return $this->getDataHubConfig()[$config]['general']['active'] ?? false;
});
}
return $configsToProcess;
}
/**
* @param string $configName
*
* @return AbstractMappingAndDataExtractor[]
*
* @throws InvalidRequestException
*/
protected function getDataExtractorsForConfig(string $configName): array
{
$config = $this->getDataHubConfig()[$configName] ?? null;
if (empty($config)) {
throw new InvalidRequestException("Invalid or unknown config name '$configName'.");
}
if (isset($this->dataExtractors[$configName])) {
return $this->dataExtractors[$configName];
}
$fieldsForAggregations = [];
foreach ($config['labelSettings'] ?? [] as $setting) {
if ($setting['useInAggs'] ?? false) {
$fieldsForAggregations[$setting['id']] = true;
}
}
$dataExtractors = [];
if ($config['schema']['assets']['enabled'] ?? false) {
$dataExtractors[DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET] = $this->dataExtractorFactory->buildDataExtractor(
$configName,
DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET,
$config['schema']['assets'],
$config['workspaces']['asset'] ?? [],
$fieldsForAggregations,
$this->indexNamePrefix
);
$dataExtractors[DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET_FOLDER] = $this->dataExtractorFactory->buildDataExtractor(
$configName,
DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET_FOLDER,
$config['schema']['assets'],
$config['workspaces']['asset'] ?? [],
$fieldsForAggregations,
$this->indexNamePrefix
);
}
if ($config['schema']['dataObjectClasses']) {
foreach ($config['schema']['dataObjectClasses'] as $objectClassConfig) {
//include thumbnails from assets (if existing)
$objectClassConfig['assets']['thumbnails'] = $config['schema']['assets']['thumbnails'] ?? [];
$objectClassConfig['assets']['allowOriginalImage'] = $config['schema']['assets']['allowOriginalImage'] ?? false;
$dataExtractors[$objectClassConfig['id']] = $this->dataExtractorFactory->buildDataExtractor(
$configName,
$objectClassConfig['id'],
$objectClassConfig,
$config['workspaces']['object'] ?? [],
$fieldsForAggregations,
$this->indexNamePrefix
);
}
$dataExtractors[DataExtractorFactory::DATA_EXTRACTOR_TYPE_OBJECT_FOLDER] = $this->dataExtractorFactory->buildDataExtractor(
$configName,
DataExtractorFactory::DATA_EXTRACTOR_TYPE_OBJECT_FOLDER,
[],
$config['workspaces']['object'] ?? [],
$fieldsForAggregations,
$this->indexNamePrefix
);
}
$this->dataExtractors[$configName] = $dataExtractors;
return $dataExtractors;
}
/**
* @param string $configName
* @param string $entityType
*
* @return AbstractMappingAndDataExtractor|null
*
* @throws InvalidRequestException
*/
protected function getDataExtractorForConfigAndEntityType(string $configName, string $entityType): ?AbstractMappingAndDataExtractor
{
return $this->getDataExtractorsForConfig($configName)[$entityType] ?? null;
}
/**
* @param string $configName
* @param string $entityType
*
* @return AbstractMappingAndDataExtractor[]
*
* @throws InvalidRequestException
*/
protected function getDataExtractorCollectionForConfigAndType(string $configName, string $entityType): array
{
$allDataExtractors = $this->getDataExtractorsForConfig($configName);
if ($entityType === DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET || $entityType === DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET_FOLDER) {
return array_filter([
DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET => $allDataExtractors[DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET] ?? null,
DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET_FOLDER => $allDataExtractors[DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET_FOLDER] ?? null
]);
} else {
$result = [];
foreach ($allDataExtractors as $dataExtractorType => $dataExtractor) {
if ($dataExtractorType !== DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET && $dataExtractorType !== DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET_FOLDER) {
$result[$dataExtractorType] = $dataExtractor;
}
}
return $result;
}
}
/**
* @param ElementInterface $element
*
* @return string
*
* @throws \Exception
*/
public function getEntityTypeForElement(ElementInterface $element): string
{
if ($element instanceof Folder) {
return DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET_FOLDER;
} elseif ($element instanceof Asset) {
return DataExtractorFactory::DATA_EXTRACTOR_TYPE_ASSET;
} elseif ($element instanceof \Pimcore\Model\DataObject\Folder) {
return DataExtractorFactory::DATA_EXTRACTOR_TYPE_OBJECT_FOLDER;
} elseif ($element instanceof Concrete) {
return $element->getClassName();
} else {
throw new \Exception('Invalid element type for element ' . $element->getType());
}
}
/**
* @param string $configName
* @param string $token
*
* @return bool
*
* @throws InvalidRequestException
*/
public function validateToken(string $configName, string $token): bool
{
$config = $this->getDataHubConfig()[$configName] ?? null;
if (empty($config) || !$config['general']['active']) {
throw new InvalidRequestException("Invalid or unknown config name '$configName'.");
}
$endpointToken = $config['deliverySettings']['apikey'] ?? null;
if ($endpointToken == null || $endpointToken !== $token) {
return false;
}
return true;
}
}