From 9aebe9c472e94a0eed64eb4643f82c7057d614b4 Mon Sep 17 00:00:00 2001 From: Bob den Otter Date: Fri, 8 Sep 2023 13:18:40 +0200 Subject: [PATCH] Working --- config/bolt/config.yaml | 3 +- config/bolt/contenttypes.yaml | 1 + src/Command/ClearListFormatCommand.php | 62 ++++++++++++++++ src/Command/UpdateListFormatCommand.php | 64 ++++++++++++++++ .../Parser/ContentTypesParser.php | 8 +- src/DataFixtures/ContentFixtures.php | 9 ++- src/Entity/Content.php | 44 +++++++++++ src/Entity/ContentExtrasTrait.php | 1 + src/Twig/ContentExtension.php | 11 ++- src/Utils/ListFormatHelper.php | 73 +++++++++++++++++++ templates/content/_taxonomies.html.twig | 8 +- 11 files changed, 273 insertions(+), 11 deletions(-) create mode 100644 src/Command/ClearListFormatCommand.php create mode 100644 src/Command/UpdateListFormatCommand.php create mode 100644 src/Utils/ListFormatHelper.php diff --git a/config/bolt/config.yaml b/config/bolt/config.yaml index 0f8cb737b..0329913ec 100644 --- a/config/bolt/config.yaml +++ b/config/bolt/config.yaml @@ -30,6 +30,7 @@ caching: frontend_menu: ~ backend_menu: ~ files_index: ~ + list_format: true # The theme to use. # @@ -256,4 +257,4 @@ reset_password_settings: user_show_sort&filter: true # Use Ajaxy saving ("Stay on page"), or traditional saving -ajaxy_saving: true +ajaxy_saving: false diff --git a/config/bolt/contenttypes.yaml b/config/bolt/contenttypes.yaml index b12241714..045978373 100644 --- a/config/bolt/contenttypes.yaml +++ b/config/bolt/contenttypes.yaml @@ -66,6 +66,7 @@ pages: singular_name: Page title_format: '{heading} - {subheading}' excerpt_format: '📦 {teaser}' + list_format: '{contenttype} Nº {id}: {title} - {status}' fields: heading: type: text diff --git a/src/Command/ClearListFormatCommand.php b/src/Command/ClearListFormatCommand.php new file mode 100644 index 000000000..3b9a34afc --- /dev/null +++ b/src/Command/ClearListFormatCommand.php @@ -0,0 +1,62 @@ +listFormatHelper = $listFormatHelper; + + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + protected function configure(): void + { + $this + ->setDescription('Clear Bolt\'s cached ListFormat data. ') + ->setHelp( + <<<'HELP' +The %command.name% command clears the `list_format` and `title` columns in the database. Be sure to run `bolt:update-list-format` afterwards. +HELP + ); + } + + /** + * This method is executed after initialize(). It usually contains the logic + * to execute to complete this command task. + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + + $io->text('// Clearing the Bolt Content `list_format` and `title` columns.'); + + $success = $this->listFormatHelper->clearColumns(); + + if ($success) { + $io->success('Cleared successfully. Be sure to run `bolt:update-list-format` next.'); + } else { + $io->warning('Not all the rows could be cleared successfully. Remove them manually'); + } + + return Command::SUCCESS; + } +} diff --git a/src/Command/UpdateListFormatCommand.php b/src/Command/UpdateListFormatCommand.php new file mode 100644 index 000000000..6bef5751c --- /dev/null +++ b/src/Command/UpdateListFormatCommand.php @@ -0,0 +1,64 @@ +listFormatHelper = $listFormatHelper; + + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + protected function configure(): void + { + $this + ->setDescription('Update Bolt\'s cached ListFormat data. ') + ->setHelp( + <<<'HELP' +The %command.name% updates clears the `list_format` and `title` columns in the database. +HELP + ); + // ->addArgument('amount', InputArgument::OPTIONAL, 'The number of rows to update in one invocation', 100); + + } + + /** + * This method is executed after initialize(). It usually contains the logic + * to execute to complete this command task. + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + + $io->text('// Clearing the Bolt Content `list_format` and `title` columns.'); + + $amount = 10000; + + $success = $this->listFormatHelper->updateColumns($amount); + + if ($success) { + $io->success('Rows updated successfully.'); + } else { + $io->warning('Not all the rows could be cleared successfully. Remove them manually'); + } + + return Command::SUCCESS; + } +} diff --git a/src/Configuration/Parser/ContentTypesParser.php b/src/Configuration/Parser/ContentTypesParser.php index bf77a7d25..8134f6e0a 100644 --- a/src/Configuration/Parser/ContentTypesParser.php +++ b/src/Configuration/Parser/ContentTypesParser.php @@ -195,13 +195,15 @@ protected function parseContentType($key, array $contentType): ?ContentType } // Make sure title_format is set - if (isset($contentType['title_format'])) { - $contentType['title_format'] = $contentType['title_format']; - } else { + if (! isset($contentType['title_format'])) { $fields = $contentType['fields']['slug']['uses']; $contentType['title_format'] = '{' . implode('} {', $fields) . '}'; } + if (! isset($contentType['list_format'])) { + $contentType['list_format'] = '[{contenttype} Nº{id} - {status}] {title}'; + } + // Make sure taxonomy is an array. if (isset($contentType['taxonomy'])) { $contentType['taxonomy'] = (array) $contentType['taxonomy']; diff --git a/src/DataFixtures/ContentFixtures.php b/src/DataFixtures/ContentFixtures.php index 249fd9ad5..859b8a86f 100644 --- a/src/DataFixtures/ContentFixtures.php +++ b/src/DataFixtures/ContentFixtures.php @@ -13,6 +13,7 @@ use Bolt\Entity\Field\SelectField; use Bolt\Enum\Statuses; use Bolt\Repository\FieldRepository; +use Bolt\Twig\ContentExtension; use Bolt\Utils\FakeContent; use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface; use Doctrine\Common\DataFixtures\DependentFixtureInterface; @@ -45,7 +46,10 @@ class ContentFixtures extends BaseFixture implements DependentFixtureInterface, /** @var TagAwareCacheInterface */ private $cache; - public function __construct(Config $config, FileLocations $fileLocations, TagAwareCacheInterface $cache, string $defaultLocale) + /** @var ContentExtension */ + private $contentExtension; + + public function __construct(Config $config, FileLocations $fileLocations, TagAwareCacheInterface $cache, string $defaultLocale, ContentExtension $contentExtension) { $this->config = $config; $this->faker = Factory::create(); @@ -58,6 +62,7 @@ public function __construct(Config $config, FileLocations $fileLocations, TagAwa $this->fileLocations = $fileLocations; $this->defaultLocale = $defaultLocale; $this->cache = $cache; + $this->contentExtension = $contentExtension; } public function getDependencies() @@ -115,6 +120,8 @@ private function loadContent(ObjectManager $manager): void $content->setModifiedAt($this->faker->dateTimeBetween('-1 year')); $content->setPublishedAt($this->faker->dateTimeBetween('-1 year')); + $content->setContentExtension($this->contentExtension); + $preset = $this->getPreset($contentType['slug']); if ($i === 1 || ! empty($preset)) { diff --git a/src/Entity/Content.php b/src/Entity/Content.php index d947da7af..fb7a75f64 100644 --- a/src/Entity/Content.php +++ b/src/Entity/Content.php @@ -14,6 +14,7 @@ use Bolt\Entity\Field\SetField; use Bolt\Enum\Statuses; use Bolt\Repository\FieldRepository; +use Bolt\Utils\ContentHelper; use DateTimeZone; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -121,6 +122,16 @@ class Content */ private $depublishedAt = null; + /** + * @ORM\Column(type="string", length=191, nullable=true) + */ + private $title; + + /** + * @ORM\Column(type="string", length=191, nullable=true) + */ + private $listFormat; + /** * @var Collection|Field[] * @@ -165,6 +176,11 @@ class Content */ private $relationsToThisContent; + /** + * @var ContentHelper + */ + private $contentHelper; + public function __construct(?ContentType $contentTypeDefinition = null) { $this->createdAt = $this->convertToUTCFromLocal(new \DateTime()); @@ -872,4 +888,32 @@ private function getFieldValuesFromDefinition(): ?array return $fieldValues; } + + /** + * @ORM\PrePersist() + * @ORM\PreUpdate() + */ + public function setTitle(): self + { + $this->title = $this->getExtras()['title']; + + return $this; + } + + public function getListFormat(): ?string + { + return $this->listFormat; + } + + /** + * @ORM\PrePersist() + * @ORM\PreUpdate() + */ + public function setListFormat(): self + { + $this->listFormat = $this->getExtras()['listFormat']; + + return $this; + } + } diff --git a/src/Entity/ContentExtrasTrait.php b/src/Entity/ContentExtrasTrait.php index 481559b4a..3cba1f3bc 100644 --- a/src/Entity/ContentExtrasTrait.php +++ b/src/Entity/ContentExtrasTrait.php @@ -34,6 +34,7 @@ public function getExtras(): array 'title' => $this->contentExtension->getAnyTitle($content, 80), 'image' => $this->contentExtension->getImage($content, true), 'excerpt' => $this->contentExtension->getExcerpt($content), + 'listFormat' => $this->contentExtension->getListFormat($content), 'link' => $this->contentExtension->getLink($content), 'editLink' => $this->contentExtension->getEditLink($content), 'statusLink' => $this->contentExtension->getStatusLink($content), diff --git a/src/Twig/ContentExtension.php b/src/Twig/ContentExtension.php index 97823a10f..688ffbac9 100644 --- a/src/Twig/ContentExtension.php +++ b/src/Twig/ContentExtension.php @@ -268,7 +268,8 @@ public function getExcerpt($content, int $length = 280, bool $includeTitle = fal } if (ContentHelper::isSuitable($content, 'excerpt_format')) { - $excerpt = $this->contentHelper->get($content, $content->getDefinition()->get('excerpt_format'), $this->requestStack->getCurrentRequest()->getLocale()); + $locale = $this->requestStack->getCurrentRequest() ? $this->requestStack->getCurrentRequest()->getLocale() : null; + $excerpt = $this->contentHelper->get($content, $content->getDefinition()->get('excerpt_format'), $locale); } else { $excerpt = $this->getFieldBasedExcerpt($content, $length, $includeTitle); } @@ -284,6 +285,14 @@ public function getExcerpt($content, int $length = 280, bool $includeTitle = fal return $pre . Excerpt::getExcerpt($excerpt, $length, $focus) . $post; } + public function getListFormat($content) + { + $listFormat = $this->contentHelper->get($content, $content->getDefinition()->get('list_format')); + + return $listFormat; + } + + private function getFieldBasedExcerpt(Content $content, int $length, bool $includeTitle = false): string { $excerptParts = []; diff --git a/src/Utils/ListFormatHelper.php b/src/Utils/ListFormatHelper.php new file mode 100644 index 000000000..f925cdf57 --- /dev/null +++ b/src/Utils/ListFormatHelper.php @@ -0,0 +1,73 @@ +config = $config; + $this->connection = $connection; + $this->prefix = $tablePrefix; + $this->contentRepository = $contentRepository; + $this->em = $em; + } + + public function clearColumns(): bool + { + $query = sprintf('UPDATE %scontent SET title = "", list_format = ""', $this->prefix); + $result = $this->connection->executeQuery($query); + + return (bool) $result; + } + + public function updateColumns(int $limit = 100): bool + { + $query = sprintf('SELECT id FROM %scontent WHERE title = "" OR list_format = "" LIMIT %d', $this->prefix, $limit); + + $rows = $this->connection->fetchAllAssociative($query); + + $counter = 0; + + foreach ($rows as $row) { + $record = $this->contentRepository->findOneById($row['id']); + + $record->setListFormat(); + $this->em->persist($record); + + + $counter++; + if ($counter > 20) { + echo '.'; + $this->em->flush(); + $counter = 0; + } + + } + + $this->em->flush(); + + return true; + } + +} diff --git a/templates/content/_taxonomies.html.twig b/templates/content/_taxonomies.html.twig index 51b8aab3c..185600485 100644 --- a/templates/content/_taxonomies.html.twig +++ b/templates/content/_taxonomies.html.twig @@ -30,7 +30,7 @@ {% endif %} - {% if definition.has_sortorder %}
{% else %}
{% endif %} + {% if definition.has_sortorder %}
{% else %}
{% endif %} -
{% if definition.has_sortorder %} -
-
+
-
{% endif %} +
{# Print postfix #} {% if definition['postfix']|default() is not empty %}