LLMS_Nav_Menus
LifterLMS Navigation Menus class.
Contents
Source Source
File: includes/class.llms.nav.menus.php
class LLMS_Nav_Menus { /** * Constructor. * * @since 3.14.7 * @since 3.22.0 Unknown. * @since 7.1.0 Postpone the LifterLMS menu meta box addition to `admin_head-nav-menus.php` * rather than `load-nav-menus.php` it's not initially hidden (for new users). * @since 7.2.0 Add navigation link block and enqueue block editor assets. * @since 7.3.0 Change `render_block_llms/navigation-link` to `render_block` for compatibility with LLMS block visibility. * * @return void */ public function __construct() { // Filter menu items on frontend to add real URLs to menu items. add_filter( 'wp_nav_menu_objects', array( $this, 'filter_nav_items' ) ); // Add meta box to the Appearance -> Menus screen on admin panel. add_action( 'admin_head-nav-menus.php', array( $this, 'add_metabox' ) ); // Add LifterLMS menu item type section to customizer. add_filter( 'customize_nav_menu_available_item_types', array( $this, 'customize_add_type' ) ); // Add LifterLMS menu items links to the customizer. add_filter( 'customize_nav_menu_available_items', array( $this, 'customize_add_items' ), 10, 4 ); // Add active classes for nav items for catalog pages. add_filter( 'wp_nav_menu_objects', array( $this, 'menu_item_classes' ) ); // Register block. add_action( 'init', array( $this, 'register_block' ) ); // Render block. add_filter( 'render_block', array( $this, 'render_block' ), 10, 2 ); // Load menu items data in block editor. add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) ); } /** * Add nav menu metabox. * * @since 3.14.7 * * @return void */ public function add_metabox() { add_meta_box( 'llms-nav-menu', __( 'LifterLMS', 'lifterlms' ), array( $this, 'output' ), 'nav-menus', 'side', 'default' ); add_action( 'admin_print_footer_scripts', array( $this, 'output_scripts' ) ); } /** * Adds LifterLMS menu items to the customizer. * * @since 3.14.7 * * @param array $items Optional. Menu items. Default empty array. * @param string $type Optional. Requested menu item type. Default empty string. * @param string $object Optional. Requested menu item object. Default empty string. * @param integer $page Optional. Requested page number. Default `0`. * @return array */ public function customize_add_items( $items = array(), $type = '', $object = '', $page = 0 ) { if ( 'llms_nav' !== $object ) { return $items; } foreach ( $this->get_nav_items() as $id => $data ) { $items[] = array( 'classes' => 'llms-nav-item-' . $id, 'id' => $id, 'title' => $data['title'], 'type_label' => __( 'Custom Link', 'lifterlms' ), 'url' => esc_url_raw( $data['url'] ), ); } return array_slice( $items, 10 * $page, 10 ); } /** * Add the LifterLMS menu item section to the customizer. * * @since 3.14.7 * * @param array $types Existing menu item types. * @return array */ public function customize_add_type( $types ) { $types['llms_nav_menu_items'] = array( 'title' => _x( 'LifterLMS', 'customizer menu section title', 'lifterlms' ), 'type' => 'llms_nav', 'object' => 'llms_nav', ); return $types; } /** * Filters Nav Menu Items to convert #llms- urls into actual URLs. * * Also hides URLs that should only be available to logged-in users. * * @since 3.14.7 * @since 3.37.12 Use `in_array` with strict types comparison. * @since 7.2.0 Remove passing item data by reference and improve URL checks. * * @param array $items Nav menu items. * @return array */ public function filter_nav_items( $items ) { $urls = array( '#llms-signout', '#llms-signin', ); foreach ( $items as $i => $data ) { $is_object = is_object( $data ) && property_exists( $data, 'url' ); $url = $is_object ? $data->url : $data['url'] ?? ''; if ( ! in_array( $url, $urls, true ) ) { continue; } $data = (object) $data; $logged_in = is_user_logged_in(); if ( '#llms-signin' === $url && ! $logged_in ) { $data->url = llms_get_page_url( 'myaccount' ); } elseif ( '#llms-signout' === $url && $logged_in ) { $data->url = wp_logout_url( llms_get_page_url( 'myaccount' ) ); } else { unset( $items[ $i ] ); continue; } $items[ $i ] = $is_object ? $data : (array) $data; } return $items; } /** * Retrieve a filtered array of custom LifterLMS nav menu items. * * @since 3.14.7 * @since 3.37.12 Fixed possible access to undefined index. * Excluded endpoints with an empty url. * * @return array */ private function get_nav_items() { $items = array(); foreach ( LLMS_Student_Dashboard::get_tabs() as $id => $data ) { if ( ! empty( $data['nav_item'] ) ) { $url = ! empty( $data['endpoint'] ) ? llms_get_endpoint_url( $data['endpoint'], '', llms_get_page_url( 'myaccount' ) ) : ''; // No URL no nav item. if ( empty( $url ) ) { if ( empty( $data['url'] ) ) { continue; } else { $url = $data['url']; } } $title = empty( $data['title'] ) ? '' : $data['title']; $items[ $id ] = array( 'url' => $url, 'label' => $title, 'title' => $title, ); } } $items['signin'] = array( 'url' => '#llms-signin', 'label' => __( 'Sign In', 'lifterlms' ), 'title' => __( 'Sign In', 'lifterlms' ), ); $items['signout'] = array( 'url' => '#llms-signout', 'label' => __( 'Sign Out', 'lifterlms' ), 'title' => __( 'Sign Out', 'lifterlms' ), ); /** * Filters array of custom LifterLMS nav menu items * * @since 3.14.7 * * @param array $items Array of custom LifterLMS nav menu items. */ return apply_filters( 'llms_nav_menu_items', $items ); } /** * Add "active" classes to menu items for LLMS catalog pages. * * @since 3.22.0 * @since 3.37.12 Use strict comparisons. * Cast `page_for_posts` option to int in order to use strict comparisons. * @since 4.12.0 Make sure `is_lifterlms()` exists before calling it. * * @param array $menu_items Menu items. * @return array */ public function menu_item_classes( $menu_items ) { if ( ! function_exists( 'is_lifterlms' ) || ! is_lifterlms() ) { return $menu_items; } $courses_id = llms_get_page_id( 'courses' ); $memberships_id = llms_get_page_id( 'memberships' ); $blog_id = absint( get_option( 'page_for_posts', 0 ) ); foreach ( $menu_items as $key => $item ) { $classes = $item->classes; $object_id = absint( $item->object_id ); // Remove active class from blog archive. if ( $blog_id === $object_id ) { $menu_items[ $key ]->current = false; foreach ( array( 'current_page_parent', 'current-menu-item' ) as $class ) { if ( in_array( $class, $classes, true ) ) { unset( $classes[ array_search( $class, $classes, true ) ] ); } } } elseif ( 'page' === $item->object && ( ( is_courses() && $courses_id === $object_id ) || ( is_memberships() && $memberships_id === $object_id ) ) ) { $menu_items[ $key ]->current = true; $classes[] = 'current-menu-item'; $classes[] = 'current_page_item'; // Set parent links for courses & memberships. } elseif ( ( $courses_id === $object_id && ( is_singular( 'course' ) || is_course_taxonomy() ) ) || ( $memberships_id === $object_id && ( is_singular( 'llms_membership' ) || is_membership_taxonomy() ) ) ) { $classes[] = 'current_page_parent'; } $menu_items[ $key ]->classes = array_unique( $classes ); } return $menu_items; } /** * Output the metabox. * * @since 3.14.7 * @since 3.24.0 Unknown. * * @return void */ public function output() { ?> <div id="posttype-llms-nav-items" class="posttypediv"> <div id="tabs-panel-llms-nav-items" class="tabs-panel tabs-panel-active"> <ul id="llms-nav-items-checklist" class="categorychecklist form-no-clear"> <?php $i = -1; foreach ( $this->get_nav_items() as $key => $data ) : ?> <li> <label class="menu-item-title"> <input type="checkbox" class="menu-item-checkbox" name="menu-item[<?php echo esc_attr( $i ); ?>][menu-item-object-id]" value="<?php echo esc_attr( $i ); ?>" /> <?php echo esc_html( $data['label'] ); ?> </label> <input type="hidden" class="menu-item-type" name="menu-item[<?php echo esc_attr( $i ); ?>][menu-item-type]" value="custom" /> <input type="hidden" class="menu-item-title" name="menu-item[<?php echo esc_attr( $i ); ?>][menu-item-title]" value="<?php echo esc_html( $data['title'] ); ?>" /> <input type="hidden" class="menu-item-url" name="menu-item[<?php echo esc_attr( $i ); ?>][menu-item-url]" value="<?php echo esc_url( $data['url'] ); ?>" /> <input type="hidden" class="menu-item-classes" name="menu-item[<?php echo esc_attr( $i ); ?>][menu-item-classes]" value="<?php echo esc_attr( 'llms-nav-item-' . $key ); ?>" /> </li> <?php $i--; endforeach; ?> </ul> </div> <p class="button-controls"> <span class="list-controls"> <a href="<?php echo admin_url( 'nav-menus.php?page-tab=all&selectall=1#posttype-llms-nav-items' ); ?>" class="select-all"><?php _e( 'Select all', 'lifterlms' ); ?></a> </span> <span class="add-to-menu"> <input type="submit" class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to menu', 'lifterlms' ); ?>" name="add-post-type-menu-item" id="submit-posttype-llms-nav-items"> <span class="spinner"></span> </span> </p> </div> <?php } /** * Output JS to ensure that users don't edit the #llms-signout URL that's replaced dynamically with an actual signout link. * * @since 3.14.7 * * @return void
Expand full source code Collapse full source code View on GitHub
Methods Methods
- __construct — Constructor.
- add_metabox — Add nav menu metabox.
- customize_add_items — Adds LifterLMS menu items to the customizer.
- customize_add_type — Add the LifterLMS menu item section to the customizer.
- filter_nav_items — Filters Nav Menu Items to convert #llms- urls into actual URLs.
- get_nav_items — Retrieve a filtered array of custom LifterLMS nav menu items.
- menu_item_classes — Add "active" classes to menu items for LLMS catalog pages.
- output — Output the metabox.
- output_scripts — Output JS to ensure that users don't edit the #llms-signout URL that's replaced dynamically with an actual signout link.
Changelog Changelog
Version | Description |
---|---|
3.37.12 | Fixed possible access to undefined index. Excluded endpoints with an empty url. Made sure to use strict comparisons. |
3.24.0 | Unknown. |
3.14.7 | Introduced. |