Moves bookmarks from core hardcoding into modules/bookmarks/ as a
fully self-contained module, following the same pattern as addressbook.
Module contributions via platform slots:
- aside.tab_panel: bookmark sidebar panel
- topbar.right_item: bookmark toggle button
- layout.body_end_template: bookmark/group dialogs
- layout.head_style: bookmark CSS (form + sidebar)
- runtime.component: bookmark-save and bookmark-panel (phase: late)
- search.resource_item: bookmarks in global search (user-scoped via {{userId}})
Backend fully in module namespace (MintyPHP\Module\Bookmarks\*):
- Service: BookmarkService, BookmarkServicesFactory, BookmarkRepositoryFactory
- Repository: BookmarkRepository, BookmarkGroupRepository, BookmarkNavigationRepository
- Support: BookmarkUrlNormalizer
- Providers: BookmarksSessionProvider, BookmarksLayoutProvider, BookmarksSearchProvider
Core cleanup:
- Removed all bookmark-specific markup from core templates
- Removed core DI registrations for bookmark services
- Removed core bookmark pages, JS, CSS
- AuthSessionTenantContextService delegates to module SessionProvider
Architecture guards:
- NoBookmarksHardcodingTest: verifies zero bookmark references in core
- testModuleClassesUseModuleNamespace: prevents core namespace leakage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
47 lines
2.1 KiB
PHTML
47 lines
2.1 KiB
PHTML
<?php
|
|
|
|
use MintyPHP\Module\Bookmarks\Support\BookmarkUrlNormalizer;
|
|
|
|
$layoutNav = is_array($layoutNav ?? null) ? $layoutNav : [];
|
|
$bookmarkNav = is_array($layoutNav['bookmarks.nav'] ?? null) ? $layoutNav['bookmarks.nav'] : [];
|
|
$bookmarkData = is_array($bookmarkNav['grouped'] ?? null) ? $bookmarkNav['grouped'] : ['groups' => [], 'ungrouped' => []];
|
|
$bookmarkGroups = is_array($bookmarkData['groups'] ?? null) ? $bookmarkData['groups'] : [];
|
|
$bookmarkUngrouped = is_array($bookmarkData['ungrouped'] ?? null) ? $bookmarkData['ungrouped'] : [];
|
|
$currentPath = trim((string) ($bookmarkNav['current_path'] ?? ''));
|
|
|
|
$existing = null;
|
|
if ($currentPath !== '') {
|
|
foreach ($bookmarkUngrouped as $bookmark) {
|
|
$bookmarkUrl = BookmarkUrlNormalizer::canonicalizeRelative((string) ($bookmark['url'] ?? ''));
|
|
if ($bookmarkUrl !== '' && $bookmarkUrl === $currentPath) {
|
|
$existing = $bookmark;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($existing === null) {
|
|
foreach ($bookmarkGroups as $group) {
|
|
foreach ((is_array($group['bookmarks'] ?? null) ? $group['bookmarks'] : []) as $bookmark) {
|
|
$bookmarkUrl = BookmarkUrlNormalizer::canonicalizeRelative((string) ($bookmark['url'] ?? ''));
|
|
if ($bookmarkUrl !== '' && $bookmarkUrl === $currentPath) {
|
|
$existing = $bookmark;
|
|
break 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
?>
|
|
<li>
|
|
<button type="button" data-bookmark-open-dialog
|
|
aria-label="<?php e($existing ? t('Edit bookmark') : t('Bookmarks')); ?>"
|
|
data-tooltip="<?php e($existing ? t('Edit bookmark') : t('Bookmarks')); ?>" data-tooltip-pos="bottom"
|
|
<?php if ($existing): ?>
|
|
data-bookmark-existing-id="<?php e((int) ($existing['id'] ?? 0)); ?>"
|
|
data-bookmark-existing-name="<?php e(trim((string) ($existing['name'] ?? ''))); ?>"
|
|
data-bookmark-existing-group="<?php e($existing['group_id'] ?? ''); ?>"
|
|
<?php endif; ?>>
|
|
<i class="bi <?php e($existing ? 'bi-bookmark-check-fill' : 'bi-bookmark-plus'); ?>"></i>
|
|
</button>
|
|
</li>
|