Skip to content

Commit 9549759

Browse files
committed
Release 1.2.0: sectioned blog settings and select fields.
Listing mode, card layout and hero image use selects; settings split into section routes with portable admin tabs. Demo MySQL driver/host fixes.
1 parent 65324fa commit 9549759

26 files changed

Lines changed: 774 additions & 156 deletions

demo/symfony8/.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ DEFAULT_URI=http://localhost:8105
2222
###< symfony/routing ###
2323

2424
###> doctrine/doctrine-bundle ###
25-
# DATABASE_URL: MySQL inside Compose (service hostname `db`). Do not use sqlite:// or *.db files in demos.
25+
# DATABASE_URL: MySQL inside Compose (service hostname `database`). Do not use sqlite:// or *.db files in demos.
2626
DATABASE_URL=mysql://app:app@database:3306/app?serverVersion=8.4&charset=utf8mb4
2727
###< doctrine/doctrine-bundle ###

demo/symfony8/.env.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
KERNEL_CLASS='App\Kernel'
22
APP_SECRET=test-secret
3-
DATABASE_URL=mysql://app:app@db:3306/app?serverVersion=8.4&charset=utf8mb4
3+
DATABASE_URL=mysql://app:app@database:3306/app?serverVersion=8.4&charset=utf8mb4

demo/symfony8/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
FROM dunglas/frankenphp:1-php8.5-alpine
22

33
RUN apk add --no-cache git unzip bash sqlite
4-
RUN install-php-extensions intl zip pdo_sqlite
4+
RUN install-php-extensions intl zip pdo_sqlite pdo_mysql
55

66
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
77
RUN git config --global --add safe.directory /app && \

demo/symfony8/composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## Table of contents
99

1010
- [Unreleased](#unreleased)
11+
- [1.2.0 - 2026-08-28](#120---2026-08-28)
1112
- [1.1.6 - 2026-08-19](#116---2026-08-19)
1213
- [1.1.5 - 2026-08-19](#115---2026-08-19)
1314
- [1.1.3 - 2026-08-19](#113---2026-08-19)
@@ -19,6 +20,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1920
## [Unreleased]
2021

2122

23+
## [1.2.0] - 2026-08-28
24+
25+
### Changed
26+
27+
- **Admin blog settings:** split into section routes (`/admin/blog/settings/{listing|cards|index-aside|article|comments}`); `/admin/blog/settings` redirects to listing.
28+
- **`BlogSettingsType`:** optional `section` form option; `listingMode`, `masonryStrategy`, and `heroImageMode` render as `<select>` (`expanded: false`).
29+
- **`BlogKitAdminAccessSubscriber`:** authorize all `admin_blog_settings*` routes via `canConfigure`.
30+
- **Templates:** portable area nav, section tabs, and sectioned settings UI (`_area_nav`, `_settings_section_tabs`, `_nav_tabs`).
31+
32+
### Fixed
33+
34+
- **Demo (symfony8):** install `pdo_mysql` so Compose MySQL `DATABASE_URL` works (REQ-DEMO-011).
35+
36+
### Notes
37+
38+
- Hosts that overrode settings with a custom controller/form for section tabs can remove those overrides and use the bundle routes/form.
39+
- Override Twig templates if you need host-specific admin chrome; form fields come from `BlogSettingsType`.
40+
41+
[1.2.0]: https://github.com/nowo-tech/BlogKitBundle/releases/tag/v1.2.0
42+
2243
## [1.1.7] - 2026-08-24
2344

2445
### Changed

docs/UPGRADING.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This document describes how to upgrade **Blog Kit Bundle** between released vers
55
## Table of contents
66

77

8+
- [From 1.1.7 to 1.2.0](#from-117-to-120)
89
- [From 1.1.6 to 1.1.7](#from-116-to-117)
910
- [Unreleased](#unreleased)
1011
- [1.1.6](#116)
@@ -16,14 +17,24 @@ This document describes how to upgrade **Blog Kit Bundle** between released vers
1617
- [1.0.0](#100)
1718
- [Future releases](#future-releases)
1819

19-
## From 1.1.6 to 1.1.7
20+
## From 1.1.7 to 1.2.0
2021

21-
No breaking changes. **No application upgrade steps.**
22+
### Breaking / behaviour changes
23+
24+
- **`admin_blog_settings` (GET)** redirects to `admin_blog_settings_listing`. There is no longer a single-page POST on `/admin/blog/settings`.
25+
- New routes: `admin_blog_settings_listing`, `_cards`, `_index_aside`, `_article`, `_comments`.
26+
- **`BlogSettingsType`:** `listingMode`, `masonryStrategy`, and `heroImageMode` are selects (not radio groups). Pass `section` (`listing`|`cards`|`index-aside`|`article`|`comments`) to build one tab; omit for the full form (BC for tests/API).
27+
28+
### Upgrade steps
2229

2330
```bash
2431
composer update nowo-tech/blog-kit-bundle
2532
```
2633

34+
1. Remove host overrides that duplicated sectioned settings (`HostBlogSettingsController`, custom section form) if present.
35+
2. Clear router/Twig cache and smoke-test `/admin/blog/settings`.
36+
3. If you styled radio lists for listing/masonry choices, switch CSS to select widgets.
37+
2738
## From 1.1.6 to 1.1.7
2839

2940
No breaking changes. **No application upgrade steps.**

rector.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
declare(strict_types=1);
44

55
use Rector\Config\RectorConfig;
6+
use Rector\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector;
67
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPublicMethodParameterRector;
78

89
return RectorConfig::configure()
@@ -15,6 +16,10 @@
1516
RemoveUnusedPublicMethodParameterRector::class => [
1617
__DIR__ . '/src/Doctrine/AuditableEntityListener.php',
1718
],
19+
// Symfony 7.4 UserInterface still requires eraseCredentials(); removed in Symfony 8.
20+
RemoveEmptyClassMethodRector::class => [
21+
__DIR__ . '/tests/Support/TestUser.php',
22+
],
1823
])
1924
->withPhpSets(php81: true)
2025
->withPreparedSets(

src/Controller/Admin/BlogSettingsController.php

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,88 @@
88
use Nowo\BlogKitBundle\Form\BlogSettingsType;
99
use Nowo\BlogKitBundle\Repository\BlogSettingsRepository;
1010
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
11+
use Symfony\Component\HttpFoundation\RedirectResponse;
1112
use Symfony\Component\HttpFoundation\Request;
1213
use Symfony\Component\HttpFoundation\Response;
1314
use Symfony\Component\Routing\Attribute\Route;
1415

1516
/**
16-
* Admin singleton form for professional blog configuration.
17+
* Admin singleton form for professional blog configuration (one path per section).
1718
*/
1819
final class BlogSettingsController extends AbstractController
1920
{
21+
/** @var array<string, string> */
22+
private const array SECTION_ROUTES = [
23+
BlogSettingsType::SECTION_LISTING => 'admin_blog_settings_listing',
24+
BlogSettingsType::SECTION_CARDS => 'admin_blog_settings_cards',
25+
BlogSettingsType::SECTION_INDEX_ASIDE => 'admin_blog_settings_index_aside',
26+
BlogSettingsType::SECTION_ARTICLE => 'admin_blog_settings_article',
27+
BlogSettingsType::SECTION_COMMENTS => 'admin_blog_settings_comments',
28+
];
29+
2030
public function __construct(
2131
private readonly BlogSettingsRepository $blogSettingsRepository,
2232
private readonly EntityManagerInterface $entityManager,
2333
) {
2434
}
2535

26-
#[Route('/admin/blog/settings', name: 'admin_blog_settings', methods: ['GET', 'POST'])]
27-
public function settings(Request $request): Response
36+
#[Route('/admin/blog/settings', name: 'admin_blog_settings', methods: ['GET'])]
37+
public function settings(): RedirectResponse
38+
{
39+
return $this->redirectToRoute('admin_blog_settings_listing');
40+
}
41+
42+
#[Route('/admin/blog/settings/listing', name: 'admin_blog_settings_listing', methods: ['GET', 'POST'])]
43+
public function listing(Request $request): Response
44+
{
45+
return $this->handleSection($request, BlogSettingsType::SECTION_LISTING);
46+
}
47+
48+
#[Route('/admin/blog/settings/cards', name: 'admin_blog_settings_cards', methods: ['GET', 'POST'])]
49+
public function cards(Request $request): Response
50+
{
51+
return $this->handleSection($request, BlogSettingsType::SECTION_CARDS);
52+
}
53+
54+
#[Route('/admin/blog/settings/index-aside', name: 'admin_blog_settings_index_aside', methods: ['GET', 'POST'])]
55+
public function indexAside(Request $request): Response
56+
{
57+
return $this->handleSection($request, BlogSettingsType::SECTION_INDEX_ASIDE);
58+
}
59+
60+
#[Route('/admin/blog/settings/article', name: 'admin_blog_settings_article', methods: ['GET', 'POST'])]
61+
public function article(Request $request): Response
62+
{
63+
return $this->handleSection($request, BlogSettingsType::SECTION_ARTICLE);
64+
}
65+
66+
#[Route('/admin/blog/settings/comments', name: 'admin_blog_settings_comments', methods: ['GET', 'POST'])]
67+
public function comments(Request $request): Response
68+
{
69+
return $this->handleSection($request, BlogSettingsType::SECTION_COMMENTS);
70+
}
71+
72+
private function handleSection(Request $request, string $section): Response
2873
{
2974
$blogSettings = $this->blogSettingsRepository->getSingleton();
30-
$form = $this->createForm(BlogSettingsType::class, $blogSettings);
75+
$route = self::SECTION_ROUTES[$section];
76+
$form = $this->createForm(BlogSettingsType::class, $blogSettings, [
77+
BlogSettingsType::OPTION_SECTION => $section,
78+
]);
3179
$form->handleRequest($request);
3280

3381
if ($form->isSubmitted() && $form->isValid()) {
3482
$this->entityManager->flush();
3583
$this->blogSettingsRepository->reset();
3684
$this->addFlash('success', 'admin.flash.settings_saved');
3785

38-
return $this->redirectToRoute('admin_blog_settings');
86+
return $this->redirectToRoute($route);
3987
}
4088

4189
return $this->render('@NowoBlogKitBundle/admin/settings.html.twig', [
42-
'page_title' => 'admin.settings.title',
43-
'form' => $form,
90+
'page_title' => 'admin.settings.title',
91+
'form' => $form,
92+
'edit_section' => $section,
4493
]);
4594
}
4695
}

src/EventSubscriber/BlogKitAdminAccessSubscriber.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function onKernelController(ControllerEvent $event): void
4444
return;
4545
}
4646

47-
if ($route === 'admin_blog_settings') {
47+
if (str_starts_with($route, 'admin_blog_settings')) {
4848
if (!$this->accessChecker->canConfigure()) {
4949
throw new AccessDeniedException('Blog settings require an authorized user.');
5050
}

0 commit comments

Comments
 (0)