File: /www/wwwroot/www.sceysls.com/wp-content/themes/Zing-Pro/public/zing-functions.php
<?php
define( 'DAHUZI_EDD_ID', '84122' ); //主题id,不可更改
define( 'DAHUZI_THEME_NAME', 'Zing主题' ); //主题名字,不可更改
//define( 'DAHUZI_THEME_HELP', '' ); //主题文档ID,不可更改
load_theme_textdomain('dahuzi_theme', get_template_directory() . '/languages');
/** --------------------------------------------------------------------------------- *
* 禁用古腾堡小工具
* --------------------------------------------------------------------------------- */
add_filter( 'gutenberg_use_widgets_block_editor', '__return_false' );
add_filter( 'use_widgets_block_editor', '__return_false' );
//注册导航
register_nav_menus(
array(
'main' => '主菜单导航', 'd1' => '底部菜单①', 'd2' => '底部菜单②', 'd3' => '底部菜单③', 'd4' => '底部菜单④'
)
);
//自定义配色
add_filter('body_class',function ($classes) {
if( xintheme('zing_color') != '0' ){
$classes[] = 'zing_color_'.xintheme('zing_color').'';
}
if( xintheme('footer_color') != '0' ){
$classes[] = 'footer_color_'.xintheme('footer_color').'';
}
return $classes;
});
//载入JS\CSS
if ( ! function_exists( 'xintheme_scripts_method' ) ) {
function xintheme_scripts_method() {
//载入css
wp_enqueue_style( 'style', get_bloginfo( 'stylesheet_url' ), array(), wp_get_theme()->get( 'Version' ) );
if( xintheme('data_animate') ){
wp_enqueue_style( 'animate', get_template_directory_uri().'/static/css/animate.min.css', array(), wp_get_theme()->get( 'Version' ) );
}
wp_enqueue_style( 'iconfont', get_template_directory_uri().'/static/font/iconfont.css', array(), wp_get_theme()->get( 'Version' ) );
wp_enqueue_style( 'line-awesome', get_template_directory_uri().'/static/line-awesome/css/line-awesome.min.css', array(), '' );
wp_enqueue_style( 'font-awesome-dahuzi', get_template_directory_uri().'/static/font-awesome/css/font-awesome.min.css', array(), '5.15.4', 'all' );
wp_enqueue_style( 'theme-color', get_template_directory_uri().'/static/css/theme-color.css', array(), wp_get_theme()->get( 'Version' ) );
//载入js
//禁止加载默认JQ
if ( !is_admin() ) { // 后台不禁止
wp_deregister_script( 'jquery' ); // 取消原有的 jquery 定义
wp_deregister_script( 'l10n' );
}
wp_enqueue_script('jquery', get_template_directory_uri() . '/static/js/jquery-1.7.2.min.js', array(),false);
wp_enqueue_script('script', get_template_directory_uri() . '/static/js/script.min.js', array('jquery'),false, true);
wp_enqueue_script('xintheme', get_template_directory_uri() . '/static/js/xintheme.js', array(),false, true);
wp_enqueue_script('theia-sticky-sidebar', get_template_directory_uri() . '/static/js/theia-sticky-sidebar.js', array(),false, true);
//fancybox
wp_enqueue_style('fancybox', get_template_directory_uri().'/static/fancybox3/jquery.fancybox.min.css');
wp_enqueue_script('fancybox3', get_template_directory_uri().'/static/fancybox3/jquery.fancybox.min.js', ['jquery'], '', true);
if( xintheme('notice_code_switch') ){
$head_notice = 'true';
}else{
$head_notice = 'false';
}
wp_localize_script('script', 'dahuzi', [
'ajaxurl' => admin_url('admin-ajax.php'),
'submit_success' => __('Success', 'dahuzi_theme'),
'please_wait' => __('Please wait...', 'dahuzi_theme'),
'submit' => __('Send Message', 'dahuzi_theme'),
]);
if( xintheme('data_animate') ){
wp_enqueue_script('animate', get_template_directory_uri() . '/static/js/animate.min.js', array(),false);
wp_localize_script('animate', 'xintheme', ['data_animate' => 'true','head_notice' => $head_notice]);
}else{
wp_localize_script('xintheme', 'xintheme', ['data_animate' => 'false','head_notice' => $head_notice]);
}
if (is_singular() && comments_open() && get_option('thread_comments')){
wp_enqueue_script( 'comment-reply' );
}
wp_enqueue_script('carousel', get_template_directory_uri() . '/static/js/owl.carousel.min.js', array(),false, true);
}
}
add_action('wp_enqueue_scripts', 'xintheme_scripts_method');
//自动添加暗箱标签属性
add_filter('the_content', 'pirobox_gall_replace');
function pirobox_gall_replace ($content){
global $post;
$pattern = "/<a(.*?)href=('|\")([^>]*).(bmp|gif|jpeg|jpg|png|webp)('|\")(.*?)>(.*?)<\/a>/i";
$replacement = '<a$1href=$2$3.$4$5 data-fancybox="images"$6>$7</a>';
$content = preg_replace($pattern, $replacement, $content);
return $content;
}
//加载动画 css
function xintheme_color_css() {
if( xintheme('data_animate') ){
echo '<style>.not-animated {opacity:0}</style>';
}
if( xintheme('xintheme_post_indent') && is_single() ){
echo '<style>#wzzt p {text-indent: 2em}</style>';
}
}
add_action('wp_head', 'xintheme_color_css');
//判断是否开启模块加载动画
function data_animate(){
if( xintheme('data_animate') ){
return ' data-animate="fadeInUp" data-delay="200"';
}
}
//移除WPjam插件的某些选项
if( defined('WPJAM_BASIC_PLUGIN_FILE') ){
add_filter('wpjam_extends_setting', function($wpjam_setting){
unset($wpjam_setting['fields']['related-posts.php']);//移除相关文章
unset($wpjam_setting['fields']['wpjam-postviews.php']);//移除文章浏览量
unset($wpjam_setting['fields']['mobile-theme.php']);//移除手机端主题选项
unset($wpjam_setting['fields']['wpjam-rewrite.php']);//移除Rewrite 优化
return $wpjam_setting;
}, 99);
$wpjam_extends = get_option('wpjam-extends');
if($wpjam_extends){
$wpjam_extends_updated = false;
if(!empty($wpjam_extends['related-posts.php'])){
unset($wpjam_extends['related-posts.php']);
$wpjam_extends_updated = true;
}
if(!empty($wpjam_extends['wpjam-postviews.php'])){
unset($wpjam_extends['wpjam-postviews.php']);
$wpjam_extends_updated = true;
}
if(!empty($wpjam_extends['mobile-theme.php'])){
unset($wpjam_extends['mobile-theme.php']);
$wpjam_extends_updated = true;
}
if($wpjam_extends_updated){
update_option('wpjam-extends', $wpjam_extends);
}
}
}
// 获取文章缩略图
function post_thumbnail($width=400, $height=200, $echo=1){
global $post, $is_chrome;
$default_timthumb = dahuzi_img('default_timthumb');
$cdn_type = dahuzi('cdn_type');
$dir = get_bloginfo('template_directory');
if( has_post_thumbnail() ){
$timthumb_src = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID),'full');
$img_url = $timthumb_src[0];
if( $cdn_type == 'qiniu' ){
if( $is_chrome || is_android_dahuzi() ){
$src = "$img_url?imageView2/1/format/webp/w/$width/h/$height/q/100";
}else{
$src = "$img_url?imageView2/1/w/$width/h/$height/q/100";
}
}elseif( $cdn_type == 'alioss' ){
if( $is_chrome || is_android_dahuzi() ){
$src = "$img_url?x-oss-process=image/resize,m_fill,w_$width,h_$height/format,webp";
}else{
$src = "$img_url?x-oss-process=image/resize,m_fill,w_$width,h_$height";
}
}else{
//$src = $img_url;
if( dahuzi('dahuzi_thumbnail_link') ){
$src = $img_url;
}else{
$src = "$dir/prune.php?src=$img_url&w=$width&h=$height&zc=1&q=100";
}
}
}else{
ob_start();
ob_end_clean();
$output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches ,PREG_SET_ORDER);
$cnt = count( $matches );
if($cnt>0){
$img_url = $matches[0][1];
if( $cdn_type == 'qiniu' ){
if( $is_chrome || is_android_dahuzi() ){
$src = "$img_url?imageView2/1/format/webp/w/$width/h/$height/q/100";
}else{
$src = "$img_url?imageView2/1/format/webp/w/$width/h/$height/q/100";
}
}elseif( $cdn_type == 'alioss' ){
if( $is_chrome || is_android_dahuzi() ){
$src = "$img_url?x-oss-process=image/resize,m_fill,w_$width,h_$height/format,webp";
}else{
$src = "$img_url?x-oss-process=image/resize,m_fill,w_$width,h_$height";
}
}else{
//$src = $img_url; // 使用文章内第一张图作为文章缩略图
if( dahuzi('dahuzi_thumbnail_link') ){
$src = $img_url;
}else{
$src = "$dir/prune.php?src=$img_url&w=$width&h=$height&zc=1&q=100";
}
}
}else{
//$src = $default_timthumb; // 默认缩略图
if( dahuzi('dahuzi_thumbnail_link') ){
$src = $default_timthumb;
}else{
$src = "$dir/prune.php?src=$default_timthumb&w=$width&h=$height&zc=1&q=100";
}
}
}
return $src;
}
# 清除wp所有自带的customize选项
# ------------------------------------------------------------------------------
function remove_default_settings_customize( $wp_customize ) {
$wp_customize->remove_section( 'title_tagline');
$wp_customize->remove_section( 'colors');
$wp_customize->remove_section( 'header_image');
$wp_customize->remove_section( 'background_image');
//$wp_customize->remove_panel( 'nav_menus');
$wp_customize->remove_section( 'static_front_page');
$wp_customize->remove_section( 'custom_css');
//$wp_customize->remove_panel( 'widgets' );
}
add_action( 'customize_register', 'remove_default_settings_customize',50 );
//后台禁止加载谷歌字体
function wp_style_del_web( $src, $handle ) {
if( strpos(strtolower($src),'fonts.googleapis.com') ){
$src='';
}
return $src;
}
add_filter( 'style_loader_src', 'wp_style_del_web', 2, 2 );
//js处理
function wp_script_del_web( $src, $handle ) {
$src_low = strtolower($src);
if( strpos($src_low,'maps.googleapis.com') ){
return str_replace('maps.googleapis.com','ditu.google.cn',$src_low); //google地图
}
if( strpos($src_low,'ajax.googleapis.com') ){
return ''; //无法访问直接去除
}
if( strpos($src_low,'twitter.com') || strpos($src_low,'facebook.com') || strpos($src_low,'youtube.com') ){
return ''; //无法访问直接去除
}
return $src;
}
add_filter( 'script_loader_src', 'wp_script_del_web', 2, 2 );
/** --------------------------------------------------------------------------------- *
* 隐藏后台「在线留言」菜单
* --------------------------------------------------------------------------------- */
if( dahuzi('remove_admin_dahuzi_contact') ){
add_action( 'admin_head', 'remove_admin_dahuzi_contact' );
function remove_admin_dahuzi_contact(){
echo "<style>#toplevel_page_contact{display:none}</style>";
}
}
/** --------------------------------------------------------------------------------- *
* 国外分享按钮
* --------------------------------------------------------------------------------- */
function dahuzi_sharing_links() {
$featured_image = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), 'full' );
return array(
'facebook' => array(
'link' => 'https://www.facebook.com/sharer/sharer.php?u=' . urlencode( get_the_permalink() ),
'icon' => 'facebook',
),
'twitter' => array(
'link' => 'https://twitter.com/intent/tweet?text=' . urlencode( get_the_title() ) . '&url=' . urlencode( get_the_permalink() ),
'icon' => 'twitter',
),
'pinterest' => array(
'link' => 'https://pinterest.com/pin/create/button/?url=' . urlencode( get_the_permalink() ) . '&media=' . urlencode( $featured_image[0] ) . '&description=' . urlencode( get_the_title() ),
'icon' => 'pinterest',
),
'google' => array(
'link' => 'https://plus.google.com/share?url=' . urlencode( get_the_permalink() ) . '&text=' . urlencode( get_the_title() ),
'icon' => 'google-plus',
),
'linkedin' => array(
'link' => 'https://www.linkedin.com/shareArticle?mini=true&url=' . urlencode( get_the_permalink() ) . '&title=' . urlencode( get_the_title() ),
'icon' => 'linkedin',
),
'reddit' => array(
'link' => 'https://reddit.com/submit?url=' . urlencode( get_the_permalink() ) . '&title=' . urlencode( get_the_title() ),
'icon' => 'reddit',
),
'tumblr' => array(
'link' => 'https://www.tumblr.com/widgets/share/tool?canonicalUrl=' . urlencode( get_the_permalink() ) . '&title=' . urlencode( get_the_title() ),
'icon' => 'tumblr',
),
'vk' => array(
'link' => 'http://vk.com/share.php?url=' . urlencode( get_the_permalink() ) . '&title=' . urlencode( get_the_title() ),
'icon' => 'vk',
),
'whatsapp' => array(
'link' => 'https://api.whatsapp.com/send?phone=whatsappphonenumber&text=' . urlencode( get_the_permalink() ) . '&title=' . urlencode( get_the_title() ),
'icon' => 'whatsapp',
),
'email' => array(
'link' => 'mailto:?subject=' . get_the_title() . '&body=' . urlencode( get_the_permalink() ),
'icon' => 'email',
),
);
}
/**
* WP Bootstrap Navwalker
*
* @package WP-Bootstrap-Navwalker
*
* @wordpress-plugin
* Plugin Name: WP Bootstrap Navwalker
* Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker
* Description: A custom WordPress nav walker class to implement the Bootstrap 4 navigation style in a custom theme using the WordPress built in menu manager.
* Author: Edward McIntyre - @twittem, WP Bootstrap, William Patton - @pattonwebz
* Version: 4.3.0
* Author URI: https://github.com/wp-bootstrap
* GitHub Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker
* GitHub Branch: master
* License: GPL-3.0+
* License URI: http://www.gnu.org/licenses/gpl-3.0.txt
*/
// Check if Class Exists.
if ( ! class_exists( 'WP_Bootstrap_Navwalker' ) ) :
/**
* WP_Bootstrap_Navwalker class.
*/
class WP_Bootstrap_Navwalker extends Walker_Nav_Menu {
/**
* Whether the items_wrap contains schema microdata or not.
*
* @since 4.2.0
* @var boolean
*/
private $has_schema = false;
/**
* Ensure the items_wrap argument contains microdata.
*
* @since 4.2.0
*/
public function __construct() {
if ( ! has_filter( 'wp_nav_menu_args', array( $this, 'add_schema_to_navbar_ul' ) ) ) {
add_filter( 'wp_nav_menu_args', array( $this, 'add_schema_to_navbar_ul' ) );
}
}
/**
* Starts the list before the elements are added.
*
* @since WP 3.0.0
*
* @see Walker_Nav_Menu::start_lvl()
*
* @param string $output Used to append additional content (passed by reference).
* @param int $depth Depth of menu item. Used for padding.
* @param WP_Nav_Menu_Args $args An object of wp_nav_menu() arguments.
*/
public function start_lvl( &$output, $depth = 0, $args = null ) {
if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
$t = '';
$n = '';
} else {
$t = "\t";
$n = "\n";
}
$indent = str_repeat( $t, $depth );
// Default class to add to the file.
$classes = array( 'dropdown-menu' );
/**
* Filters the CSS class(es) applied to a menu list element.
*
* @since WP 4.8.0
*
* @param array $classes The CSS classes that are applied to the menu `<ul>` element.
* @param stdClass $args An object of `wp_nav_menu()` arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$class_names = join( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
/*
* The `.dropdown-menu` container needs to have a labelledby
* attribute which points to it's trigger link.
*
* Form a string for the labelledby attribute from the the latest
* link with an id that was added to the $output.
*/
$labelledby = '';
// Find all links with an id in the output.
preg_match_all( '/(<a.*?id=\"|\')(.*?)\"|\'.*?>/im', $output, $matches );
// With pointer at end of array check if we got an ID match.
if ( end( $matches[2] ) ) {
// Build a string to use as aria-labelledby.
$labelledby = 'aria-labelledby="' . esc_attr( end( $matches[2] ) ) . '"';
}
$output .= '<i class="fa fa-sort-down mobile_dropdown_icon"></i>';
$output .= "{$n}{$indent}<ul$class_names $labelledby>{$n}";
}
/**
* Starts the element output.
*
* @since WP 3.0.0
* @since WP 4.4.0 The {@see 'nav_menu_item_args'} filter was added.
*
* @see Walker_Nav_Menu::start_el()
*
* @param string $output Used to append additional content (passed by reference).
* @param WP_Nav_Menu_Item $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param WP_Nav_Menu_Args $args An object of wp_nav_menu() arguments.
* @param int $id Current item ID.
*/
public function start_el( &$output, $item, $depth = 0, $args = null, $id = 0 ) {
if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
$t = '';
$n = '';
} else {
$t = "\t";
$n = "\n";
}
$indent = ( $depth ) ? str_repeat( $t, $depth ) : '';
if ( false !== strpos( $args->items_wrap, 'itemscope' ) && false === $this->has_schema ) {
$this->has_schema = true;
$args->link_before = '<span itemprop="name">' . $args->link_before;
$args->link_after .= '</span>';
}
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
// Updating the CSS classes of a menu item in the WordPress Customizer preview results in all classes defined
// in that particular input box to come in as one big class string.
$split_on_spaces = function ( $class ) {
return preg_split( '/\s+/', $class );
};
$classes = $this->flatten( array_map( $split_on_spaces, $classes ) );
/*
* Initialize some holder variables to store specially handled item
* wrappers and icons.
*/
$linkmod_classes = array();
$icon_classes = array();
/*
* Get an updated $classes array without linkmod or icon classes.
*
* NOTE: linkmod and icon class arrays are passed by reference and
* are maybe modified before being used later in this function.
*/
$classes = self::separate_linkmods_and_icons_from_classes( $classes, $linkmod_classes, $icon_classes, $depth );
// Join any icon classes plucked from $classes into a string.
$icon_class_string = join( ' ', $icon_classes );
/**
* Filters the arguments for a single nav menu item.
*
* @since WP 4.4.0
*
* @param WP_Nav_Menu_Args $args An object of wp_nav_menu() arguments.
* @param WP_Nav_Menu_Item $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
*
* @var WP_Nav_Menu_Args
*/
$args = apply_filters( 'nav_menu_item_args', $args, $item, $depth );
// Add .dropdown or .active classes where they are needed.
if ( $this->has_children ) {
$classes[] = 'dropdown';
}
if ( in_array( 'current-menu-item', $classes, true ) || in_array( 'current-menu-parent', $classes, true ) ) {
$classes[] = 'active';
}
// Add some additional default classes to the item.
$classes[] = 'menu-item-' . $item->ID;
$classes[] = 'nav-item';
// Allow filtering the classes.
$classes = apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth );
// Form a string of classes in format: class="class_names".
$class_names = join( ' ', $classes );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
/**
* Filters the ID applied to a menu item's list item element.
*
* @since WP 3.0.1
* @since WP 4.1.0 The `$depth` parameter was added.
*
* @param string $menu_id The ID that is applied to the menu item's `<li>` element.
* @param WP_Nav_Menu_Item $item The current menu item.
* @param WP_Nav_Menu_Args $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$id = apply_filters( 'nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args, $depth );
$id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
$output .= $indent . '<li ' . $id . $class_names . '>';
// Initialize array for holding the $atts for the link item.
$atts = array();
$atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : '';
$atts['target'] = ! empty( $item->target ) ? $item->target : '';
if ( '_blank' === $item->target && empty( $item->xfn ) ) {
$atts['rel'] = 'noopener noreferrer';
} else {
$atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
}
// If the item has_children add atts to <a>.
if ( $this->has_children && 0 === $depth ) {
//$atts['href'] = '#'; //一级菜单不可点击
$atts['href'] = $item->url;
//$atts['data-toggle'] = 'dropdown'; //一级菜单不可点击
$atts['aria-haspopup'] = 'true';
$atts['aria-expanded'] = 'false';
$atts['class'] = 'dropdown-toggle nav-link';
$atts['id'] = 'menu-item-dropdown-' . $item->ID;
} else {
if ( true === $this->has_schema ) {
$atts['itemprop'] = 'url';
}
$atts['href'] = ! empty( $item->url ) ? $item->url : '#';
// For items in dropdowns use .dropdown-item instead of .nav-link.
if ( $depth > 0 ) {
$atts['class'] = 'dropdown-item';
} else {
$atts['class'] = 'nav-link';
}
}
$atts['aria-current'] = $item->current ? 'page' : '';
// Update atts of this item based on any custom linkmod classes.
$atts = self::update_atts_for_linkmod_type( $atts, $linkmod_classes );
// Allow filtering of the $atts array before using it.
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );
// Build a string of html containing all the atts for the item.
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( ! empty( $value ) ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
// Set a typeflag to easily test if this is a linkmod or not.
$linkmod_type = self::get_linkmod_type( $linkmod_classes );
// START appending the internal item contents to the output.
$item_output = isset( $args->before ) ? $args->before : '';
/*
* This is the start of the internal nav item. Depending on what
* kind of linkmod we have we may need different wrapper elements.
*/
if ( '' !== $linkmod_type ) {
// Is linkmod, output the required element opener.
$item_output .= self::linkmod_element_open( $linkmod_type, $attributes );
} else {
// With no link mod type set this must be a standard <a> tag.
$item_output .= '<a' . $attributes . '>';
}
/*
* Initiate empty icon var, then if we have a string containing any
* icon classes form the icon markup with an <i> element. This is
* output inside of the item before the $title (the link text).
*/
$icon_html = '';
if ( ! empty( $icon_class_string ) ) {
// Append an <i> with the icon classes to what is output before links.
//不输出图标html
//$icon_html = '<i class="' . esc_attr( $icon_class_string ) . '" aria-hidden="true"></i> ';
}
/** This filter is documented in wp-includes/post-template.php */
$title = apply_filters( 'the_title', $item->title, $item->ID );
/**
* Filters a menu item's title.
*
* @since WP 4.4.0
*
* @param string $title The menu item's title.
* @param WP_Nav_Menu_Item $item The current menu item.
* @param WP_Nav_Menu_Args $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth );
// If the .sr-only class was set apply to the nav items text only.
if ( in_array( 'sr-only', $linkmod_classes, true ) ) {
$title = self::wrap_for_screen_reader( $title );
$keys_to_unset = array_keys( $linkmod_classes, 'sr-only', true );
foreach ( $keys_to_unset as $k ) {
unset( $linkmod_classes[ $k ] );
}
}
// Put the item contents into $output.
$item_output .= isset( $args->link_before ) ? $args->link_before . $icon_html . $title . $args->link_after : '';
/*
* This is the end of the internal nav item. We need to close the
* correct element depending on the type of link or link mod.
*/
if ( '' !== $linkmod_type ) {
// Is linkmod, output the required closing element.
$item_output .= self::linkmod_element_close( $linkmod_type );
} else {
// With no link mod type set this must be a standard <a> tag.
$item_output .= '</a>';
}
$item_output .= isset( $args->after ) ? $args->after : '';
// END appending the internal item contents to the output.
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
/**
* Menu fallback.
*
* If this function is assigned to the wp_nav_menu's fallback_cb variable
* and a menu has not been assigned to the theme location in the WordPress
* menu manager the function will display nothing to a non-logged in user,
* and will add a link to the WordPress menu manager if logged in as an admin.
*
* @param array $args passed from the wp_nav_menu function.
* @return string|void String when echo is false.
*/
public static function fallback( $args ) {
if ( ! current_user_can( 'edit_theme_options' ) ) {
return;
}
// Initialize var to store fallback html.
$fallback_output = '';
// Menu container opening tag.
$show_container = false;
if ( $args['container'] ) {
/**
* Filters the list of HTML tags that are valid for use as menu containers.
*
* @since WP 3.0.0
*
* @param array $tags The acceptable HTML tags for use as menu containers.
* Default is array containing 'div' and 'nav'.
*/
$allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) );
if ( is_string( $args['container'] ) && in_array( $args['container'], $allowed_tags, true ) ) {
$show_container = true;
$class = $args['container_class'] ? ' class="menu-fallback-container ' . esc_attr( $args['container_class'] ) . '"' : ' class="menu-fallback-container"';
$id = $args['container_id'] ? ' id="' . esc_attr( $args['container_id'] ) . '"' : '';
$fallback_output .= '<' . $args['container'] . $id . $class . '>';
}
}
// The fallback menu.
$class = $args['menu_class'] ? ' class="menu-fallback-menu ' . esc_attr( $args['menu_class'] ) . '"' : ' class="menu-fallback-menu"';
$id = $args['menu_id'] ? ' id="' . esc_attr( $args['menu_id'] ) . '"' : '';
$fallback_output .= '<ul' . $id . $class . '>';
$fallback_output .= '<li class="nav-item"><a href="' . esc_url( admin_url( 'nav-menus.php' ) ) . '" class="nav-link" title="请前往「后台-外观-菜单」中添加菜单,注意勾选菜单显示位置(此处为主菜单)">请前往「后台-外观-菜单」中添加菜单,注意勾选菜单显示位置(此处为主菜单)</a></li>';
$fallback_output .= '</ul>';
// Menu container closing tag.
if ( $show_container ) {
$fallback_output .= '</' . $args['container'] . '>';
}
// if $args has 'echo' key and it's true echo, otherwise return.
if ( array_key_exists( 'echo', $args ) && $args['echo'] ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $fallback_output;
} else {
return $fallback_output;
}
}
/**
* Filter to ensure the items_Wrap argument contains microdata.
*
* @since 4.2.0
*
* @param array $args The nav instance arguments.
* @return array $args The altered nav instance arguments.
*/
public function add_schema_to_navbar_ul( $args ) {
$wrap = $args['items_wrap'];
if ( strpos( $wrap, 'SiteNavigationElement' ) === false ) {
$args['items_wrap'] = preg_replace( '/(>).*>?\%3\$s/', ' itemscope itemtype="http://www.schema.org/SiteNavigationElement"$0', $wrap );
}
return $args;
}
/**
* Find any custom linkmod or icon classes and store in their holder
* arrays then remove them from the main classes array.
*
* Supported linkmods: .disabled, .dropdown-header, .dropdown-divider, .sr-only
* Supported iconsets: Font Awesome 4/5, Glypicons
*
* NOTE: This accepts the linkmod and icon arrays by reference.
*
* @since 4.0.0
*
* @param array $classes an array of classes currently assigned to the item.
* @param array $linkmod_classes an array to hold linkmod classes.
* @param array $icon_classes an array to hold icon classes.
* @param integer $depth an integer holding current depth level.
*
* @return array $classes a maybe modified array of classnames.
*/
private function separate_linkmods_and_icons_from_classes( $classes, &$linkmod_classes, &$icon_classes, $depth ) {
// Loop through $classes array to find linkmod or icon classes.
foreach ( $classes as $key => $class ) {
/*
* If any special classes are found, store the class in it's
* holder array and and unset the item from $classes.
*/
if ( preg_match( '/^disabled|^sr-only/i', $class ) ) {
// Test for .disabled or .sr-only classes.
$linkmod_classes[] = $class;
unset( $classes[ $key ] );
} elseif ( preg_match( '/^dropdown-header|^dropdown-divider|^dropdown-item-text/i', $class ) && $depth > 0 ) {
/*
* Test for .dropdown-header or .dropdown-divider and a
* depth greater than 0 - IE inside a dropdown.
*/
$linkmod_classes[] = $class;
unset( $classes[ $key ] );
} elseif ( preg_match( '/^fa-(\S*)?|^fa(s|r|l|b)?(\s?)?$/i', $class ) ) {
// Font Awesome.
$icon_classes[] = $class;
unset( $classes[ $key ] );
} elseif ( preg_match( '/^glyphicon-(\S*)?|^glyphicon(\s?)$/i', $class ) ) {
// Glyphicons.
$icon_classes[] = $class;
unset( $classes[ $key ] );
}
}
return $classes;
}
/**
* Return a string containing a linkmod type and update $atts array
* accordingly depending on the decided.
*
* @since 4.0.0
*
* @param array $linkmod_classes array of any link modifier classes.
*
* @return string empty for default, a linkmod type string otherwise.
*/
private function get_linkmod_type( $linkmod_classes = array() ) {
$linkmod_type = '';
// Loop through array of linkmod classes to handle their $atts.
if ( ! empty( $linkmod_classes ) ) {
foreach ( $linkmod_classes as $link_class ) {
if ( ! empty( $link_class ) ) {
// Check for special class types and set a flag for them.
if ( 'dropdown-header' === $link_class ) {
$linkmod_type = 'dropdown-header';
} elseif ( 'dropdown-divider' === $link_class ) {
$linkmod_type = 'dropdown-divider';
} elseif ( 'dropdown-item-text' === $link_class ) {
$linkmod_type = 'dropdown-item-text';
}
}
}
}
return $linkmod_type;
}
/**
* Update the attributes of a nav item depending on the limkmod classes.
*
* @since 4.0.0
*
* @param array $atts array of atts for the current link in nav item.
* @param array $linkmod_classes an array of classes that modify link or nav item behaviors or displays.
*
* @return array maybe updated array of attributes for item.
*/
private function update_atts_for_linkmod_type( $atts = array(), $linkmod_classes = array() ) {
if ( ! empty( $linkmod_classes ) ) {
foreach ( $linkmod_classes as $link_class ) {
if ( ! empty( $link_class ) ) {
/*
* Update $atts with a space and the extra classname
* so long as it's not a sr-only class.
*/
if ( 'sr-only' !== $link_class ) {
$atts['class'] .= ' ' . esc_attr( $link_class );
}
// Check for special class types we need additional handling for.
if ( 'disabled' === $link_class ) {
// Convert link to '#' and unset open targets.
$atts['href'] = '#';
unset( $atts['target'] );
} elseif ( 'dropdown-header' === $link_class || 'dropdown-divider' === $link_class || 'dropdown-item-text' === $link_class ) {
// Store a type flag and unset href and target.
unset( $atts['href'] );
unset( $atts['target'] );
}
}
}
}
return $atts;
}
/**
* Wraps the passed text in a screen reader only class.
*
* @since 4.0.0
*
* @param string $text the string of text to be wrapped in a screen reader class.
* @return string the string wrapped in a span with the class.
*/
private function wrap_for_screen_reader( $text = '' ) {
if ( $text ) {
$text = '<span class="sr-only">' . $text . '</span>';
}
return $text;
}
/**
* Returns the correct opening element and attributes for a linkmod.
*
* @since 4.0.0
*
* @param string $linkmod_type a sting containing a linkmod type flag.
* @param string $attributes a string of attributes to add to the element.
*
* @return string a string with the openign tag for the element with attribibutes added.
*/
private function linkmod_element_open( $linkmod_type, $attributes = '' ) {
$output = '';
if ( 'dropdown-item-text' === $linkmod_type ) {
$output .= '<span class="dropdown-item-text"' . $attributes . '>';
} elseif ( 'dropdown-header' === $linkmod_type ) {
/*
* For a header use a span with the .h6 class instead of a real
* header tag so that it doesn't confuse screen readers.
*/
$output .= '<span class="dropdown-header h6"' . $attributes . '>';
} elseif ( 'dropdown-divider' === $linkmod_type ) {
// This is a divider.
$output .= '<div class="dropdown-divider"' . $attributes . '>';
}
return $output;
}
/**
* Return the correct closing tag for the linkmod element.
*
* @since 4.0.0
*
* @param string $linkmod_type a string containing a special linkmod type.
*
* @return string a string with the closing tag for this linkmod type.
*/
private function linkmod_element_close( $linkmod_type ) {
$output = '';
if ( 'dropdown-header' === $linkmod_type || 'dropdown-item-text' === $linkmod_type ) {
/*
* For a header use a span with the .h6 class instead of a real
* header tag so that it doesn't confuse screen readers.
*/
$output .= '</span>';
} elseif ( 'dropdown-divider' === $linkmod_type ) {
// This is a divider.
$output .= '</div>';
}
return $output;
}
/**
* Flattens a multidimensional array to a simple array.
*
* @param array $array a multidimensional array.
*
* @return array a simple array
*/
public function flatten( $array ) {
$result = array();
foreach ( $array as $element ) {
if ( is_array( $element ) ) {
array_push( $result, ...$this->flatten( $element ) );
} else {
$result[] = $element;
}
}
return $result;
}
}
endif;