'user_login', 'first_name' => 'first_name', 'last_name' => 'last_name', 'display_name' => 'display_name', 'nickname' => 'nickname', 'email' => 'user_email', ); } /** * Placeholder chips for the admin help UI. * * @return array */ public static function get_placeholder_examples() { return array( array( 'code' => '{username}', 'label' => __( 'Username', 'advance-menu-manager' ), ), array( 'code' => '{first_name}', 'label' => __( 'First name', 'advance-menu-manager' ), ), array( 'code' => '{last_name}', 'label' => __( 'Last name', 'advance-menu-manager' ), ), array( 'code' => '{display_name}', 'label' => __( 'Display name', 'advance-menu-manager' ), ), array( 'code' => '{nickname}', 'label' => __( 'Nickname', 'advance-menu-manager' ), ), array( 'code' => '{email}', 'label' => __( 'Email', 'advance-menu-manager' ), ), array( 'code' => '{avatar size="48"}', 'label' => __( 'Avatar', 'advance-menu-manager' ), ), ); } /** * Whether a string contains any supported placeholder. * * @param string $value Field value. * @return bool */ public static function has_placeholders( $value ) { if ( ! is_string( $value ) || '' === $value ) { return false; } if ( false !== strpos( $value, '{avatar' ) ) { return true; } foreach ( array_keys( self::get_text_placeholders() ) as $key ) { if ( false !== strpos( $value, '{' . $key . '}' ) ) { return true; } } return false; } /** * Replace placeholders in nav menu item objects on the frontend. * * @param array $items Menu items. * @param object $args Menu arguments. * @return array */ public static function replace_in_menu_items( $items, $args ) { unset( $args ); if ( empty( $items ) || ! is_array( $items ) ) { return $items; } if ( is_admin() && ! wp_doing_ajax() ) { return $items; } $user = wp_get_current_user(); $logged_in = ( $user instanceof WP_User ) && 0 !== (int) $user->ID; foreach ( $items as $index => $item ) { if ( ! is_object( $item ) ) { continue; } if ( isset( $item->title ) && self::has_placeholders( $item->title ) ) { $items[ $index ]->title = $logged_in ? self::replace_placeholders( $item->title, $user, 'title' ) : self::strip_placeholders( $item->title ); } if ( isset( $item->attr_title ) && self::has_placeholders( $item->attr_title ) ) { $items[ $index ]->attr_title = $logged_in ? self::replace_placeholders( $item->attr_title, $user, 'attr_title' ) : self::strip_placeholders( $item->attr_title ); } if ( isset( $item->description ) && self::has_placeholders( $item->description ) ) { $items[ $index ]->description = $logged_in ? self::replace_placeholders( $item->description, $user, 'description' ) : self::strip_placeholders( $item->description ); } if ( isset( $item->url ) && self::has_placeholders( $item->url ) ) { $items[ $index ]->url = $logged_in ? self::replace_placeholders( $item->url, $user, 'url' ) : self::strip_placeholders( $item->url ); } } return $items; } /** * Replace all placeholders in a string for the given user. * * @param string $value Field value. * @param WP_User $user Current user. * @param string $context Field context: title|attr_title|description|url. * @return string */ public static function replace_placeholders( $value, $user, $context = 'title' ) { if ( ! is_string( $value ) || '' === $value || ! ( $user instanceof WP_User ) ) { return $value; } $value = self::replace_text_placeholders( $value, $user ); $value = self::replace_avatar_placeholders( $value, $user, $context ); /** * Filter the menu field value after user placeholder replacement. * * @param string $value Replaced value. * @param WP_User $user Current user. * @param string $context Field context. */ return apply_filters( 'dsamm_menu_user_placeholder_value', $value, $user, $context ); } /** * Replace text placeholders. * * @param string $value Field value. * @param WP_User $user Current user. * @return string */ private static function replace_text_placeholders( $value, $user ) { foreach ( self::get_text_placeholders() as $placeholder => $property ) { $token = '{' . $placeholder . '}'; if ( false === strpos( $value, $token ) ) { continue; } $replacement = ''; if ( 'first_name' === $property || 'last_name' === $property || 'nickname' === $property ) { $replacement = (string) $user->get( $property ); } elseif ( isset( $user->{$property} ) ) { $replacement = (string) $user->{$property}; } $value = str_replace( $token, $replacement, $value ); } return $value; } /** * Replace avatar placeholders. * * @param string $value Field value. * @param WP_User $user Current user. * @param string $context Field context. * @return string */ private static function replace_avatar_placeholders( $value, $user, $context ) { if ( false === strpos( $value, '{avatar' ) ) { return $value; } return preg_replace_callback( '/\{avatar(?:\s+size=(["\']?)(\d+)\1)?\}/i', function( $matches ) use ( $user, $context ) { $size = ! empty( $matches[2] ) ? absint( $matches[2] ) : self::DEFAULT_AVATAR_SIZE; $size = max( self::MIN_AVATAR_SIZE, min( self::MAX_AVATAR_SIZE, $size ) ); if ( 'url' === $context || 'attr_title' === $context ) { $url = get_avatar_url( $user->ID, array( 'size' => $size ) ); return $url ? $url : ''; } $avatar = get_avatar( $user->ID, $size, '', $user->display_name, array( 'class' => 'amm-user-avatar', ) ); return is_string( $avatar ) ? $avatar : ''; }, $value ); } /** * Remove all supported placeholders from a string (replace with empty). * * Used for logged-out visitors so raw placeholder tokens are never visible. * * @param string $value Field value. * @return string */ private static function strip_placeholders( $value ) { if ( ! is_string( $value ) || '' === $value ) { return $value; } foreach ( array_keys( self::get_text_placeholders() ) as $key ) { $value = str_replace( '{' . $key . '}', '', $value ); } $value = preg_replace( '/\{avatar(?:\s+size=(["\']?)\d+\1)?\}/i', '', $value ); return trim( $value ); } /** * Render admin help for available placeholders. * * @param int $menu_item_id Menu item ID. * @param array $args Optional args. */ public static function render_help( $menu_item_id, $args = array() ) { $defaults = array( 'readonly' => false, ); $args = wp_parse_args( $args, $defaults ); $menu_item_id = (int) $menu_item_id; $examples = self::get_placeholder_examples(); $toggle_id = 'amm-user-placeholders-body-' . $menu_item_id; ?>