From 22d54e20738fa7e9df54d1044f4b8649abfab4eb Mon Sep 17 00:00:00 2001 From: DDEV User Date: Wed, 29 Mar 2023 08:52:01 +0000 Subject: [PATCH] add error notice in layout, added missing english translations, fixes some glitches --- CHANGELOG.md | 7 +++ src/Collection/EntryCollection.php | 8 +++- src/Command/PrepareCommand.php | 2 +- src/DataContainer/LayoutContainer.php | 45 ++++++++++++++----- .../Callback/EncoreEntryOptionListener.php | 16 +++++-- src/Resources/translations/messages.de.yml | 2 + src/Resources/translations/messages.en.yml | 13 ++++++ tests/DataContainer/LayoutContainerTest.php | 14 ++++-- .../EncoreEntryOptionListenerTest.php | 4 +- 9 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 src/Resources/translations/messages.en.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 5af393f..bb37873 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## [1.20.0] - 2023-03-29 +- Changed: show message in layout when entrypoints not generated +- Changed: added some english translations +- Fixed: throw correct exception in EntryCollection +- Fixed: warning when package.json has no dependencies in prepare command +- Fixed: add entry button in layout has not function if entrypoints not generated + ## [1.19.0] - 2023-03-23 - Changed: reduced utils bundle usage ([#28]) - Deprecated: class `ImportsTemplateChoice` diff --git a/src/Collection/EntryCollection.php b/src/Collection/EntryCollection.php index 2290e89..6971cb7 100644 --- a/src/Collection/EntryCollection.php +++ b/src/Collection/EntryCollection.php @@ -33,6 +33,7 @@ public function __construct(ConfigurationCollection $configurationCollection, ar /** * Return all encore entries (from webpack config and registered via bundle). + * @throws NoEntrypointsException */ public function getEntries(): array { @@ -85,6 +86,9 @@ private function mergeEntries(array $entrypointJsonFiles, array $bundleConfigEnt return $bundleConfigEntries; } + /** + * @throws NoEntrypointsException + */ private function parseEntrypoints(string $entrypointsJson): array { $cached = null; @@ -100,13 +104,13 @@ private function parseEntrypoints(string $entrypointsJson): array } if (!file_exists($entrypointsJson)) { - throw new \InvalidArgumentException(sprintf('Could not find the entrypoints.json: the file "%s" does not exist. Maybe you forgot to run encore command?', $entrypointsJson)); + throw new NoEntrypointsException(sprintf('Could not find the entrypoints.json: the file "%s" does not exist. Maybe you forgot to run encore command?', $entrypointsJson)); } $entriesData = json_decode(file_get_contents($entrypointsJson), true); if (null === $entriesData) { - throw new \InvalidArgumentException(sprintf('Could not decode the "%s" file', $entrypointsJson)); + throw new NoEntrypointsException(sprintf('Could not decode the "%s" file', $entrypointsJson)); } if (!isset($entriesData['entrypoints'])) { diff --git a/src/Command/PrepareCommand.php b/src/Command/PrepareCommand.php index 30fcc2f..73a565a 100644 --- a/src/Command/PrepareCommand.php +++ b/src/Command/PrepareCommand.php @@ -184,7 +184,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $packageData['dependencies'] = array_merge( ['@hundh/encore-entry-dependencies' => 'file:.'.DIRECTORY_SEPARATOR.$encoreAssetsPath.DIRECTORY_SEPARATOR], - $packageData['dependencies'] + $packageData['dependencies'] ?? [] ); (new Filesystem())->dumpFile( diff --git a/src/DataContainer/LayoutContainer.php b/src/DataContainer/LayoutContainer.php index 45be630..b8d5e7f 100644 --- a/src/DataContainer/LayoutContainer.php +++ b/src/DataContainer/LayoutContainer.php @@ -14,24 +14,31 @@ use Contao\DataContainer; use Contao\LayoutModel; use Contao\Message; +use HeimrichHannot\EncoreBundle\Collection\EntryCollection; +use HeimrichHannot\EncoreBundle\Exception\NoEntrypointsException; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Contracts\Translation\TranslatorInterface; class LayoutContainer { - protected array $bundleConfig; - protected ContaoFramework $contaoFramework; - private RequestStack $requestStack; - private ScopeMatcher $scopeMatcher; + protected array $bundleConfig; + protected ContaoFramework $contaoFramework; + private RequestStack $requestStack; + private ScopeMatcher $scopeMatcher; + private EntryCollection $entryCollection; + private TranslatorInterface $translator; /** * LayoutContainer constructor. */ - public function __construct(array $bundleConfig, ContaoFramework $contaoFramework, RequestStack $requestStack, ScopeMatcher $scopeMatcher) + public function __construct(array $bundleConfig, ContaoFramework $contaoFramework, RequestStack $requestStack, ScopeMatcher $scopeMatcher, EntryCollection $entryCollection, TranslatorInterface $translator) { $this->bundleConfig = $bundleConfig; $this->contaoFramework = $contaoFramework; $this->requestStack = $requestStack; $this->scopeMatcher = $scopeMatcher; + $this->entryCollection = $entryCollection; + $this->translator = $translator; } /** @@ -41,17 +48,31 @@ public function onLoadCallback(DataContainer $dc = null): void { $request = $this->requestStack->getCurrentRequest(); - if (!$request - || !$dc - || !$this->scopeMatcher->isBackendRequest($request) - || !isset($this->bundleConfig['use_contao_template_variables']) - || true !== $this->bundleConfig['use_contao_template_variables'] - || !($layout = $this->contaoFramework->getAdapter(LayoutModel::class)->findByPk($dc->id))) { + if (!$request || !$dc || !$this->scopeMatcher->isBackendRequest($request) || !($layout = $this->contaoFramework->getAdapter(LayoutModel::class)->findByPk($dc->id))) { + return; + } + + $messageAdapter = $this->contaoFramework->getAdapter(Message::class); + if ($layout->addEncore) { + if ($messageAdapter->hasMessages('huh.encore.error.noEntryPoints')) { + $messageAdapter->addError($messageAdapter->generateUnwrapped('huh.encore.error.noEntryPoints', true)); + } else { + try { + $this->entryCollection->getEntries(); + } catch (NoEntrypointsException $e) { + $messageAdapter->addError('[Encore Bundle] '.$this->translator->trans('huh.encore.errors.noEntrypoints').' '.$e->getMessage()); + } + } + } + + if (!isset($this->bundleConfig['use_contao_template_variables']) + || true !== $this->bundleConfig['use_contao_template_variables']) { return; } if ($layout->addEncore && $layout->addJQuery && (!isset($this->bundleConfig['unset_jquery']) || true !== $this->bundleConfig['unset_jquery'])) { - $this->contaoFramework->getAdapter(Message::class)->addInfo(($GLOBALS['TL_LANG']['tl_layout']['INFO']['jquery_order_conflict'] ?: '')); + $messageAdapter->addInfo(($GLOBALS['TL_LANG']['tl_layout']['INFO']['jquery_order_conflict'] ?: '')); + } } diff --git a/src/EventListener/Callback/EncoreEntryOptionListener.php b/src/EventListener/Callback/EncoreEntryOptionListener.php index 001f0eb..e0d9e47 100644 --- a/src/EventListener/Callback/EncoreEntryOptionListener.php +++ b/src/EventListener/Callback/EncoreEntryOptionListener.php @@ -8,22 +8,32 @@ namespace HeimrichHannot\EncoreBundle\EventListener\Callback; +use Contao\Message; use HeimrichHannot\EncoreBundle\Collection\EntryCollection; +use HeimrichHannot\EncoreBundle\Exception\NoEntrypointsException; +use Symfony\Contracts\Translation\TranslatorInterface; class EncoreEntryOptionListener { - private EntryCollection $entryCollection; + private EntryCollection $entryCollection; + private TranslatorInterface $translator; - public function __construct(EntryCollection $entryCollection) + public function __construct(EntryCollection $entryCollection, TranslatorInterface $translator) { $this->entryCollection = $entryCollection; + $this->translator = $translator; } public function getEntriesAsOptions(): array { $choices = []; - $projectEntries = $this->entryCollection->getEntries(); + try { + $projectEntries = $this->entryCollection->getEntries(); + } catch (NoEntrypointsException $e) { + $projectEntries = []; + Message::addError('[Encore Bundle] '.$this->translator->trans('huh.encore.errors.noEntrypoints').' '.$e->getMessage(), 'huh.encore.error.noEntryPoints'); + } if (empty($projectEntries)) { return $choices; diff --git a/src/Resources/translations/messages.de.yml b/src/Resources/translations/messages.de.yml index 154946a..7f63c8a 100644 --- a/src/Resources/translations/messages.de.yml +++ b/src/Resources/translations/messages.de.yml @@ -9,3 +9,5 @@ huh.encore: encoreEntriesSelect_active: name: "Aktiv" description: "" + errors: + noEntrypoints: "Es konnten keine Entrypoints gefunden werden. Folgende Fehlermeldung erhalten:" \ No newline at end of file diff --git a/src/Resources/translations/messages.en.yml b/src/Resources/translations/messages.en.yml new file mode 100644 index 0000000..e5b6436 --- /dev/null +++ b/src/Resources/translations/messages.en.yml @@ -0,0 +1,13 @@ +huh.encore: + fields: + encoreEntriesSelect: + name: "Encore entries" + description: "Choose encore entries to include in the template" + encoreEntriesSelect_entry: + name: "Entry" + description: "" + encoreEntriesSelect_active: + name: "Active" + description: "" + errors: + noEntrypoints: "Could not find encore entrypoints. Got following error message:" \ No newline at end of file diff --git a/tests/DataContainer/LayoutContainerTest.php b/tests/DataContainer/LayoutContainerTest.php index ac4b914..a308058 100644 --- a/tests/DataContainer/LayoutContainerTest.php +++ b/tests/DataContainer/LayoutContainerTest.php @@ -14,10 +14,12 @@ use Contao\LayoutModel; use Contao\Message; use Contao\TestCase\ContaoTestCase; +use HeimrichHannot\EncoreBundle\Collection\EntryCollection; use HeimrichHannot\EncoreBundle\DataContainer\LayoutContainer; use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Contracts\Translation\TranslatorInterface; class LayoutContainerTest extends ContaoTestCase { @@ -27,12 +29,16 @@ public function createTestInstance(array $parameters = []): LayoutContainer $contaoFramework = $parameters['contaoFramework'] ?? $this->mockContaoFramework(); $requestStack = $parameters['requestStack'] ?? $this->createMock(RequestStack::class); $scopeMatcher = $parameters['scopeMatcher'] ?? $this->createMock(ScopeMatcher::class); + $entryCollection = $parameters['entryCollection'] ?? $this->createMock(EntryCollection::class); + $translator = $parameters['translator'] ?? $this->createMock(TranslatorInterface::class); return new LayoutContainer( $bundleConfig, $contaoFramework, $requestStack, - $scopeMatcher + $scopeMatcher, + $entryCollection, + $translator ); } @@ -40,7 +46,7 @@ public function testOnLoadCallback() { $GLOBALS['TL_LANG']['tl_layout']['INFO']['jquery_order_conflict'] = 'Info'; - $messageAdapter = $this->mockAdapter(['addInfo']); + $messageAdapter = $this->mockAdapter(['addError', 'addInfo', 'generateUnwrapped', 'hasMessages']); $messageAdapter->expects($this->never())->method('addInfo')->willReturn(null); /** @var ContaoFramework|MockObject $contaoFramework */ @@ -91,7 +97,7 @@ public function testOnLoadCallback() 'addJQuery' => true, ])); - $messageAdapter = $this->mockAdapter(['addInfo']); + $messageAdapter = $this->mockAdapter(['addError', 'addInfo', 'generateUnwrapped', 'hasMessages']); $messageAdapter->expects($this->once())->method('addInfo')->willReturn(null); /** @var ContaoFramework|MockObject $contaoFramework */ $contaoFramework = $this->mockContaoFramework([ @@ -107,7 +113,7 @@ public function testOnLoadCallback() $instance->onLoadCallback($dc); $bundleConfig['unset_jquery'] = true; - $messageAdapter = $this->mockAdapter(['addInfo']); + $messageAdapter = $this->mockAdapter(['addError', 'addInfo', 'generateUnwrapped', 'hasMessages']); $messageAdapter->expects($this->never())->method('addInfo')->willReturn(null); /** @var ContaoFramework|MockObject $contaoFramework */ $contaoFramework = $this->mockContaoFramework([ diff --git a/tests/EventListener/Callback/EncoreEntryOptionListenerTest.php b/tests/EventListener/Callback/EncoreEntryOptionListenerTest.php index b68bd3b..9d4bf9b 100644 --- a/tests/EventListener/Callback/EncoreEntryOptionListenerTest.php +++ b/tests/EventListener/Callback/EncoreEntryOptionListenerTest.php @@ -11,14 +11,16 @@ use Contao\TestCase\ContaoTestCase; use HeimrichHannot\EncoreBundle\Collection\EntryCollection; use HeimrichHannot\EncoreBundle\EventListener\Callback\EncoreEntryOptionListener; +use Symfony\Contracts\Translation\TranslatorInterface; class EncoreEntryOptionListenerTest extends ContaoTestCase { public function createTestInstance(array $parameters = []): EncoreEntryOptionListener { $entryCollection = $parameters['entryCollection'] ?? $this->createMock(EntryCollection::class); + $translator = $parameters['translator'] ?? $this->createMock(TranslatorInterface::class); - return new EncoreEntryOptionListener($entryCollection); + return new EncoreEntryOptionListener($entryCollection, $translator); } public function testGetEntriesAsOptions()