From dd34798c013e77e34c2f9d6b1f73484a241ae399 Mon Sep 17 00:00:00 2001 From: Jonathan Barbin Date: Sun, 21 Nov 2021 01:33:05 +0100 Subject: [PATCH] fix(fixtures): non existent data mapped for fields of type select --- assets/js/app/editor/Components/Select.vue | 21 ++++--- src/DataFixtures/ContentFixtures.php | 69 ++++++++++++++++++++++ src/Twig/FieldExtension.php | 11 ++++ 3 files changed, 94 insertions(+), 7 deletions(-) diff --git a/assets/js/app/editor/Components/Select.vue b/assets/js/app/editor/Components/Select.vue index 106489794..2f1b85984 100644 --- a/assets/js/app/editor/Components/Select.vue +++ b/assets/js/app/editor/Components/Select.vue @@ -103,15 +103,22 @@ export default { }, }, mounted() { - const _values = this.value.map ? this.value : [this.value]; + const _values = !this.value ? [] : this.value.map ? this.value : [this.value]; const _options = this.options; - let filterSelectedItems = _values.map(value => { - const item = _options.filter(opt => opt.key === value); - if (item) { - return item[0]; - } - }); + /** + * Filter method is necessary for required fields because the empty option is not + * set. If the field is empty, "filterSelectedItems" will contain an undefined + * element and "select" will not be filled with the first available option. + */ + let filterSelectedItems = _values + .map(value => { + const item = _options.filter(opt => opt.key === value); + if (item.length > 0) { + return item[0]; + } + }) + .filter(item => undefined !== item); if (filterSelectedItems.length === 0) { filterSelectedItems = [_options[0]]; diff --git a/src/DataFixtures/ContentFixtures.php b/src/DataFixtures/ContentFixtures.php index e5eff73e5..16bdb39d2 100644 --- a/src/DataFixtures/ContentFixtures.php +++ b/src/DataFixtures/ContentFixtures.php @@ -10,6 +10,7 @@ use Bolt\Configuration\FileLocations; use Bolt\Entity\Content; use Bolt\Entity\Field; +use Bolt\Entity\Field\SelectField; use Bolt\Enum\Statuses; use Bolt\Repository\FieldRepository; use Bolt\Utils\FakeContent; @@ -75,6 +76,8 @@ public function load(ObjectManager $manager): void $this->loadContent($manager); $manager->flush(); + + $this->setSelectFieldsMappedWithContent($manager); } private function loadContent(ObjectManager $manager): void @@ -366,6 +369,14 @@ private function getFieldTypeValue(DeepCollection $field, bool $singleton, Conte ]; } + break; + case 'select': + $data = []; + + if (isset($field['values']) && ($field['values'] instanceof ContentType)) { + $data = [\array_rand($field['values']->all())]; + } + break; default: $data = [$this->faker->sentence(6, true)]; @@ -474,4 +485,62 @@ private function getPreset(string $slug): array return $preset; } + + private function setSelectFieldsMappedWithContent(ObjectManager $manager): void + { + /** @var Content[] $allContent */ + $allContent = $manager->getRepository(Content::class)->findAll(); + + foreach ($allContent as $content) { + $contentDefaultLocale = $content->getDefaultLocale(); + $contentLocales = $content->getLocales(); + foreach ($content->getFields() as $field) { + if (! $this->isSelectFieldAndMappedWithContent($field)) { + continue; + } + + /** @var SelectField $field */ + $contentType = $field->getContentType(); + + if (! \is_string($contentType)) { + continue; + } + + try { + /** @var Content $randomReference */ + $randomReference = $this->getRandomReference(\sprintf('content_%s', $contentType)); + } catch (\Exception $exception) { + continue; + } + + $content->setFieldValue($field->getName(), [$randomReference->getId()], $this->defaultLocale); + + foreach ($contentLocales as $locale) { + if ( + $locale !== $contentDefaultLocale + && array_search($locale, $contentLocales->toArray(), true) !== (count($contentLocales) - 1) + ) { + $content->setFieldValue($field->getName(), [$randomReference->getId()], $locale); + } + } + } + + $manager->persist($content); + } + + $manager->flush(); + } + + private function isSelectFieldAndMappedWithContent(Field $field): bool + { + if (! $field instanceof SelectField) { + return FALSE; + } + + if (! $field->isContentSelect()) { + return FALSE; + } + + return TRUE; + } } diff --git a/src/Twig/FieldExtension.php b/src/Twig/FieldExtension.php index 011046be0..f043905a5 100644 --- a/src/Twig/FieldExtension.php +++ b/src/Twig/FieldExtension.php @@ -307,6 +307,17 @@ private function selectOptionsContentTypeCache(string $contentTypeSlug, array $p $options = []; + // We need to add this as a 'dummy' option for when the user is allowed + // not to pick an option. This is needed, because otherwise the `select` + // would default to the one. + if (! $field->getDefinition()->get('required', true)) { + $options[] = [ + 'key' => '', + 'value' => '', + 'selected' => false, + ]; + } + foreach ($records as $record) { if ($field->getDefinition()->get('mode') === 'format') { $formattedKey = $this->contentHelper->get($record, $field->getDefinition()->get('format'));