: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Class that generates custom markup for mega menu that shows posts by categories
defined( 'ABSPATH' ) || exit;
if( ! class_exists( 'Themify_Mega_Menu_Walker', false ) ) {
* Class Themify_Mega_Menu_Walker generates menu with posts by category
class Themify_Mega_Menu_Walker extends Walker_Nav_Menu {
static $mega_open = false;
private static $hasLayout=false;
private static $open=false;
static $disableAssetsLoading=false;
* render a widget menu item
* $class_names additional CSS classes to add to the menu wrapper
function render_widget_menu( $item, int $depth, string $class_names = '' ):string {
$title = apply_filters( 'the_title', $item->title, $item->ID );
$output = "<li class='{$class_names}'><a role='button' tabindex='0'>" . $title . '<span class="child-arrow"></span></a><ul class="sub-menu tf_box">';
$menu_widget = Themify_Widgets_Menu::get_instance()->get_widget_menu_class( $item );
$output .= '<li class="themify-widget-menu">';
$output .= sprintf( '<!--themify_widget_menu %s %s -->', $menu_widget, $item->ID );
* Render a Layout Part inside menu
* $class_names additional CSS classes to add to the menu wrapper
function render_layout_part( $item,int $depth,string $class_names = '' ):string {
$title = apply_filters( 'the_title', $item->title, $item->ID );
$output = "<li class='{$class_names}'><a role='button' tabindex='0'>" . $title . '<span class="child-arrow"></span></a><ul class="sub-menu tf_box">';
$output .= '<li class="themify-widget-menu">' . do_shortcode( sprintf( '[themify_layout_part id="%s"]', $item->object_id ) );
function start_el( &$output, $item, $depth = 0, $args = array(), $current_object_id = 0 ) {
$classes = empty ( $item->classes ) ? array () : (array) $item->classes;
if( $item->type === 'taxonomy' ){
$classes[]='menu-item-'.$item->ID;
/** This filter is documented in wp-includes/class-walker-nav-menu.php */
$args = apply_filters( 'nav_menu_item_args', $args, $item, $depth );
$classes = implode(' ', apply_filters('nav_menu_css_class', array_keys(array_flip(array_filter($classes) )), $item, $args, $depth ));
/** This filter is documented in wp-includes/class-walker-nav-menu.php */
$id = apply_filters( 'nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args, $depth );
/* handle the display of widget menu items */
if( Themify_Widgets_Menu::get_instance()->is_menu_widget( $item ) ) {
$item_output= $this->render_widget_menu( $item, $depth, $classes );
} else if ( $item->type === 'post_type' && $item->object === 'tbuilder_layout_part' ) {
$item_output = $this->render_layout_part( $item, $depth, $classes );
'id' => ! empty( $id ) ? $id : '',
'class' => ! empty( $classes ) ? $classes : ''
/* required for "mega" menu type which displays posts from a taxonomy term */
if ( $item->type === 'taxonomy' ) {
$li_attributes['data-termid']= $item->object_id;
$li_attributes['data-tax']= $item->object;
if ( $args->walker->has_children > 0 ) {
$li_attributes['aria-haspopup'] = "true";
/** This filter is documented in wp-includes/class-walker-nav-menu.php */
$li_attributes = apply_filters( 'nav_menu_item_attributes', $li_attributes, $item, $args, $depth );
$output .= '<li ' . $this->build_atts( $li_attributes ) . '>';
$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';
$atts['rel'] = $item->xfn;
if ( ! empty( $item->url ) ) {
if ( get_privacy_policy_url() === $item->url ) {
$atts['rel'] = empty( $atts['rel'] ) ? 'privacy-policy' : $atts['rel'] . ' privacy-policy';
$atts['href'] = $item->url;
$atts['aria-current'] = $item->current ? 'page' : '';
/** This filter is documented in wp-includes/class-walker-nav-menu.php */
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );
/** This filter is documented in wp-includes/post-template.php */
$title = apply_filters( 'the_title', $item->title, $item->ID );
/** This filter is documented in wp-includes/class-walker-nav-menu.php */
$title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth );
$item_output = $args->before. '<a ' . $this->build_atts( $atts ) . '>' . $args->link_before . $title;
if(isset($args->post_count) && $args->post_count===true && $item->type==='taxonomy'){
$term = get_term( $item->object_id, $item->object );
$item_output.='<span class="tf_post_count">'.$term->count.'</span>';
if($args->walker->has_children>0){
$item_output.='<span class="child-arrow"></span>';
if ( ! empty( $item->post_content ) && themify_check( 'menu_description', true ) ) {
$item_output .= '<small>' . esc_html( $item->post_content ) . '</small>';
$item_output.='</a> ' . $args->link_after . $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
function start_lvl( &$output, $depth = 0, $args = array() ) {
if(self::$hasLayout==='layout'){
elseif(self::$hasLayout==='ajax'){
$cl='tf_mega_taxes tf_left tf_box';
$output.='<div class="mega-sub-menu sub-menu tf_scrollbar">';
$output .= '<ul class="'.$cl.'">';
function end_lvl( &$output, $depth = 0, $args = array() ) {
* @param array $children_elements
function display_element( $item, &$children_elements, $max_depth, $depth, $args, &$output ) {
$id_field = $this->db_fields['id'];
if ( themify_is_menu_highlighted_link($item->ID) ) {
$item->classes[] = 'highlight-link';
if ( in_array( 'mega', $item->classes,true ) || themify_is_mega_menu_type( $item->ID, 'mega' )){ // backward compatibility
$item->classes[] = 'mega';
$item->classes[] = 'has-mega-sub-menu';
$item->classes[] = 'has-mega';
elseif(in_array( 'columns', $item->classes,true ) || themify_is_mega_menu_type( $item->$id_field, 'column' )){// backwards compatibility
$item->classes[] = 'has-mega-column';
$item->classes[] = 'has-mega';
if( $column_layout = get_post_meta( $item->ID, '_themify_mega_menu_columns_layout', true ) ) {
$item->classes[] = 'layout-' . $column_layout;
$item->classes[] = 'layout-auto';
self::$hasLayout='layout';
elseif(($dropdown_columns = get_post_meta( $item->$id_field, '_themify_dropdown_columns', true ))){
$item->classes[] = 'has-mega-dropdown dropdown-columns-' . $dropdown_columns;
elseif(in_array( 'columns-sub-item', $item->classes,true ) ) {
if ( ! empty( $children_elements[ $item->$id_field ] ) ) {
$item->classes[] = 'has-sub-menu';
foreach( $children_elements[ $item->$id_field ] as $child ) {
Walker_Nav_Menu::display_element( $item, $children_elements, $max_depth, $depth, $args, $output );
public static function preloadCssJs(){
if(self::$disableAssetsLoading===false){
if ( themify_is_themify_theme() ) {
themify_enque_style('tf_megamenu',THEMIFY_URI . '/megamenu/css/style.css',null,THEMIFY_VERSION,'screen and (min-width:' . (Themify_Enqueue_Assets::$mobileMenuActive + 1) . 'px)');
Themify_Enqueue_Assets::addLocalization('done','tf_megamenu',true);
* copy of Walker_Nav_Menu::build_atts, for compatibility with WP < 6.3.0
* documented in wp-includes/class-walker-nav-menu.php
protected function build_atts( $atts = array() ) {
foreach ( $atts as $attr => $value ) {
if ( false !== $value && '' !== $value && is_scalar( $value ) ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attribute_string .= ' ' . $attr . '="' . $value . '"';
return $attribute_string;
if( ! function_exists('themify_theme_mega_get_posts') ) {
* Returns posts from a taxonomy by a given term
function themify_theme_mega_get_posts( $term_id, $taxonomy ):string {
$taxObject = get_taxonomy( $taxonomy );
if ( is_wp_error( $taxObject ) || empty( $taxObject ) ) {
$postPerPage = themify_get( 'setting-mega_menu_posts', 5, true );
$term_query_args = apply_filters( 'themify_mega_menu_query',
'post_type' => $taxObject->object_type,
'suppress_filters' => false,
'posts_per_page' => $postPerPage
$posts = get_posts( $term_query_args );
$saved_post = clone $post;
$template = locate_template( array(
'includes/loop-megamenu-'.get_post_type().'.php',
'includes/loop-megamenu.php',
$template = THEMIFY_DIR . '/megamenu/templates/loop-megamenu.php';
foreach( $posts as $p ) {
$mega_posts = ob_get_clean();
if ( isset( $saved_post )) {
setup_postdata( $saved_post );
$mega_posts = '<article itemscope itemtype="https://schema.org/Article" class="post"><p class="post-title">'.__('Error loading posts.', 'themify').'</p></article>';
return apply_filters( 'themify_mega_posts_output', $mega_posts, $term_id, $taxonomy );
if( ! function_exists( 'themify_theme_mega_posts' ) ) {
* Called with AJAX to return posts
function themify_theme_mega_posts() {
$termid = isset( $_POST['termid'] )? $_POST['termid']: '';
$taxonomy = isset( $_POST['tax'] )? $_POST['tax']: 'category';
die(themify_theme_mega_get_posts( $termid, $taxonomy ));
add_action('wp_ajax_themify_theme_mega_posts', 'themify_theme_mega_posts');
add_action('wp_ajax_nopriv_themify_theme_mega_posts', 'themify_theme_mega_posts');
/***************************************************
* Themify Theme Access Point
***************************************************/
if ( ! function_exists( 'themify_theme_main_menu' ) ) {
* Sets custom menu selected in page custom panel as navigation, otherwise sets the default.
function themify_theme_main_menu( $args = array() ) {
if( 'no' !== themify_get( 'setting-mega_menu',false,true ) ) {
$args['walker'] = new Themify_Mega_Menu_Walker;
echo apply_filters( 'themify_' . $menu_type . '_menu_html', themify_menu_nav( $args ), $args );
* Check if mega menu is enabled for a menu item
function themify_is_mega_menu_type( $item_id, $type = 'mega' ) {
if($type==='mega' || $type==='column' || $type==='dual'){
$key=$type==='mega'?'item':$type;
return get_post_meta( $item_id, '_themify_mega_menu_'.$key, true ) == '1';
function themify_is_menu_highlighted_link( $item_id ) {
return get_post_meta( $item_id, '_themify_highlight_link', true );
* Add the option to enable mega menu to taxonomy menu types
function themify_menu_mega_option( $item_id, $item, $depth, $args ) {
$dropdown_columns = (int) get_post_meta( $item_id, '_themify_dropdown_columns', true );
$is_mega = themify_is_mega_menu_type( $item_id, 'mega' );
$is_column = !$is_mega && themify_is_mega_menu_type( $item_id, 'column' );
$is_dropdown_column = !$is_column && ! empty( $dropdown_columns );
$column_layout = get_post_meta( $item_id, '_themify_mega_menu_columns_layout', true );
<div class="field-tf-mega description description-thin">
<label for="edit-menu-item-tf-mega-<?php echo $item_id; ?>">
<?php _e( 'Mega Menu', 'themify' ) ?>
<a href="https://themify.me/docs/builder#mega-menu" target="_blank"><i class="ti-help"></i></a>
<select name="menu-item-tf-mega[<?php echo $item_id; ?>]" id="edit-menu-item-tf-mega-<?php echo $item_id?>" class="edit-menu-item-tf-mega themify_field_tf-mega widefat">
<option value=""></option>
<option value="mega" <?php if( $is_mega ) echo 'selected';?>><?php _e( 'Mega Posts', 'themify' ); ?></option>
<option value="columns" <?php if( $is_column ) echo 'selected';?>><?php _e( 'Fullwidth Columns', 'themify' ); ?></option>
<option value="drop" <?php if( $is_dropdown_column===true ) echo 'selected';?>><?php _e( 'Dropdown Columns', 'themify' ); ?></option>
<div class="tf-mega-columns-layout">
echo '<input type="hidden" name="menu-item-tf-mega-columns-layout[' . $item_id . ']" value="'.$column_layout.'" class="val">';
'' => __( 'Auto', 'themify' ),
'4-8' => __( '1/3 - 2/3', 'themify' ),
'8-4' => __( '2/3 - 1/3', 'themify' ),
'6-3-3' => __( '2/4 - 1/4 - 1/4', 'themify' ),
'3-3-6' => __( '1/4 - 1/4 - 2/4', 'themify' ),
'3-6-3' => __( '1/4 - 2/4 - 1/4', 'themify' ),
'3-9' => __( '1/4 - 3/4', 'themify' ),
'9-3' => __( '3/4 - 1/4', 'themify' ),
$selected = $column_layout === $key ? 'class="selected"' : '';
echo '<a href="#" ' . $selected . ' data-value="'. $key . '" title="' . $label . '"></a>';
<p class="tf-dropdown-columns-field description description-thin">
<label for="edit-menu-item-tf-dropdown-columns-<?php echo $item_id; ?>">
<?php _e( 'Dropdown Columns', 'themify' ) ?><br />
<select name="menu-item-tf-dropdown_columns[<?php echo $item_id; ?>]" id="edit-menu-item-tf-dropdown_columns-<?php echo $item_id?>" class="edit-menu-item-tf-dropdown_columns">
<option value=""></option>
<option value="2" <?php selected( 2, $dropdown_columns ) ?>>2</option>
<option value="3" <?php selected( 3, $dropdown_columns ) ?>>3</option>
<option value="4" <?php selected( 4, $dropdown_columns ) ?>>4</option>
$allow_hightlight = apply_filters( 'themify_menu_highlight_link', false);
$highlight = get_post_meta( $item_id, '_themify_highlight_link', true );
<div class="field-tf-highlight description description-thin"><br>
<label for="edit-menu-item-tf-highlight-<?php echo $item_id; ?>">
<input type="checkbox" name="menu-item-tf-highlight[<?php echo $item_id; ?>]" value="1" <?php echo ($highlight ? 'checked="checked"' : ''); ?> id="edit-menu-item-tf-highlight-<?php echo $item_id?>" class="edit-menu-item-tf-highlight themify_field_tf-highlight widefat">
<?php _e( 'Highlight this link', 'themify' ) ?><br />
add_action( 'wp_nav_menu_item_custom_fields', 'themify_menu_mega_option', 12, 4 );
* Save the mega menu option for menu items
function themify_update_mega_menu_option( $menu_id, $menu_item_db_id, $args ) {
'_themify_mega_menu_item_tax' => 'menu-item-tf-mega_tax',
'_themify_mega_menu_columns_layout' => 'menu-item-tf-mega-columns-layout',
'_themify_highlight_link' => 'menu-item-tf-highlight',
* save Mega Menu <select> option
* the Mega Menu option saves as two different custom fields, for backwards compatibility
if ( isset( $_POST['menu-item-tf-mega'][$menu_item_db_id] ) ) {
/* delete both keys first to ensure they are not both activated on a menu item at the same time */