feat: extract bookmarks as standalone module with MintyPHP\Module\Bookmarks namespace
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>
This commit is contained in:
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
|
||||
use MintyPHP\Http\SessionStoreInterface;
|
||||
use MintyPHP\Service\Bookmark\BookmarkService;
|
||||
|
||||
$bmSessionData = is_array(app(SessionStoreInterface::class)->get('user_bookmarks')) ? app(SessionStoreInterface::class)->get('user_bookmarks') : [];
|
||||
$bmSessionGroups = is_array($bmSessionData['groups'] ?? null) ? $bmSessionData['groups'] : [];
|
||||
|
||||
?>
|
||||
<dialog
|
||||
data-app-bookmark-dialog
|
||||
data-app-component="bookmark-save"
|
||||
data-max-message="<?php e(t('Maximum bookmarks reached')); ?>"
|
||||
data-title-create="<?php e(t('Bookmarks')); ?>"
|
||||
data-title-edit="<?php e(t('Bookmarks')); ?>"
|
||||
data-label-save="<?php e(t('Save')); ?>"
|
||||
data-label-update="<?php e(t('Save')); ?>"
|
||||
data-msg-saved="<?php e(t('Bookmark saved')); ?>"
|
||||
data-msg-updated="<?php e(t('Bookmark updated')); ?>"
|
||||
data-msg-group-created="<?php e(t('Group created')); ?>"
|
||||
data-msg-error-generic="<?php e(t('Bookmark action failed')); ?>"
|
||||
data-msg-group-create-failed="<?php e(t('Group action failed')); ?>"
|
||||
data-msg-name-required="<?php e(t('Bookmark name is required')); ?>"
|
||||
data-msg-url-required="<?php e(t('Bookmark URL is invalid')); ?>"
|
||||
data-msg-group-not-found="<?php e(t('Group not found')); ?>"
|
||||
aria-labelledby="app-bookmark-dialog-title"
|
||||
>
|
||||
<article class="app-bookmark-dialog">
|
||||
<header>
|
||||
<h2 id="app-bookmark-dialog-title"><?php e(t('Bookmarks')); ?></h2>
|
||||
<button type="button" class="close" data-bookmark-dialog-close aria-label="<?php e(t('Close')); ?>" title="<?php e(t('Close')); ?>"></button>
|
||||
</header>
|
||||
<form data-bookmark-save-form>
|
||||
<label for="bookmark-name"><?php e(t('Name')); ?></label>
|
||||
<input type="text" id="bookmark-name" name="name" maxlength="120" required
|
||||
placeholder="<?php e(t('Bookmark name')); ?>">
|
||||
<label for="bookmark-group"><?php e(t('Assign to group')); ?></label>
|
||||
<select id="bookmark-group" name="group_id" data-bookmark-group-select>
|
||||
<option value=""><?php e(t('No group')); ?></option>
|
||||
<?php foreach ($bmSessionGroups as $grp):
|
||||
$grpId = (int) ($grp['id'] ?? 0);
|
||||
$grpName = trim((string) ($grp['name'] ?? ''));
|
||||
if ($grpId <= 0 || $grpName === '') { continue; }
|
||||
?>
|
||||
<option value="<?php e($grpId); ?>"><?php e($grpName); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<button type="button" class="outline secondary app-bookmark-new-group-btn" data-bookmark-new-group>
|
||||
<i class="bi bi-plus"></i> <?php e(t('New group')); ?>
|
||||
</button>
|
||||
<footer>
|
||||
<button type="submit" class="app-action-success" data-bookmark-submit-label><?php e(t('Save')); ?></button>
|
||||
</footer>
|
||||
</form>
|
||||
</article>
|
||||
</dialog>
|
||||
|
||||
<dialog
|
||||
data-app-bookmark-group-dialog
|
||||
data-title-create="<?php e(t('New group')); ?>"
|
||||
data-title-edit="<?php e(t('Edit group')); ?>"
|
||||
data-label-save="<?php e(t('Save')); ?>"
|
||||
data-label-update="<?php e(t('Save')); ?>"
|
||||
data-max-message="<?php e(t('Maximum groups reached')); ?>"
|
||||
data-msg-created="<?php e(t('Group created')); ?>"
|
||||
data-msg-updated="<?php e(t('Group updated')); ?>"
|
||||
data-msg-error-generic="<?php e(t('Group action failed')); ?>"
|
||||
data-msg-name-required="<?php e(t('Group name is required')); ?>"
|
||||
aria-labelledby="app-bookmark-group-dialog-title"
|
||||
>
|
||||
<article class="app-bookmark-dialog app-bookmark-group-dialog">
|
||||
<header>
|
||||
<h2 id="app-bookmark-group-dialog-title"><?php e(t('New group')); ?></h2>
|
||||
<button type="button" class="close" data-bookmark-group-dialog-close aria-label="<?php e(t('Close')); ?>" title="<?php e(t('Close')); ?>"></button>
|
||||
</header>
|
||||
<form data-bookmark-group-save-form>
|
||||
<label for="bookmark-group-name"><?php e(t('Group name')); ?></label>
|
||||
<input type="text" id="bookmark-group-name" name="name" maxlength="100" required
|
||||
placeholder="<?php e(t('Group name')); ?>">
|
||||
<label><?php e(t('Icon')); ?></label>
|
||||
<div class="app-bookmark-group-icon-picker" data-bookmark-group-icon-picker>
|
||||
<?php foreach (BookmarkService::allowedGroupIcons() as $allowedIcon): ?>
|
||||
<button type="button" class="app-bookmark-group-icon-option"
|
||||
data-icon="<?php e($allowedIcon); ?>"
|
||||
aria-label="<?php e($allowedIcon); ?>">
|
||||
<i class="bi <?php e($allowedIcon); ?>"></i>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<input type="hidden" name="icon" value="bi-folder">
|
||||
<footer>
|
||||
<button type="submit" class="app-action-success" data-bookmark-group-submit-label><?php e(t('Save')); ?></button>
|
||||
</footer>
|
||||
</form>
|
||||
</article>
|
||||
</dialog>
|
||||
Reference in New Issue
Block a user