Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Autocomplete/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Remove `ParentEntityAutocompleteType` in favor of `BaseEntityAutocompleteType`
- Remove `ExtraLazyChoiceLoader` in favor of `Symfony\Component\Form\ChoiceList\Loader\LazyChoiceLoader` from Symfony Form >=7.2
- Add parameter `$security` to `AutocompleteResultsExecutor::__construct()`
- Remove BC layer for `EntityAutocompleterInterface::getAttributes()` and `EntityAutocompleterInterface::getGroupBy()`

## 2.30

Expand Down Expand Up @@ -52,7 +53,7 @@ class IngredientAutocompleteType extends AbstractType

- Deprecate `ExtraLazyChoiceLoader` in favor of `Symfony\Component\Form\ChoiceList\Loader\LazyChoiceLoader`
- Reset TomSelect when updating url attribute #1505
- Add `getAttributes()` method to define additional attributes for autocomplete results #2541
- Add `EntityAutocompleterInterface::getAttributes()` method to define additional attributes for autocomplete results #2541

## 2.22.0

Expand Down
9 changes: 2 additions & 7 deletions src/Autocomplete/src/AutocompleteResultsExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function fetchResults(EntityAutocompleterInterface $autocompleter, string

$results = [];

if (!method_exists($autocompleter, 'getGroupBy') || null === $groupBy = $autocompleter->getGroupBy()) {
if (null === $groupBy = $autocompleter->getGroupBy()) {
foreach ($paginator as $entity) {
$results[] = $this->formatResult($autocompleter, $entity);
}
Expand Down Expand Up @@ -112,13 +112,8 @@ public function fetchResults(EntityAutocompleterInterface $autocompleter, string
*/
private function formatResult(EntityAutocompleterInterface $autocompleter, object $entity): array
{
$attributes = [];
if (method_exists($autocompleter, 'getAttributes')) {
$attributes = $autocompleter->getAttributes($entity);
}

return [
...$attributes,
...$autocompleter->getAttributes($entity),
'value' => $autocompleter->getValue($entity),
'text' => $autocompleter->getLabel($entity),
];
Expand Down
17 changes: 7 additions & 10 deletions src/Autocomplete/src/EntityAutocompleterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@
* Interface for classes that will have an "autocomplete" endpoint exposed.
*
* @template T of object
*
* TODO Remove next lines for Symfony UX 3
*
* @method array getAttributes(object $entity) Returns extra attributes to add to the autocomplete result.
* @method mixed getGroupBy() Return group_by option.
*/
interface EntityAutocompleterInterface
{
Expand Down Expand Up @@ -58,9 +53,11 @@ public function getValue(object $entity): mixed;
/**
* Returns extra attributes to add to the autocomplete result.
*
* TODO Uncomment for Symfony UX 3
* @param T $entity
*
* @return array<string, mixed>
*/
/* public function getAttributes(object $entity): array; */
public function getAttributes(object $entity): array;

/**
* Return true if access should be granted to the autocomplete results for the current user.
Expand All @@ -69,10 +66,10 @@ public function getValue(object $entity): mixed;
*/
public function isGranted(Security $security): bool;

/*
/**
* Return group_by option.
*
* TODO Uncomment for Symfony UX 3
* @return string|null
*/
/* public function getGroupBy(): mixed; */
public function getGroupBy(): mixed;
}
3 changes: 3 additions & 0 deletions src/Autocomplete/src/Form/BaseEntityAutocompleteType.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,14 @@ public function configureOptions(OptionsResolver $resolver): void
'security' => false,
// set the max results number that a query on automatic endpoint return.
'max_results' => 10,
// extra attributes to add to the autocomplete result, either an array or a callable (called with the entity)
'additional_attributes' => null,
]);

$resolver->setAllowedTypes('security', ['boolean', 'string', 'callable']);
$resolver->setAllowedTypes('max_results', ['int', 'null']);
$resolver->setAllowedTypes('filter_query', ['callable', 'null']);
$resolver->setAllowedTypes('additional_attributes', ['null', 'callable', 'array']);
$resolver->setNormalizer('searchable_fields', function (Options $options, ?array $searchableFields) {
if (null !== $searchableFields && null !== $options['filter_query']) {
throw new RuntimeException('Both the searchable_fields and filter_query options cannot be set.');
Expand Down
21 changes: 19 additions & 2 deletions src/Autocomplete/src/Form/WrappedEntityTypeAutocompleter.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,28 @@ public function getGroupBy(): mixed
return $this->getFormOption('group_by');
}

public function getAttributes(object $entity): array
{
$attributesOption = $this->getFormOption('additional_attributes');

if (null === $attributesOption) {
return [];
}

if (\is_array($attributesOption)) {
return $attributesOption;
}

if (\is_callable($attributesOption)) {
return $attributesOption($entity);
}

throw new \InvalidArgumentException('The "additional_attributes" option must be either an array or a callable.');
}

private function getFormOption(string $name): mixed
{
$form = $this->getForm();
// Remove when dropping support for ParentEntityAutocompleteType
$form = $form->has('autocomplete') ? $form->get('autocomplete') : $form;
$formOptions = $form->getConfig()->getOptions();

return $formOptions[$name] ?? null;
Expand Down
1 change: 1 addition & 0 deletions src/Turbo/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Minimum required Symfony version is now 6.4
- Minimum required PHP version is now 8.2
- Remove old compatibility layer with deprecated `StimulusTwigExtension` from WebpackEncoreBundle ^1.0, use StimulusBundle instead
- Remove BC layer for `TurboStreamListenRendererInterface::renderTurboStreamListen()` `$eventSourceOptions` parameter

## 2.32

Expand Down
12 changes: 4 additions & 8 deletions src/Turbo/src/Bridge/Mercure/TurboStreamListenRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use Symfony\Component\Mercure\Twig\MercureExtension;
use Symfony\UX\StimulusBundle\Helper\StimulusHelper;
use Symfony\UX\Turbo\Broadcaster\IdAccessor;
use Symfony\UX\Turbo\Twig\TurboStreamListenRendererWithOptionsInterface;
use Symfony\UX\Turbo\Twig\TurboStreamListenRendererInterface;
use Twig\Environment;
use Twig\Error\RuntimeError;
use Twig\Extension\AbstractExtension;
Expand All @@ -25,7 +25,7 @@
*
* @author Kévin Dunglas <[email protected]>
*/
final class TurboStreamListenRenderer implements TurboStreamListenRendererWithOptionsInterface
final class TurboStreamListenRenderer implements TurboStreamListenRendererInterface
{
public function __construct(
private HubInterface $hub,
Expand All @@ -35,12 +35,8 @@ public function __construct(
) {
}

public function renderTurboStreamListen(Environment $env, $topic /* array $eventSourceOptions = [] */): string
public function renderTurboStreamListen(Environment $env, $topic, array $eventSourceOptions = []): string
{
if (\func_num_args() > 2) {
$eventSourceOptions = func_get_arg(2);
}

$topics = $topic instanceof TopicSet
? array_map($this->resolveTopic(...), $topic->getTopics())
: [$this->resolveTopic($topic)];
Expand All @@ -52,7 +48,7 @@ public function renderTurboStreamListen(Environment $env, $topic /* array $event
$controllerAttributes['topic'] = current($topics);
}

if (isset($eventSourceOptions)) {
if ([] !== $eventSourceOptions) {
try {
// Mercure >= 0.7: https://github.com/symfony/mercure/pull/123
/* @phpstan-ignore-next-line function.alreadyNarrowedType */
Expand Down
4 changes: 1 addition & 3 deletions src/Turbo/src/Twig/TurboRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ public function renderTurboStreamListen(Environment $env, $topic, ?string $trans

$renderer = $this->turboStreamListenRenderers->get($transport);

return $renderer instanceof TurboStreamListenRendererWithOptionsInterface
? $renderer->renderTurboStreamListen($env, $topic, $options) // @phpstan-ignore-line
: $renderer->renderTurboStreamListen($env, $topic);
return $renderer->renderTurboStreamListen($env, $topic, $options);
}
}
5 changes: 3 additions & 2 deletions src/Turbo/src/Twig/TurboStreamListenRendererInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
interface TurboStreamListenRendererInterface
{
/**
* @param string|object $topic
* @param string|object $topic
* @param array<string, mixed> $eventSourceOptions
*/
public function renderTurboStreamListen(Environment $env, $topic /* , array $eventSourceOptions = [] */): string;
public function renderTurboStreamListen(Environment $env, $topic, array $eventSourceOptions = []): string;
}

This file was deleted.

3 changes: 1 addition & 2 deletions src/Turbo/tests/Twig/TurboRuntimeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Symfony\Contracts\Service\ServiceProviderInterface;
use Symfony\UX\Turbo\Twig\TurboRuntime;
use Symfony\UX\Turbo\Twig\TurboStreamListenRendererInterface;
use Symfony\UX\Turbo\Twig\TurboStreamListenRendererWithOptionsInterface;
use Twig\Environment;

final class TurboRuntimeTest extends TestCase
Expand All @@ -41,7 +40,7 @@ public function testRenderTurboStreamListenWithMultipleHubs()
{
$twig = $this->createMock(Environment::class);
$renderer1 = $this->createMock(TurboStreamListenRendererInterface::class);
$renderer2 = $this->createMock(TurboStreamListenRendererWithOptionsInterface::class);
$renderer2 = $this->createMock(TurboStreamListenRendererInterface::class);
$renderer2->expects($this->once())
->method('renderTurboStreamListen')
->with($twig, 'a_topic', ['hub' => 'hub2'])
Expand Down
Loading