diff --git a/src/FieldDescription/TypeGuesserChain.php b/src/FieldDescription/TypeGuesserChain.php index 4cdbaeacf4..7dfa94c858 100644 --- a/src/FieldDescription/TypeGuesserChain.php +++ b/src/FieldDescription/TypeGuesserChain.php @@ -53,6 +53,8 @@ public function __construct(array $guessers) /** * @psalm-suppress ArgumentTypeCoercion @see https://github.com/vimeo/psalm/issues/5938 + * @psalm-suppress MoreSpecificReturnType @see https://github.com/vimeo/psalm/issues/8330#issuecomment-1198609261 + * @psalm-suppress LessSpecificReturnStatement @see https://github.com/vimeo/psalm/issues/8330#issuecomment-1198609261 */ public function guess(FieldDescriptionInterface $fieldDescription): ?TypeGuess { diff --git a/src/Resources/config/menu.php b/src/Resources/config/menu.php index 2828fecbcf..fb566618c2 100644 --- a/src/Resources/config/menu.php +++ b/src/Resources/config/menu.php @@ -33,6 +33,7 @@ ]) ->set('sonata.admin.sidebar_menu', MenuItem::class) + ->share(false) ->tag('knp_menu.menu', ['alias' => 'sonata_admin_sidebar']) ->factory([ new ReferenceConfigurator('sonata.admin.menu_builder'), diff --git a/tests/App/EventListener/ConfigureMenu.php b/tests/App/EventListener/ConfigureMenu.php new file mode 100644 index 0000000000..864d88fa3e --- /dev/null +++ b/tests/App/EventListener/ConfigureMenu.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\AdminBundle\Tests\App\EventListener; + +use Sonata\AdminBundle\Event\ConfigureMenuEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +final class ConfigureMenu implements EventSubscriberInterface +{ + private int $counter = 0; + + public static function getSubscribedEvents(): array + { + return [ + ConfigureMenuEvent::SIDEBAR => 'configureMenu', + ]; + } + + public function configureMenu(ConfigureMenuEvent $configureMenuEvent): void + { + $configureMenuEvent->getMenu()->addChild(sprintf('Dynamic Menu %s', ++$this->counter))->setAttribute('class', 'dynamic-menu'); + } +} diff --git a/tests/Functional/Controller/MenuTest.php b/tests/Functional/Controller/MenuTest.php new file mode 100644 index 0000000000..7960e56c89 --- /dev/null +++ b/tests/Functional/Controller/MenuTest.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\AdminBundle\Tests\Functional\Controller; + +use Sonata\AdminBundle\Tests\App\AppKernel; +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +final class MenuTest extends WebTestCase +{ + public function testDynamicMenuInLongRunningProcess(): void + { + $client = static::createClient(); + $client->disableReboot(); // forces requests to land at same Kernel, simulating long-running process like one used in roadrunner/reactphp/amphp + + for ($i = 1; $i < 5; ++$i) { + $client->request(Request::METHOD_GET, '/admin/dashboard'); + + static::assertSame(Response::HTTP_OK, $client->getResponse()->getStatusCode()); + + $crawler = $client->getCrawler(); + + $menu = $crawler->filter('.sidebar-menu .dynamic-menu a'); + + static::assertCount(1, $menu); + static::assertSame(sprintf('Dynamic Menu %s', $i), trim($menu->text())); + } + } + + protected static function getKernelClass(): string + { + return AppKernel::class; + } +}