diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache index e119f96..828a6dd 100644 --- a/.php-cs-fixer.cache +++ b/.php-cs-fixer.cache @@ -1 +1 @@ -{"php":"8.3.25","version":"3.64.0:v3.64.0#58dd9c931c785a79739310aef5178928305ffa67","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":true,"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"array_syntax":{"syntax":"short"},"no_unused_imports":true,"single_quote":true,"trailing_comma_in_multiline":true},"hashes":{"fragments\/QuickNavigation\/Dropdown.php":"7cc52d767a1b8fa704e4d89c9a3e48a7","fragments\/QuickNavigation\/List.php":"e90ddecd29ce153eec1083841a3088e2","fragments\/QuickNavigation\/NoResult.php":"9b879a1abf902a8aa81cb9e6ce5d921a","fragments\/QuickNavigation\/MinibarList.php":"6c40eb3f991f48d730f45b8d222914b1","pages\/config.php":"cae53f73bf533cc8bb59dadf1cbdebe4","pages\/index.php":"daf2b1a819e7a27391553c599d053802","lib\/LinkMap\/QuickNavigationLinkMap.php":"3060d0975067e724f1dd427eadb02d47","lib\/Utility\/BuildNavigationArray.php":"d2a23cc394de4fd4e83bb34da8b3c0bc","lib\/Minibar\/ArticleHistoryElement.php":"fa606bdfb8e44afdcd46695f36b5d327","lib\/QuickNavigationApi.php":"4eabc25eae94790b9095085102dc278a","lib\/ApiFunction\/MenuRender.php":"fa555351a229780f110eba970ed42a59","lib\/ApiFunction\/MediaSearch.php":"04d4e816aa6766f1f2bf889482187287","lib\/Button\/FavoriteButton.php":"c8163f9adb12699453fe458de325515e","lib\/Button\/ButtonRegistry.php":"0ecf7951feeb0b3524fa1b8c92ac6288","lib\/Button\/YformButton.php":"cb3c1d7608735d18b5732b7425f3c14a","lib\/Button\/ArticleHistoryButton.php":"3851f59535b0647f184a5d706da08aba","lib\/Button\/ButtonInterface.php":"943bf3db82d39b6854401e16fe7e36b6","lib\/Button\/ArticleNavigationButton.php":"a81f2e97e73f235cba29ffcad4db1854","lib\/Button\/WatsonButton.php":"ef0d3641591e83b6e7dfec54008e36a8","lib\/Button\/CategoryButton.php":"3854696ad9b32dffad7d25d881fd2b18","lib\/Media\/MediaSorter.php":"4af98d56992a2e58b4d440ff1545af50","lib\/Media\/QuickNavigationMedia.php":"aa21d3042a12fc77d87e15ccb9c66319","lib\/QuickNavigation.php":"9a208b43632faa9d39923ff64c22f056","update.php":"d6e8377314743b0306a045ec165b99ea","boot.php":"85e4410621c51370487316f2c7de01b4"}} \ No newline at end of file +{"php":"8.4.12","version":"3.64.0:v3.64.0#58dd9c931c785a79739310aef5178928305ffa67","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":true,"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"array_syntax":{"syntax":"short"},"no_unused_imports":true,"single_quote":true,"trailing_comma_in_multiline":true},"hashes":{"update.php":"599fd370563dc5811b440c0ae86309d7","fragments\/QuickNavigation\/NoResult.php":"9b879a1abf902a8aa81cb9e6ce5d921a","fragments\/QuickNavigation\/MinibarList.php":"6c40eb3f991f48d730f45b8d222914b1","fragments\/QuickNavigation\/List.php":"e90ddecd29ce153eec1083841a3088e2","fragments\/QuickNavigation\/Dropdown.php":"7cc52d767a1b8fa704e4d89c9a3e48a7","lib\/QuickNavigationApi.php":"4eabc25eae94790b9095085102dc278a","lib\/ApiFunction\/MenuRender.php":"fa555351a229780f110eba970ed42a59","lib\/ApiFunction\/MediaSearch.php":"04d4e816aa6766f1f2bf889482187287","lib\/QuickNavigation.php":"9a208b43632faa9d39923ff64c22f056","lib\/Minibar\/ArticleHistoryElement.php":"fa606bdfb8e44afdcd46695f36b5d327","lib\/Button\/ArticleNavigationButton.php":"a81f2e97e73f235cba29ffcad4db1854","lib\/Button\/YformButton.php":"cb3c1d7608735d18b5732b7425f3c14a","lib\/Button\/ButtonInterface.php":"943bf3db82d39b6854401e16fe7e36b6","lib\/Button\/ButtonRegistry.php":"0ecf7951feeb0b3524fa1b8c92ac6288","lib\/Button\/WatsonButton.php":"ef0d3641591e83b6e7dfec54008e36a8","lib\/Button\/ArticleHistoryButton.php":"3851f59535b0647f184a5d706da08aba","lib\/Button\/FavoriteButton.php":"c8163f9adb12699453fe458de325515e","lib\/Button\/CategoryButton.php":"3854696ad9b32dffad7d25d881fd2b18","lib\/LinkMap\/QuickNavigationLinkMap.php":"3060d0975067e724f1dd427eadb02d47","lib\/Utility\/BuildNavigationArray.php":"d2a23cc394de4fd4e83bb34da8b3c0bc","lib\/Media\/QuickNavigationMedia.php":"aa21d3042a12fc77d87e15ccb9c66319","lib\/Media\/MediaSorter.php":"4af98d56992a2e58b4d440ff1545af50","boot.php":"85e4410621c51370487316f2c7de01b4","pages\/index.php":"daf2b1a819e7a27391553c599d053802","pages\/config.php":"cae53f73bf533cc8bb59dadf1cbdebe4"}} diff --git a/assets/quick-navigation.css b/assets/quick-navigation.css index 149ce63..402094f 100644 --- a/assets/quick-navigation.css +++ b/assets/quick-navigation.css @@ -152,3 +152,65 @@ { color: var(--quick-navigation-color-offline); } + +/* Favoriten Sections */ +.quick-navigation-section-header { + padding: 10px 12px 6px; + font-weight: 600; + font-size: 11px; + text-transform: uppercase; + color: #666; + background-color: #f5f5f5; + border-top: 1px solid #e0e0e0; + margin: 0; +} + +.quick-navigation-section-header:first-child { + border-top: none; +} + +.quick-navigation-section-divider { + display: none; +} + +.quick-navigation-addon-fav { + padding: 0; +} + +.quick-navigation-addon-fav a { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 12px; + color: inherit; + text-decoration: none; +} + +.quick-navigation-addon-fav a:hover { + background-color: #f0f0f0; +} + +.quick-navigation-addon-fav a i { + width: 16px; + text-align: center; + flex-shrink: 0; +} + +/* Dark Theme Support */ +.rex-theme-dark .quick-navigation-section-header { + color: #aaa; + background-color: #2a2d33; + border-top-color: #404040; +} + +.rex-theme-dark .quick-navigation-addon-fav a:hover { + background-color: #35383e; +} + +.rex-theme-dark .quick-navigation-menu-header { + border-bottom-color: #404040; +} + +.rex-theme-dark .quick-navigation-no-results { + background-color: rgba(42, 45, 51, 0.59); +} diff --git a/boot.php b/boot.php index ebb0b4d..78cc1c7 100644 --- a/boot.php +++ b/boot.php @@ -51,14 +51,44 @@ $userId = rex::getUser()->getId(); if (rex_addon::get('quick_navigation')->getConfig('quick_navigation_artdirections' . $userId) != '1') { - ButtonRegistry::registerButton(new ArticleNavigationButton(), 10); + ButtonRegistry::registerButton( + new ArticleNavigationButton(), + 10, + 'article_navigation', + rex_addon::get('quick_navigation')->i18n('quick_navigation_button_article_navigation') + ); } - ButtonRegistry::registerButton(new WatsonButton(), 20); - ButtonRegistry::registerButton(new CategoryButton(), 30); - ButtonRegistry::registerButton(new ArticleHistoryButton('structure', 20), 40); - ButtonRegistry::registerButton(new YformButton(), 50); - ButtonRegistry::registerButton(new FavoriteButton(), 60); + ButtonRegistry::registerButton( + new WatsonButton(), + 20, + 'watson', + rex_addon::get('quick_navigation')->i18n('quick_navigation_button_watson') + ); + ButtonRegistry::registerButton( + new CategoryButton(), + 30, + 'category', + rex_addon::get('quick_navigation')->i18n('quick_navigation_button_category') + ); + ButtonRegistry::registerButton( + new ArticleHistoryButton('structure', 20), + 40, + 'article_history', + rex_addon::get('quick_navigation')->i18n('quick_navigation_button_article_history') + ); + ButtonRegistry::registerButton( + new YformButton(), + 50, + 'yform', + rex_addon::get('quick_navigation')->i18n('quick_navigation_button_yform') + ); + ButtonRegistry::registerButton( + new FavoriteButton(), + 60, + 'favorite', + rex_addon::get('quick_navigation')->i18n('quick_navigation_button_favorite') + ); // Addonrechte (permissions) registieren rex_perm::register('quick_navigation[]'); diff --git a/fragments/QuickNavigation/List.php b/fragments/QuickNavigation/List.php index 533cffd..f6c1144 100644 --- a/fragments/QuickNavigation/List.php +++ b/fragments/QuickNavigation/List.php @@ -7,10 +7,14 @@ \ No newline at end of file diff --git a/lang/de_de.lang b/lang/de_de.lang index 0ac3f5f..d7f913a 100644 --- a/lang/de_de.lang +++ b/lang/de_de.lang @@ -21,6 +21,9 @@ quick_navigation_favorite = Favoriten quick_navigation_manage_favorite = Favoriten anlegen quick_navigation_favorite_article_add = Artikel hinzufügen in: quick_navigation_favorite_category_add = Kategorie hinzufügen in: +quick_navigation_addon_pages = AddOn-Seiten +quick_navigation_structure_favs = Struktur +quick_navigation_addon_pages_selection = AddOn-Seiten Favoriten quick_navigation_yform = YForm quick_navigation_yform_add = Datensatz hinzufügen in: @@ -35,3 +38,13 @@ quick_navigation_media_live_search_placeholder = Live-Suche... # Live Search quick_navigation_media_live_search_placeholder = Live-Suche... + +# Button Management +quick_navigation_button_management = Buttons ausblenden (Opt-Out) +quick_navigation_button_management_note = Wähle die Buttons aus, die du NICHT sehen möchtest. Alle anderen Buttons bleiben sichtbar. +quick_navigation_button_article_navigation = Artikelnavigation (Blättern) +quick_navigation_button_watson = Watson +quick_navigation_button_category = Kategorie +quick_navigation_button_article_history = Artikel-Historie +quick_navigation_button_yform = YForm +quick_navigation_button_favorite = Favoriten diff --git a/lang/en_gb.lang b/lang/en_gb.lang index 76eac8c..55d91fa 100644 --- a/lang/en_gb.lang +++ b/lang/en_gb.lang @@ -21,6 +21,9 @@ quick_navigation_favorite = Favorites quick_navigation_manage_favorite = Add favorites quick_navigation_favorite_article_add = Add article to: quick_navigation_favorite_category_add = Add category to: +quick_navigation_addon_pages = AddOn Pages +quick_navigation_structure_favs = Structure +quick_navigation_addon_pages_selection = AddOn Pages Favorites quick_navigation_yform = YForm quick_navigation_yform_add = Add dataset to: @@ -32,3 +35,13 @@ quick_navigation_media_sort_title = Sort by title (A-Z) # Media Live-Search quick_navigation_media_livesearch = Enable media live search? quick_navigation_media_live_search_placeholder = Live search... + +# Button Management +quick_navigation_button_management = Hide buttons (Opt-Out) +quick_navigation_button_management_note = Select the buttons you DON'T want to see. All other buttons remain visible. +quick_navigation_button_article_navigation = Article Navigation (Browse) +quick_navigation_button_watson = Watson +quick_navigation_button_category = Category +quick_navigation_button_article_history = Article History +quick_navigation_button_yform = YForm +quick_navigation_button_favorite = Favorites diff --git a/lib/Button/ButtonRegistry.php b/lib/Button/ButtonRegistry.php index 72bf3c0..a9ac709 100644 --- a/lib/Button/ButtonRegistry.php +++ b/lib/Button/ButtonRegistry.php @@ -2,27 +2,63 @@ namespace FriendsOfRedaxo\QuickNavigation\Button; +use rex; +use rex_addon; + class ButtonRegistry { /** - * @var array an array that contains button instances and their priorities + * @var array an array that contains button instances and their priorities */ protected static array $buttons = []; /** * Registers a button with an optional priority. * Lower priority values cause the button to appear earlier in the list. + * + * @param string $id Unique identifier for the button (e.g. 'article_navigation', 'watson') + * @param string $label Human readable label for config (e.g. 'Artikelnavigation', 'Watson') */ - public static function registerButton(ButtonInterface $buttonInstance, int $priority = 10): void + public static function registerButton(ButtonInterface $buttonInstance, int $priority = 10, string $id = '', string $label = ''): void { - self::$buttons[] = ['instance' => $buttonInstance, 'priority' => $priority]; + // Generate ID from class name if not provided + if ($id === '') { + $className = get_class($buttonInstance); + $id = strtolower(str_replace('Button', '', substr($className, strrpos($className, '\\') + 1))); + } + + // Use ID as label if not provided + if ($label === '') { + $label = ucfirst(str_replace('_', ' ', $id)); + } + + self::$buttons[] = [ + 'id' => $id, + 'label' => $label, + 'instance' => $buttonInstance, + 'priority' => $priority + ]; } /** - * Returns the buttons sorted by their priority. + * Returns the buttons sorted by their priority, filtered by user preferences. */ public static function getButtonsOutput(): string { + $user = rex::getUser(); + if (!$user) { + return ''; + } + + $userId = $user->getId(); + $addon = rex_addon::get('quick_navigation'); + + // Get disabled buttons for this user (Opt-Out) + $disabledButtons = $addon->getConfig('quick_navigation_disabled_buttons' . $userId, []); + if (!is_array($disabledButtons)) { + $disabledButtons = []; + } + // Sorts the buttons based on their priority usort(self::$buttons, static function (array $a, array $b): int { return $a['priority'] <=> $b['priority']; @@ -30,10 +66,39 @@ public static function getButtonsOutput(): string $resultString = ''; foreach (self::$buttons as $button) { + // Skip if button is disabled for this user + if (in_array($button['id'], $disabledButtons, true)) { + continue; + } + // Since all instances implement ButtonInterface, it's guaranteed that get() exists. $resultString .= $button['instance']->get(); } return $resultString; } + + /** + * Returns all available buttons with their metadata for configuration. + * @return array + */ + public static function getAvailableButtons(): array + { + // Sort by priority + $sortedButtons = self::$buttons; + usort($sortedButtons, static function (array $a, array $b): int { + return $a['priority'] <=> $b['priority']; + }); + + $result = []; + foreach ($sortedButtons as $button) { + $result[] = [ + 'id' => $button['id'], + 'label' => $button['label'], + 'priority' => $button['priority'] + ]; + } + + return $result; + } } diff --git a/lib/Button/FavoriteButton.php b/lib/Button/FavoriteButton.php index 3dfa868..8bc22f0 100644 --- a/lib/Button/FavoriteButton.php +++ b/lib/Button/FavoriteButton.php @@ -6,6 +6,7 @@ use rex; use rex_addon; +use rex_be_controller; use rex_category; use rex_clang; @@ -27,9 +28,14 @@ public function get(): string } $categoryIds = rex_addon::get('quick_navigation')->getConfig('quick_navigation_favs' . $user->getId()); + $addonPages = rex_addon::get('quick_navigation')->getConfig('quick_navigation_addon_favs' . $user->getId(), []); $listItems = []; + + // Struktur-Favoriten zuerst if ($categoryIds && count($categoryIds) > 0) { + $listItems[] = '
' . rex_i18n::msg('quick_navigation_structure_favs') . '
'; + $clangId = rex_request('clang', 'int', rex_clang::getStartId()); foreach ($categoryIds as $categoryId) { @@ -77,7 +83,53 @@ public function get(): string $listItems[] = $listItem; } - } else { + } + + // AddOn-Seiten Favoriten danach + if (is_array($addonPages) && count($addonPages) > 0) { + if (count($listItems) > 0) { + $listItems[] = '
'; + } + $listItems[] = '
' . rex_i18n::msg('quick_navigation_addon_pages') . '
'; + + foreach ($addonPages as $pageKey) { + $pageInfo = $this->parsePageKey($pageKey); + if (!$pageInfo) { + continue; + } + + // Check permission + $page = rex_be_controller::getPageObject($pageInfo['fullKey']); + if (!$page || $page->isHidden()) { + continue; + } + + // Check user permission + $requiredPerms = $page->getRequiredPermissions(); + if (!empty($requiredPerms) && !$user->hasPerm($requiredPerms)) { + continue; + } + + $attributes = [ + 'href' => rex_url::backendPage($pageInfo['fullKey']), + 'title' => $pageInfo['title'], + ]; + + $listItem = ' +
+ + + ' . rex_escape($pageInfo['title']) . ' + +
+ '; + + $listItems[] = $listItem; + } + } + + // Keine Favoriten + if (count($listItems) === 0) { $listItems[] = ''.rex_i18n::msg('quick_navigation_manage_favorite').''; } @@ -88,4 +140,84 @@ public function get(): string ]); return $fragment->parse('QuickNavigation/Dropdown.php'); } + + /** + * Parse page key and return info + * @return array{fullKey: string, title: string, icon: string}|null + */ + private function parsePageKey(string $pageKey): ?array + { + $page = rex_be_controller::getPageObject($pageKey); + if (!$page) { + return null; + } + + return [ + 'fullKey' => $pageKey, + 'title' => $page->getTitle(), + 'icon' => $page->getIcon() ?: 'rex-icon fa-cube', + ]; + } + + /** + * Get all available backend pages for favorites + * @return array + */ + public static function getAvailablePages(): array + { + $user = rex::getUser(); + if (!$user) { + return []; + } + + $pages = []; + $pageContainer = rex_be_controller::getPages(); + + foreach ($pageContainer as $pageKey => $page) { + // Skip system pages + if (in_array($pageKey, ['setup', 'login', 'logout', '2factor_auth', '2factor_auth_verify'], true)) { + continue; + } + + // Skip if user has no permission + if ($page->isHidden()) { + continue; + } + + $requiredPerms = $page->getRequiredPermissions(); + if (!empty($requiredPerms) && !$user->hasPerm($requiredPerms)) { + continue; + } + + $addonName = $pageKey; + $pages[] = [ + 'key' => $pageKey, + 'title' => $page->getTitle(), + 'icon' => $page->getIcon() ?: 'rex-icon fa-cube', + 'addon' => $addonName, + ]; + + // Add subpages + foreach ($page->getSubpages() as $subpageKey => $subpage) { + if ($subpage->isHidden()) { + continue; + } + + $subRequiredPerms = $subpage->getRequiredPermissions(); + if (!empty($subRequiredPerms) && !$user->hasPerm($subRequiredPerms)) { + continue; + } + + $fullKey = $pageKey . '/' . $subpageKey; + $pages[] = [ + 'key' => $fullKey, + 'title' => ' → ' . $subpage->getTitle(), + 'icon' => $subpage->getIcon() ?: 'rex-icon fa-cube', + 'addon' => $addonName, + ]; + } + } + + return $pages; + } } diff --git a/pages/config.php b/pages/config.php index 7bde858..118178b 100644 --- a/pages/config.php +++ b/pages/config.php @@ -2,6 +2,8 @@ namespace FriendsOfRedaxo\QuickNavigation; +use FriendsOfRedaxo\QuickNavigation\Button\ButtonRegistry; +use FriendsOfRedaxo\QuickNavigation\Button\FavoriteButton; use rex; use rex_addon; use rex_category_select; @@ -26,6 +28,11 @@ $config['quick_navigation_ignoreoffline' . $user] = isset($config['quick_navigation_ignoreoffline' . $user]) ? 1 : 0; $config['quick_navigation_artdirections' . $user] = isset($config['quick_navigation_artdirections' . $user]) ? 1 : 0; $config['quick_navigation_media_livesearch' . $user] = isset($config['quick_navigation_media_livesearch' . $user]) ? 1 : 0; + + // Disabled Buttons speichern (Array bleibt als Array) + if (!isset($config['quick_navigation_disabled_buttons' . $user])) { + $config['quick_navigation_disabled_buttons' . $user] = []; + } $package->setConfig($config); echo rex_view::success($package->i18n('quick_navigation_config_saved')); @@ -56,6 +63,38 @@ $fragment = new rex_fragment(); $fragment->setVar('elements', $formElements, false); $content .= $fragment->parse('core/form/container.php'); + +// AddOn-Seiten Favoriten +$formElements = []; +$n = []; +$n['label'] = ''; + +// Get all available pages +$availablePages = FavoriteButton::getAvailablePages(); +$selectedPages = $package->getConfig('quick_navigation_addon_favs' . $user, []); +if (!is_array($selectedPages)) { + $selectedPages = []; +} + +$selectHtml = ''; +$n['field'] = $selectHtml; +$formElements[] = $n; +$fragment = new rex_fragment(); +$fragment->setVar('elements', $formElements, false); +$content .= $fragment->parse('core/form/container.php'); + // Ignore offline cats $formElements = []; $n = []; @@ -89,7 +128,43 @@ $fragment->setVar('elements', $formElements, false); $content .= $fragment->parse('core/form/checkbox.php'); -// Medienpool-Sortier-Button-Option entfernt +// Button-Management +$formElements = []; +$n = []; +$n['label'] = ''; + +// Get all available buttons +$availableButtons = ButtonRegistry::getAvailableButtons(); +$disabledButtons = $package->getConfig('quick_navigation_disabled_buttons' . $user, []); +if (!is_array($disabledButtons)) { + $disabledButtons = []; +} + +$buttonCheckboxes = ''; +foreach ($availableButtons as $button) { + $isDisabled = in_array($button['id'], $disabledButtons, true); + $buttonCheckboxes .= sprintf( + '
+ +
', + $user, + rex_escape($button['id']), + $isDisabled ? ' checked="checked"' : '', + rex_escape($button['label']) + ); +} + +$n['field'] = '
' . $buttonCheckboxes . '
'; +$n['note'] = $package->i18n('quick_navigation_button_management_note'); +$formElements[] = $n; +$fragment = new rex_fragment(); +$fragment->setVar('elements', $formElements, false); +$content .= $fragment->parse('core/form/container.php'); + +$content .= ''; // Save-Button $formElements = [];