DigiComp.FluidJsonViews/Classes/ViewHelpers/Controller/FluidJsonController.php
Ferdinand Kuhl baf5636bd3
All checks were successful
ci/woodpecker/push/code-style Pipeline was successful
ci/woodpecker/push/functional-tests/1 Pipeline was successful
ci/woodpecker/push/functional-tests/2 Pipeline was successful
ci/woodpecker/push/functional-tests/3 Pipeline was successful
ci/woodpecker/push/functional-tests/4 Pipeline was successful
adjusting to new storage location of render functions
2024-06-02 04:26:53 +02:00

143 lines
4.6 KiB
PHP

<?php
declare(strict_types=1);
namespace DigiComp\FluidJsonViews\ViewHelpers\Controller;
use DigiComp\FluidRenderFunctions\InvokeRenderFunctionInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Proxy\Proxy;
use Doctrine\ORM\Query\Parameter;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Persistence\Doctrine\Query;
use Neos\FluidAdaptor\Core\Widget\AbstractWidgetController;
use Neos\FluidAdaptor\View\TemplateView;
use Neos\Utility\TypeHandling;
class FluidJsonController extends AbstractWidgetController
{
/**
* @Flow\Inject
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* @inheritDoc
*/
protected $supportedMediaTypes = [
'text/html',
'application/json',
];
/**
* @var Query|null
*/
protected ?Query $query = null;
protected InvokeRenderFunctionInterface $renderFunction;
/**
* @Flow\InjectConfiguration(package="DigiComp.FluidJsonViews", path="limitConfiguration")
* @var array
*/
protected array $limitConfiguration;
/**
* @var array
*/
protected array $searchProperties;
protected function initializeAction(): void
{
parent::initializeAction();
$this->query = clone $this->widgetConfiguration['objects']->getQuery();
$this->renderFunction = $this->widgetConfiguration['renderFunction'];
$this->searchProperties = $this->widgetConfiguration['searchProperties'];
$this->initializeDoctrineSource();
}
/**
* Initializes count, objectType and doctrine's MetaDataFactory
*/
protected function initializeDoctrineSource(): void
{
// As we are working with objects which may be doctrine proxies persisted in session, its metadata have
// never been loaded in this request. So let's see these parameters and load their metadata, so the doctrine
// framework knows how to go on.
if ($this->query instanceof Query) {
$parameters = $this->query->getQueryBuilder()->getParameters();
foreach ($parameters as $parameter) {
if ($parameter instanceof Parameter && $parameter->getValue() instanceof Proxy) {
$this->entityManager->getMetadataFactory()->getMetadataFor(
TypeHandling::getTypeForValue($parameter->getValue())
);
}
}
}
}
public function indexAction()
{
$this->view->assign('entityClassName', $this->query->getType());
if ($this->view instanceof TemplateView) {
$renderingContext = $this->request
->getInternalArgument('__widgetContext')
->getViewHelperChildNodeRenderingContext();
$this->view->assignMultiple($renderingContext->getVariableProvider()->getAll());
}
}
/**
* @see https://select2.org/data-sources/ajax#request-parameters
*/
public function dataAction(
?int $limit = null,
?string $term = null,
?int $page = 0
) {
$query = $this->query;
$result['recordsTotal'] = $query->execute()->count();
if ($term !== null) {
$searchConstraint = $this->getSearchConstraints($term);
$query->matching($query->logicalAnd($searchConstraint));
}
$result['recordsFiltered'] = $query->execute()->count();
if ($limit === null) {
$limit = $this->limitConfiguration['default'];
}
if ($this->limitConfiguration['max'] !== null) {
if ($limit > $this->limitConfiguration['max'] || $limit === null) {
$limit = $this->limitConfiguration['max'];
}
}
if ($limit !== null) {
$data = $query->setLimit($limit)->setOffset($page * $limit)->execute();
} else {
$data = $query->execute();
}
$renderFunc = $this->renderFunction;
foreach ($data as $object) {
$result['results'][] = [
'id' => $this->persistenceManager->getIdentifierByObject($object),
'text' => $renderFunc($object),
];
}
$this->response->setContentType('application/json');
return \json_encode($result, \JSON_THROW_ON_ERROR);
}
protected function getSearchConstraints(
string $term
): object {
$searchConstraints = [];
foreach ($this->searchProperties as $searchProperty) {
$searchConstraints[] = $this->query->like($searchProperty, '%' . $term . '%');
}
return $this->query->logicalOr($searchConstraints);
}
}