File: /home/vhosts/harpoeditore.it/httpdocs/wp-content/themes/dt-the7/inc/class-the7-mega-menu.php
<?php
/**
* The7 mega menu front class.
*
* @since 3.0.0
*
* @package The7
*/
defined( 'ABSPATH' ) || exit;
/**
* Class The7_Mega_Menu
*/
class The7_Mega_Menu {
/**
* Columns for second menu level.
*
* @var int
*/
protected $columns = 3;
/**
* Is mega menu enabled.
*
* @var bool
*/
protected $mega_menu_enabled = false;
/**
* @var bool $force_icons_only
*/
protected $force_icons_only = false;
/**
* Add mega menu hooks.
*/
public function add_hooks() {
add_action( 'presscore_nav_menu_start_el', array( $this, 'detect_mega_menu_action' ), 10, 3 );
add_filter( 'presscore_nav_menu_css_class', array( $this, 'mega_menu_class_filter' ), 10, 4 );
add_filter( 'presscore_nav_menu_el_before', array( $this, 'append_columns' ), 10, 4 );
add_filter( 'presscore_nav_menu_start_lvl', array( $this, 'start_row' ), 10, 2 );
add_filter( 'presscore_nav_menu_end_lvl', array( $this, 'end_row' ), 10, 2 );
add_filter( 'walker_nav_menu_start_el', array( $this, 'append_widgets' ), 10, 4 );
add_filter( 'presscore_nav_menu_item', array( $this, 'menu_item' ), 10, 6 );
}
/**
* Remove mega menu hooks.
*/
public function remove_hooks() {
remove_action( 'presscore_nav_menu_start_el', array( $this, 'detect_mega_menu_action' ) );
remove_filter( 'presscore_nav_menu_css_class', array( $this, 'mega_menu_class_filter' ) );
remove_filter( 'presscore_nav_menu_el_before', array( $this, 'append_columns' ) );
remove_filter( 'presscore_nav_menu_start_lvl', array( $this, 'start_row' ) );
remove_filter( 'presscore_nav_menu_end_lvl', array( $this, 'end_row' ) );
remove_filter( 'walker_nav_menu_start_el', array( $this, 'append_widgets' ) );
remove_filter( 'presscore_nav_menu_item', array( $this, 'menu_item' ) );
}
/**
* @param bool $icons_only Should we use only icons functionality.
*/
public function force_icons_only( $icons_only = true ) {
$this->force_icons_only = $icons_only;
}
/**
* Filter menu item. Add icon/image.
*
* @param string $menu_item Menu item code.
* @param string $title Menu item title.
* @param string $description Menu item description.
* @param WP_Post $item Menu item data object.
* @param int $depth Menu item depth.
* @param stdClass $args An object of wp_nav_menu() arguments.
*
* @return string
*/
public function menu_item( $menu_item, $title, $description, $item, $depth, $args ) {
if ( $menu_item ) {
return $menu_item;
}
$icon = $this->dt_get_item_icon( $item );
if ( isset( $item->the7_mega_menu['menu-item-image-position'], $item->the7_mega_menu['menu-item-icon-type'] ) && in_array( $item->the7_mega_menu['menu-item-icon-type'], array( 'image', 'icon' ), true ) && in_array( $item->the7_mega_menu['menu-item-image-position'], array( 'right_top', 'left_top' ), true ) ) {
$menu_item = '<span class="menu-item-text">' . $icon . '<span class="menu-text">' . $title . '</span></span>' . $description;
} else {
$menu_item = $icon . '<span class="menu-item-text"><span class="menu-text">' . $title . '</span>' . $description . '</span>';
}
return $menu_item;
}
/**
* Early mega menu setup.
*
* Find out if mega menu enabled, set second level columns, is current item clickable.
*
* @param WP_Post $item Menu item data object.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item.
*/
public function detect_mega_menu_action( $item, $args, $depth ) {
if ( 0 === $depth ) {
if ( isset( $item->the7_mega_menu['mega-menu'] ) && $item->the7_mega_menu['mega-menu'] === 'on' && ! $this->force_icons_only ) {
$this->mega_menu_enabled = true;
$this->columns = ( isset( $item->the7_mega_menu['mega-menu-columns'] ) ? (int) $item->the7_mega_menu['mega-menu-columns'] : 3 );
} else {
$this->mega_menu_enabled = false;
$this->columns = 3;
}
} elseif ( $this->is_mega_menu_enabled() ) {
// If mega menu enabled.
if ( 1 === $depth ) {
// Only items with $depth = 1 have ability to remove a link.
$item->dt_is_clickable = empty( $item->the7_mega_menu['mega-menu-remove-link'] ) || $item->the7_mega_menu['mega-menu-remove-link'] === 'off';
} else {
// Items with $depth > 1 are clickable dy default.
$item->dt_is_clickable = true;
}
if ( ! empty( $item->the7_mega_menu['mega-menu-widgets'] ) && $item->the7_mega_menu['mega-menu-widgets'] !== 'none' ) {
$item->dt_is_parent = true;
}
}
do_action('the7_mega_menu_presscore_nav_menu_start_el', $item, $args, $depth);
}
/**
* Setup menu item classes.
*
* @param array $classes Menu item classes.
* @param WP_Post $item Menu item data object.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item.
*
* @return array
*/
public function mega_menu_class_filter( $classes, $item, $args, $depth ) {
if ( $this->is_mega_menu_enabled() ) {
if ( 0 === $depth ) {
$classes[] = 'dt-mega-menu';
if ( isset( $item->the7_mega_menu['mega-menu-fullwidth'] ) && $item->the7_mega_menu['mega-menu-fullwidth'] === 'on' ) {
$classes[] = 'mega-full-width';
} else {
$classes[] = 'mega-auto-width';
}
if ( ! empty( $item->the7_mega_menu['mega-menu-columns'] ) ) {
$classes[] = 'mega-column-' . (int) $item->the7_mega_menu['mega-menu-columns'];
}
} elseif ( 1 === $depth ) {
if ( isset( $item->the7_mega_menu['mega-menu-hide-title'] ) && $item->the7_mega_menu['mega-menu-hide-title'] === 'on' ) {
$classes[] = 'hide-mega-title';
if ( ! isset( $item->the7_mega_menu['menu-item-icon-type'] ) || $item->the7_mega_menu['menu-item-icon-type'] === 'none' ) {
$classes[] = 'empty-title';
}
}
if ( isset( $item->the7_mega_menu['mega-menu-widgets'] ) && $item->the7_mega_menu['mega-menu-widgets'] !== 'none' ) {
$classes[] = 'has-widget';
}
$classes[] = 'no-link';
$classes[] = 'dt-mega-parent';
$classes[] = $this->get_column_class( $this->columns );
if ( isset( $item->the7_mega_menu['mega-menu-start-new-row'] ) && $item->the7_mega_menu['mega-menu-start-new-row'] === 'on' ) {
$classes[] = 'new-row';
}
}
if ( $item->description ) {
$classes[] = 'with-subtitle';
}
}
return $classes;
}
/**
* Append row wrap open tag to $output if mega menu enabled.
*
* @param string $output Menu item html.
* @param int $depth Depth of menu item.
*
* @return string
*/
public function start_row( $output, $depth ) {
if ( 0 === $depth && $this->is_mega_menu_enabled() ) {
$output = '<div class="dt-mega-menu-wrap">' . $output;
}
return $output;
}
/**
* Append row wrap close tag to $output if mega menu enabled.
*
* @param string $output Menu item html.
* @param int $depth Depth of menu item.
*
* @return string
*/
public function end_row( $output, $depth ) {
if ( 0 === $depth && $this->is_mega_menu_enabled() ) {
$output .= '</div>';
}
return $output;
}
/**
* Append columns HTML.
*
* @param string $before HTML that will be output before menu item.
* @param WP_Post $item Menu item data object.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item.
*
* @return string
*/
public function append_columns( $before, $item, $args, $depth ) {
if ( $this->is_mega_menu_enabled() ) {
if ( 1 === $depth && isset( $item->the7_mega_menu['mega-menu-start-new-row'] ) && $item->the7_mega_menu['mega-menu-start-new-row'] === 'on' ) {
$args->walker->end_lvl( $before, $depth, $args );
$args->walker->start_lvl( $before, $depth, $args );
} elseif ( 2 === $depth && isset( $item->the7_mega_menu['mega-menu-start-new-column'] ) && $item->the7_mega_menu['mega-menu-start-new-column'] === 'on' ) {
$fake_column_classes = array(
'menu-item',
'menu-item-has-children',
'dt-mega-parent',
'has-children',
'new-column',
);
$fake_column_classes[] = $this->get_column_class( $this->columns );
if ( isset( $item->the7_mega_menu['mega-menu-hide-title'] ) && $item->the7_mega_menu['mega-menu-hide-title'] === 'on' ) {
$fake_column_classes[] = 'hide-mega-title';
if ( ! isset( $item->the7_mega_menu['menu-item-icon-type'] ) || $item->the7_mega_menu['menu-item-icon-type'] === 'none' ) {
$classes[] = 'empty-title';
}
}
$args->walker->end_lvl( $before, $depth - 1, $args );
$args->walker->end_el( $before, $item, $depth - 1, $args );
$before .= '<li class="' . implode( ' ', array_filter( $fake_column_classes ) ) . '">';
$args->walker->start_lvl( $before, $depth - 1, $args );
}
}
return $before;
}
/**
* Append widgets based on mega menu settings.
*
* @param string $item_html Item HTML.
* @param WP_Post $item Menu item data object.
*
* @return string
*/
public function append_widgets( $item_html, $item, $depth, $args ) {
$local_html = '';
if ( ! empty( $item->the7_mega_menu['mega-menu-widgets'] ) && $item->the7_mega_menu['mega-menu-widgets'] !== 'none' && $this->is_mega_menu_enabled() ) {
$style = $this->dt_get_spacing_inline_style( $item, 'mega-menu-widgets-padding', 'padding' );
$inline_style = '';
if ( $style ) {
$inline_style = 'style="' . esc_attr( $style ) . '"';
}
ob_start();
echo '<ul ' . $inline_style . ' class="sub-nav sub-nav-widgets"><li><div class="mega-menu-widgets sidebar-content">'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
dynamic_sidebar( $item->the7_mega_menu['mega-menu-widgets'] );
echo '</div></li></ul>';
$local_html .= ob_get_clean();
}
$item_html .= apply_filters( 'the7_mega_menu_walker_nav_menu_start_el', $local_html, $item, $depth, $args);
return $item_html;
}
/**
* Return column class based on $col arg. Supports 5 columns layout maximum.
*
* @param int $col Columns.
*
* @return string
*/
protected function get_column_class( $col ) {
$columns_classes = array(
1 => 'wf-1',
2 => 'wf-1-2',
3 => 'wf-1-3',
4 => 'wf-1-4',
5 => 'wf-1-5',
);
return isset( $columns_classes[ $col ] ) ? $columns_classes[ $col ] : '';
}
/**
* Return menu item icon if any.
*
* @param WP_Post $item Page data object.
*
* @return string
*/
protected function dt_get_item_icon( $item ) {
$image_html = '';
$deprecated_mega_menu = The7_Admin_Dashboard_Settings::get( 'deprecated_mega_menu_settings' );
if ( isset( $item->the7_mega_menu['menu-item-icon-type'] ) ) {
switch ( $item->the7_mega_menu['menu-item-icon-type'] ) {
case 'html':
$image_html = $item->the7_mega_menu['menu-item-icon-html'];
break;
case 'icon':
$inline_style = '';
if ( $deprecated_mega_menu ) {
$style = $this->dt_get_icon_padding_inline_style( $item );
if ( $style ) {
$inline_style = 'style="' . esc_attr( $style ) . '"';
}
}
$image_html = '<i class="fa-fw ' . esc_attr( $item->the7_mega_menu['menu-item-icon'] ) . '" ' . $inline_style . ' ></i>';
break;
case 'image':
if ( empty( $item->the7_mega_menu['menu-item-image'][1] ) ) {
break;
}
$width = 50;
$height = 50;
$image_style = '';
if ( $deprecated_mega_menu ) {
if ( isset( $item->the7_mega_menu['menu-item-image-size'] ) ) {
$size_option_value = (array) The7_Option_Field_Spacing::decode( $item->the7_mega_menu['menu-item-image-size'] );
if ( count( $size_option_value ) === 2 ) {
list( $width, $height ) = array_map( 'absint', wp_list_pluck( $size_option_value, 'val' ) );
}
}
if ( isset( $item->the7_mega_menu['menu-item-image-border-radius'] ) ) {
$image_style .= 'border-radius: ' . $item->the7_mega_menu['menu-item-image-border-radius'] . ';';
}
$image_style .= $this->dt_get_icon_padding_inline_style( $item );
if ( $image_style ) {
$image_style = 'style="' . esc_attr( $image_style ) . '"';
}
}
$image_html = dt_get_thumb_img(
array(
'class' => 'rollover',
'img_id' => $item->the7_mega_menu['menu-item-image'][1],
'alt' => 'Menu icon',
'options' => array(
'w' => $width,
'h' => $height,
),
'wrap' => '<img %IMG_CLASS% %SRC% %ALT% %SIZE% %CUSTOM% />',
'custom' => $image_style,
'echo' => false,
)
);
break;
}
}
return $image_html;
}
/**
* Return padding inline style.
*
* @param WP_Post $item Page data object.
* @param string $prop Mega menu property.
* @param string $style_type CSS property.
*
* @return string
*/
protected function dt_get_spacing_inline_style( $item, $prop, $style_type ) {
$style = '';
if ( empty( $style_type ) ) {
$style_type = 'padding';
}
if ( isset( $item->the7_mega_menu[ $prop ] ) ) {
$padding_option_value = The7_Option_Field_Spacing::decode( $item->the7_mega_menu[ $prop ] );
if ( $padding_option_value ) {
$padding_style = '';
foreach ( $padding_option_value as $padding ) {
$padding_style .= "{$padding['val']}{$padding['units']} ";
}
$style = $style_type . ': ' . trim( $padding_style ) . ';';
}
}
return $style;
}
/**
* Return menu item padding inline style.
*
* @param WP_Post $item Page data object.
*
* @return string
*/
protected function dt_get_icon_padding_inline_style( $item ) {
return $this->dt_get_spacing_inline_style( $item, 'menu-item-image-padding', 'margin' );
}
/**
* @return bool
*/
protected function is_mega_menu_enabled() {
if ( $this->force_icons_only ) {
return false;
}
return $this->mega_menu_enabled;
}
}