label. */ function swiftdash_links_sections() { return array( 'content' => __( 'Content', 'swiftwebdev-dashboard-analytics' ), 'design' => __( 'Design', 'swiftwebdev-dashboard-analytics' ), 'people' => __( 'Plugins and users', 'swiftwebdev-dashboard-analytics' ), 'tools' => __( 'Tools', 'swiftwebdev-dashboard-analytics' ), 'settings' => __( 'Settings', 'swiftwebdev-dashboard-analytics' ), 'store' => __( 'Store', 'swiftwebdev-dashboard-analytics' ), ); } /** * Shortcuts available to the current user, keyed by id, in default order. * * @return array[] Each: id, label, description, icon, url, capability, tone, section. */ function swiftdash_quick_links() { $block_theme = function_exists( 'wp_is_block_theme' ) && wp_is_block_theme(); $pending = (int) wp_count_comments()->moderated; $comments = __( 'Review and reply to comments.', 'swiftwebdev-dashboard-analytics' ); if ( $pending ) { $comments = sprintf( /* translators: %s: number of comments waiting for review. */ _n( 'Review and reply to comments. %s waiting for review.', 'Review and reply to comments. %s waiting for review.', $pending, 'swiftwebdev-dashboard-analytics' ), number_format_i18n( $pending ) ); } $links = array( array( 'add-post', __( 'Add new post', 'swiftwebdev-dashboard-analytics' ), __( 'Write and publish a new blog post.', 'swiftwebdev-dashboard-analytics' ), 'plus-circle-fill', 'post-new.php', 'edit_posts', 'blue', 'content' ), array( 'all-posts', __( 'All posts', 'swiftwebdev-dashboard-analytics' ), __( 'Edit, publish or remove your existing posts.', 'swiftwebdev-dashboard-analytics' ), 'note-fill', 'edit.php', 'edit_posts', 'sky', 'content' ), array( 'categories', __( 'Categories', 'swiftwebdev-dashboard-analytics' ), __( 'Group your posts by topic.', 'swiftwebdev-dashboard-analytics' ), 'folder-fill', 'edit-tags.php?taxonomy=category', 'manage_categories', 'orange', 'content' ), array( 'tags', __( 'Tags', 'swiftwebdev-dashboard-analytics' ), __( 'Label posts with keywords so readers find related content.', 'swiftwebdev-dashboard-analytics' ), 'tag-fill', 'edit-tags.php?taxonomy=post_tag', 'manage_categories', 'green', 'content' ), array( 'add-page', __( 'Add new page', 'swiftwebdev-dashboard-analytics' ), __( 'Create a new page such as About or Contact.', 'swiftwebdev-dashboard-analytics' ), 'file-plus-fill', 'post-new.php?post_type=page', 'edit_pages', 'purple', 'content' ), array( 'manage-pages', __( 'All pages', 'swiftwebdev-dashboard-analytics' ), __( 'Edit, publish or remove your existing pages.', 'swiftwebdev-dashboard-analytics' ), 'files-fill', 'edit.php?post_type=page', 'edit_pages', 'purple', 'content' ), array( 'upload-media', __( 'Upload media', 'swiftwebdev-dashboard-analytics' ), __( 'Add images, videos or documents to your media library.', 'swiftwebdev-dashboard-analytics' ), 'cloud-arrow-up-fill', 'media-new.php', 'upload_files', 'green', 'content' ), array( 'media-library', __( 'Media library', 'swiftwebdev-dashboard-analytics' ), __( 'Browse and manage every file you have uploaded.', 'swiftwebdev-dashboard-analytics' ), 'images-fill', 'upload.php', 'upload_files', 'sky', 'content' ), array( 'comments', __( 'Comments', 'swiftwebdev-dashboard-analytics' ), $comments, 'chat-circle-text-fill', 'edit-comments.php', 'moderate_comments', 'orange', 'content' ), array( 'themes', __( 'Themes', 'swiftwebdev-dashboard-analytics' ), __( 'Choose or change the theme that styles your site.', 'swiftwebdev-dashboard-analytics' ), 'palette-fill', 'themes.php', 'switch_themes', 'purple', 'design' ), array( 'customize-site', $block_theme ? __( 'Site editor', 'swiftwebdev-dashboard-analytics' ) : __( 'Customize site', 'swiftwebdev-dashboard-analytics' ), __( 'Change how your site looks: colors, fonts, header and footer.', 'swiftwebdev-dashboard-analytics' ), 'paint-brush-fill', $block_theme ? 'site-editor.php' : 'customize.php', 'edit_theme_options', 'red', 'design', ), ); if ( $block_theme ) { $links[] = array( 'patterns', __( 'Patterns', 'swiftwebdev-dashboard-analytics' ), __( 'Reusable blocks and layouts for your pages and templates.', 'swiftwebdev-dashboard-analytics' ), 'shapes-fill', 'site-editor.php?path=/patterns', 'edit_theme_options', 'blue', 'design' ); $links[] = array( 'navigation', __( 'Navigation', 'swiftwebdev-dashboard-analytics' ), __( 'Choose which links appear in your site navigation.', 'swiftwebdev-dashboard-analytics' ), 'compass-fill', 'site-editor.php?path=/navigation', 'edit_theme_options', 'green', 'design' ); } else { if ( current_theme_supports( 'widgets' ) ) { $links[] = array( 'widgets', __( 'Widgets', 'swiftwebdev-dashboard-analytics' ), __( 'Add content blocks to your sidebars and footer.', 'swiftwebdev-dashboard-analytics' ), 'squares-four-fill', 'widgets.php', 'edit_theme_options', 'blue', 'design' ); } if ( current_theme_supports( 'menus' ) ) { $links[] = array( 'menus', __( 'Menus', 'swiftwebdev-dashboard-analytics' ), __( 'Choose which links appear in your site navigation.', 'swiftwebdev-dashboard-analytics' ), 'list-fill', 'nav-menus.php', 'edit_theme_options', 'green', 'design' ); } } if ( ! defined( 'DISALLOW_FILE_EDIT' ) || ! DISALLOW_FILE_EDIT ) { $links[] = array( 'theme-editor', __( 'Theme file editor', 'swiftwebdev-dashboard-analytics' ), __( 'Edit theme code directly. For developers only.', 'swiftwebdev-dashboard-analytics' ), 'code-fill', 'theme-editor.php', 'edit_themes', 'sky', 'design' ); } array_push( $links, array( 'add-plugin', __( 'Add plugin', 'swiftwebdev-dashboard-analytics' ), __( 'Find and install new plugins from WordPress.org.', 'swiftwebdev-dashboard-analytics' ), 'puzzle-piece-fill', 'plugin-install.php', 'install_plugins', 'sky', 'people' ), array( 'manage-plugins', __( 'Installed plugins', 'swiftwebdev-dashboard-analytics' ), __( 'Update, turn on or turn off the plugins you have.', 'swiftwebdev-dashboard-analytics' ), 'plug-fill', 'plugins.php', 'activate_plugins', 'blue', 'people' ), array( 'add-user', __( 'Add user', 'swiftwebdev-dashboard-analytics' ), __( 'Invite a new person to your site.', 'swiftwebdev-dashboard-analytics' ), 'user-plus-fill', 'user-new.php', 'create_users', 'green', 'people' ), array( 'manage-users', __( 'Manage users', 'swiftwebdev-dashboard-analytics' ), __( 'See everyone on your site and change what they can do.', 'swiftwebdev-dashboard-analytics' ), 'users-fill', 'users.php', 'list_users', 'orange', 'people' ), array( 'profile', __( 'Your profile', 'swiftwebdev-dashboard-analytics' ), __( 'Change your name, email address and password.', 'swiftwebdev-dashboard-analytics' ), 'user-circle-fill', 'profile.php', 'read', 'purple', 'people' ), array( 'tools', __( 'Tools', 'swiftwebdev-dashboard-analytics' ), __( 'Open the WordPress tools screen.', 'swiftwebdev-dashboard-analytics' ), 'wrench-fill', 'tools.php', 'edit_posts', 'blue', 'tools' ), array( 'import', __( 'Import', 'swiftwebdev-dashboard-analytics' ), __( 'Bring in posts and pages from another site.', 'swiftwebdev-dashboard-analytics' ), 'download-simple-fill', 'import.php', 'import', 'green', 'tools' ), array( 'export-data', __( 'Export', 'swiftwebdev-dashboard-analytics' ), __( 'Download your posts, pages and comments as a file you can import elsewhere.', 'swiftwebdev-dashboard-analytics' ), 'export-fill', 'export.php', 'export', 'purple', 'tools' ), array( 'site-health', __( 'Site Health', 'swiftwebdev-dashboard-analytics' ), __( 'Check your site for security and performance problems.', 'swiftwebdev-dashboard-analytics' ), 'heartbeat-fill', 'site-health.php', 'view_site_health_checks', 'red', 'tools' ), array( 'system-info', __( 'System information', 'swiftwebdev-dashboard-analytics' ), __( 'See your server, PHP and WordPress details, useful when asking for support.', 'swiftwebdev-dashboard-analytics' ), 'info-fill', 'site-health.php?tab=debug', 'view_site_health_checks', 'sky', 'tools' ), array( 'updates', __( 'Updates', 'swiftwebdev-dashboard-analytics' ), __( 'Update WordPress, plugins, themes and translations.', 'swiftwebdev-dashboard-analytics' ), 'arrows-clockwise-fill', 'update-core.php', 'update_core', 'orange', 'tools' ), array( 'site-settings', __( 'General settings', 'swiftwebdev-dashboard-analytics' ), __( 'Change your site title, tagline, time zone and other basics.', 'swiftwebdev-dashboard-analytics' ), 'gear-six-fill', 'options-general.php', 'manage_options', 'blue', 'settings' ), array( 'writing', __( 'Writing', 'swiftwebdev-dashboard-analytics' ), __( 'Default post category, format and post by email.', 'swiftwebdev-dashboard-analytics' ), 'pen-nib-fill', 'options-writing.php', 'manage_options', 'purple', 'settings' ), array( 'reading', __( 'Reading', 'swiftwebdev-dashboard-analytics' ), __( 'Your homepage, posts per page and search engine visibility.', 'swiftwebdev-dashboard-analytics' ), 'book-open-fill', 'options-reading.php', 'manage_options', 'green', 'settings' ), array( 'discussion', __( 'Discussion', 'swiftwebdev-dashboard-analytics' ), __( 'Decide who can comment and how comments are reviewed.', 'swiftwebdev-dashboard-analytics' ), 'chats-circle-fill', 'options-discussion.php', 'manage_options', 'orange', 'settings' ), array( 'media-settings', __( 'Media settings', 'swiftwebdev-dashboard-analytics' ), __( 'Image sizes and how uploads are organized.', 'swiftwebdev-dashboard-analytics' ), 'image-fill', 'options-media.php', 'manage_options', 'sky', 'settings' ), array( 'permalinks', __( 'Permalinks', 'swiftwebdev-dashboard-analytics' ), __( 'Choose how the web addresses of your posts look.', 'swiftwebdev-dashboard-analytics' ), 'link-simple-fill', 'options-permalink.php', 'manage_options', 'red', 'settings' ), array( 'privacy', __( 'Privacy', 'swiftwebdev-dashboard-analytics' ), __( 'Set your privacy policy page.', 'swiftwebdev-dashboard-analytics' ), 'shield-check-fill', 'options-privacy.php', 'manage_privacy_options', 'green', 'settings' ) ); if ( class_exists( 'WooCommerce' ) ) { $hpos = class_exists( '\Automattic\WooCommerce\Utilities\OrderUtil' ) && \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled(); $links[] = array( 'add-product', __( 'Add product', 'swiftwebdev-dashboard-analytics' ), __( 'Add a new product to your store.', 'swiftwebdev-dashboard-analytics' ), 'shopping-cart-fill', 'post-new.php?post_type=product', 'edit_products', 'green', 'store' ); $links[] = array( 'orders', __( 'Orders', 'swiftwebdev-dashboard-analytics' ), __( 'See and process your store orders.', 'swiftwebdev-dashboard-analytics' ), 'receipt-fill', $hpos ? 'admin.php?page=wc-orders' : 'edit.php?post_type=shop_order', 'edit_shop_orders', 'orange', 'store' ); } $keyed = array(); foreach ( $links as $link ) { $link[4] = admin_url( $link[4] ); $keyed[ $link[0] ] = array_combine( array( 'id', 'label', 'description', 'icon', 'url', 'capability', 'tone', 'section' ), $link ); } /** * Filters the Quick Links shortcuts. Each item: id, label, description, icon, url, capability, * tone (blue, sky, purple, green, orange, red) and section (content, design, people, tools, settings, store). * Items the current user lacks the capability for are removed afterwards. * * @param array[] $links Shortcuts keyed by id, in default order. */ $keyed = apply_filters( 'swiftdash_quick_links', $keyed ); $sections = swiftdash_links_sections(); $available = array(); foreach ( (array) $keyed as $link ) { if ( empty( $link['id'] ) || ! preg_match( '/^[a-z0-9_-]+$/', $link['id'] ) || empty( $link['capability'] ) || ! current_user_can( $link['capability'] ) ) { continue; } $link = wp_parse_args( $link, array( 'label' => '', 'description' => '', 'icon' => 'link-simple-fill', 'url' => '', 'tone' => 'blue', 'section' => 'tools', ) ); if ( ! isset( $sections[ $link['section'] ] ) ) { $link['section'] = 'tools'; } $available[ $link['id'] ] = $link; } return $available; } /** * Default pinned shortcuts: the first 8 available of the recommended set. * * @param array[] $links Available shortcuts keyed by id. * @return string[] */ function swiftdash_links_default_pins( $links ) { $ids = array( 'add-post', 'add-page', 'upload-media', 'manage-users', 'customize-site', 'add-plugin', 'updates', 'site-health' ); return array_slice( array_values( array_intersect( $ids, array_keys( $links ) ) ), 0, 8 ); } /** * Register the per-user layout meta. */ function swiftdash_register_links_meta() { $ids = array( 'type' => 'array', 'maxItems' => 100, 'items' => array( 'type' => 'string', 'pattern' => '^[a-z0-9_-]+$', ), ); register_meta( 'user', 'swiftdash_links', array( 'type' => 'object', 'single' => true, 'auth_callback' => function ( $allowed, $meta_key, $user_id ) { return current_user_can( 'edit_user', $user_id ); }, 'show_in_rest' => array( 'schema' => array( 'type' => 'object', 'properties' => array( 'order' => $ids, 'hidden' => $ids, 'pinned' => $ids, ), 'additionalProperties' => false, ), ), ) ); } add_action( 'init', 'swiftdash_register_links_meta' ); /** * Current user's layout, limited to the available shortcuts. * * Pinned is ordered as shown on the dashboard. Older saves kept the pinned order in `order`, so pinned * ids are sorted by their position there. * * @param array[] $links Available shortcuts keyed by id. * @return array { hidden: ids, pinned: ids in dashboard order } */ function swiftdash_links_state( $links ) { $ids = array_keys( $links ); $saved = get_user_meta( get_current_user_id(), 'swiftdash_links', true ); if ( ! is_array( $saved ) ) { return array( 'hidden' => array(), 'pinned' => swiftdash_links_default_pins( $links ), ); } $pick = function ( $key ) use ( $saved, $ids ) { return isset( $saved[ $key ] ) && is_array( $saved[ $key ] ) ? array_values( array_intersect( array_map( 'sanitize_key', $saved[ $key ] ), $ids ) ) : array(); }; $hidden = $pick( 'hidden' ); $pinned = array_diff( $pick( 'pinned' ), $hidden ); return array( 'hidden' => $hidden, 'pinned' => array_values( array_intersect( array_unique( array_merge( $pick( 'order' ), $pinned ) ), $pinned ) ), ); } /** * Enqueue Quick Links assets. * * @param string $screen_key Current SwiftWebDev Dashboard screen key. */ function swiftdash_links_assets( $screen_key ) { if ( 'links' !== $screen_key && 'dashboard' !== $screen_key ) { return; } wp_enqueue_style( 'swiftdash-links', SWIFTDASH_URL . 'assets/css/links.css', array( 'swiftdash-app' ), SWIFTDASH_VERSION ); // The dashboard widget is plain links, so the script only loads on the Quick Links screen. if ( 'links' === $screen_key ) { wp_enqueue_script( 'swiftdash-sortable-lib', SWIFTDASH_URL . 'assets/vendor/sortable/Sortable.min.js', array(), SWIFTDASH_VERSION, true ); wp_enqueue_script( 'swiftdash-links', SWIFTDASH_URL . 'assets/js/links.js', array( 'swiftdash-app', 'swiftdash-sortable-lib', 'wp-api-fetch', 'wp-i18n' ), SWIFTDASH_VERSION, true ); wp_set_script_translations( 'swiftdash-links', 'swiftwebdev-dashboard-analytics' ); } } add_action( 'swiftdash_enqueue_assets', 'swiftdash_links_assets' ); /** * Tone class for a shortcut. * * @param array $link Shortcut. * @return string */ function swiftdash_link_tone( $link ) { return 'sd-ql-tone--' . ( in_array( $link['tone'], array( 'blue', 'sky', 'purple', 'green', 'orange', 'red' ), true ) ? $link['tone'] : 'blue' ); } /** * Quick Links screen. * * @param array $screen Screen definition. */ function swiftdash_screen_links( $screen ) { $links = swiftdash_quick_links(); $state = swiftdash_links_state( $links ); swiftdash_render_page_header( $screen['title'], $screen['description'], $links ? function () { ?>
>