<?php
namespace App\V4\Form;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use App\Form\Type\SubresourceChoicesTrait;
use App\Service\Cache\CacheManager;
use App\V4\Logger\SentryLogger;
use Psr\Cache\CacheException;
use Psr\Cache\InvalidArgumentException;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
/**
* @see https://stackoverflow.com/questions/35456199/symfony-2-8-dynamic-choicetype-options
*/
class AsyncSubresourceChoicesLoader implements ChoiceLoaderInterface
{
use SubresourceChoicesTrait;
/**
* @var CollectionDataProviderInterface
*/
private $collectionDataProvider;
/**
* @var CacheManager
*/
private $cacheManager;
/**
* @var SentryLogger
*/
private $sentryLogger;
/**
* @var string
*/
private $entityFQCN;
/**
* @var string
*/
private $valueProperty;
/**
* @var ArrayChoiceList
*/
private $choiceList;
/**
* @var array
*/
private $additionalFilters;
public function __construct(
CollectionDataProviderInterface $collectionDataProvider,
CacheManager $cacheManager,
SentryLogger $sentryLogger,
string $entityFQCN,
string $valueProperty = 'id',
array $additionalFilters = []
) {
$this->collectionDataProvider = $collectionDataProvider;
$this->cacheManager = $cacheManager;
$this->sentryLogger = $sentryLogger;
$this->entityFQCN = $entityFQCN;
$this->valueProperty = $valueProperty;
$this->additionalFilters = $additionalFilters;
}
/**
* {@inheritdoc}
*/
public function loadChoiceList($value = null)
{
if (!$this->choiceList) {
$this->choiceList = new ArrayChoiceList([], $value);
}
return $this->choiceList;
}
/**
* {@inheritdoc}
*/
public function loadChoicesForValues(array $values, $value = null)
{
$matches = $this->findMatchesOrEmpty($values);
$this->choiceList = new ArrayChoiceList($matches, $value);
return $matches;
}
/**
* {@inheritdoc}
*/
public function loadValuesForChoices(array $choices, $value = null)
{
$ids = [];
foreach ($choices as $choice) {
if (is_callable($value)) {
$ids[] = $value($choice);
continue;
}
$ids[] = $choice;
}
$this->choiceList = new ArrayChoiceList($choices, $value);
return $ids;
}
/**
* @throws CacheException
* @throws InvalidArgumentException
*/
private function findMatchesOrEmpty(array $ids)
{
if (empty($ids)) {
return [];
}
sort($ids);
return $this->getEntityChoices(
$this->collectionDataProvider,
$this->cacheManager,
$this->sentryLogger,
$this->entityFQCN,
array_merge($this->additionalFilters, [$this->valueProperty => $ids])
);
}
}