271 lines
7.0 KiB
PHP
271 lines
7.0 KiB
PHP
<?php
|
|
use Elementor\Controls_Manager;
|
|
use Elementor\Group_Control_Text_Shadow;
|
|
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
|
|
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
|
|
use Elementor\Group_Control_Text_Stroke;
|
|
use Elementor\Group_Control_Typography;
|
|
|
|
use ElementorPro\Modules\LoopFilter\Traits\Hierarchical_Taxonomy_Trait;
|
|
use ElementorPro\Modules\LoopFilter\Traits\Taxonomy_Filter_Trait;
|
|
use ElementorPro\Modules\Posts\Traits\Pagination_Trait;
|
|
use Elementor\Utils;
|
|
use ElementorPro\Modules\ThemeBuilder\Module as ThemeBuilderModule;
|
|
|
|
class Elementor_Category_Nav_Tree extends \Elementor\Widget_Base {
|
|
use Hierarchical_Taxonomy_Trait;
|
|
use Taxonomy_Filter_Trait;
|
|
use Pagination_Trait;
|
|
|
|
public function get_name() {
|
|
return 'category_nav_tree';
|
|
}
|
|
|
|
public function get_title() {
|
|
return esc_html__( 'Category Nav Tree', 'elementor-addon' );
|
|
}
|
|
|
|
public function get_icon() {
|
|
return 'eicon-code';
|
|
}
|
|
|
|
public function get_categories() {
|
|
return [ 'basic' ];
|
|
}
|
|
|
|
public function get_keywords() {
|
|
return [ 'category', 'nav', 'tree', 'category nav tree' ];
|
|
}
|
|
|
|
protected function register_controls() {
|
|
$this->start_controls_section(
|
|
'section_title',
|
|
[
|
|
'label' => esc_html__( 'List', 'elementor' ),
|
|
]
|
|
);
|
|
|
|
$this->add_control(
|
|
'taxonomy',
|
|
[
|
|
'label' => esc_html__( 'Taxonomy', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SELECT,
|
|
'options' => $this->get_taxonomies_list(),
|
|
'label_block' => true,
|
|
'frontend_available' => true,
|
|
]
|
|
);
|
|
|
|
$this->add_control(
|
|
"list_dots",
|
|
[
|
|
'label' => esc_html__( 'List dots - hide', 'elementor' ),
|
|
'type' => Controls_Manager::SWITCHER,
|
|
'label_on' => esc_html__( 'On', 'elementor' ),
|
|
'label_off' => esc_html__( 'Off', 'elementor' ),
|
|
'selectors' => [
|
|
"{{WRAPPER}} ul" => 'list-style-type: none;',
|
|
],
|
|
]
|
|
);
|
|
$this->end_controls_section();
|
|
|
|
$this->start_controls_section(
|
|
'section_title_style',
|
|
[
|
|
'label' => esc_html__( 'List', 'elementor' ),
|
|
'tab' => Controls_Manager::TAB_STYLE,
|
|
]
|
|
);
|
|
|
|
$this->add_control(
|
|
'title_color',
|
|
[
|
|
'label' => esc_html__( 'Text Color', 'elementor' ),
|
|
'type' => Controls_Manager::COLOR,
|
|
'global' => [
|
|
'default' => Global_Colors::COLOR_PRIMARY,
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}} .category-nav-tree li a' => 'color: {{VALUE}};',
|
|
],
|
|
]
|
|
);
|
|
|
|
$this->add_group_control(
|
|
Group_Control_Typography::get_type(),
|
|
[
|
|
'name' => 'typography',
|
|
'global' => [
|
|
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
|
|
],
|
|
'selector' => '{{WRAPPER}} .category-nav-tree li a',
|
|
]
|
|
);
|
|
|
|
$this->add_group_control(
|
|
Group_Control_Text_Stroke::get_type(),
|
|
[
|
|
'name' => 'text_stroke',
|
|
'selector' => '{{WRAPPER}} .category-nav-tree li a',
|
|
]
|
|
);
|
|
|
|
|
|
$this->add_responsive_control(
|
|
'list_margin',
|
|
[
|
|
'label' => esc_html__( 'Margin - list', 'elementor-pro' ),
|
|
'type' => Controls_Manager::DIMENSIONS,
|
|
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
|
|
'selectors' => [
|
|
'{{WRAPPER}} .category-nav-tree' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
|
|
],
|
|
]
|
|
);
|
|
$this->add_responsive_control(
|
|
'list_padding',
|
|
[
|
|
'label' => esc_html__( 'Padding - list', 'elementor-pro' ),
|
|
'type' => Controls_Manager::DIMENSIONS,
|
|
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
|
|
'selectors' => [
|
|
'{{WRAPPER}} .category-nav-tree' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
|
|
],
|
|
]
|
|
);
|
|
|
|
|
|
|
|
$this->end_controls_section();
|
|
}
|
|
|
|
protected function get_taxonomies_list() {
|
|
$taxonomies = get_taxonomies( [], 'objects' );
|
|
|
|
$options = [ '' => esc_html__( 'Select a taxonomy', 'elementor-pro' ) ];
|
|
|
|
foreach ( $taxonomies as $taxonomy ) {
|
|
$options[ $taxonomy->name ] = $taxonomy->label;
|
|
}
|
|
|
|
return $options;
|
|
}
|
|
|
|
public function render() {
|
|
if (has_nav_menu('custom-category-menu')) {
|
|
$menu_items = wp_get_nav_menu_items(get_nav_menu_locations()['custom-category-menu']);
|
|
if ($menu_items) {
|
|
$menu_tree = $this->build_menu_tree($menu_items);
|
|
echo '<ul class="category-nav-tree">';
|
|
$this->render_menu_tree($menu_tree);
|
|
echo '</ul>';
|
|
} else {
|
|
echo '<p>' . esc_html__('No menu items found in the Custom Category Menu.', 'elementor-addon') . '</p>';
|
|
}
|
|
} else {
|
|
echo '<p>' . esc_html__('Please assign a menu to the Custom Category Menu location.', 'elementor-addon') . '</p>';
|
|
}
|
|
}
|
|
|
|
protected function build_menu_tree($menu_items) {
|
|
$tree = [];
|
|
foreach ($menu_items as $item) {
|
|
$tree[$item->menu_item_parent][] = $item;
|
|
}
|
|
return $tree;
|
|
}
|
|
|
|
|
|
protected function render_menu_tree($menu_tree, $parent_id = 0, $level = 0) {
|
|
|
|
if (!isset($menu_tree[$parent_id])) {
|
|
return false;
|
|
}
|
|
|
|
$current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
|
|
|
$has_active_child = false;
|
|
$parent_is_active = false;
|
|
|
|
foreach ($menu_tree[$parent_id] as $menu_item) {
|
|
|
|
$classes = 'lvl-' . esc_attr($level);
|
|
$a_classes = '';
|
|
$is_current = trailingslashit($menu_item->url) === trailingslashit($current_url);
|
|
|
|
if ($is_current) {
|
|
$classes .= ' active';
|
|
$parent_is_active = true;
|
|
}
|
|
|
|
$has_children = isset($menu_tree[$menu_item->ID]);
|
|
|
|
if ($has_children) {
|
|
$a_classes .= 'parent';
|
|
}
|
|
|
|
$child_active = $this->render_menu_tree_helper($menu_tree, $menu_item->ID, $level + 1);
|
|
|
|
if ($child_active) {
|
|
$classes .= ' active';
|
|
$has_active_child = true;
|
|
}
|
|
|
|
echo '<li class="' . esc_attr($classes) . '">';
|
|
echo '<span class="' . esc_attr($a_classes) . '">';
|
|
echo '<a href="' . esc_url($menu_item->url) . '" >';
|
|
echo esc_html($menu_item->title);
|
|
echo '</a>';
|
|
if ($has_children) {
|
|
echo '<span class="parent-arrow"><i aria-hidden="true" class="xlio ion-ios-arrow-down"></i></span>';
|
|
}
|
|
echo '</span>';
|
|
|
|
if (isset($menu_tree[$menu_item->ID])) {
|
|
echo '<ul class="ul-lvl-' . esc_attr($level + 1) . '">';
|
|
$this->render_menu_tree($menu_tree, $menu_item->ID, $level + 1);
|
|
echo '</ul>';
|
|
}
|
|
|
|
echo '</li>';
|
|
}
|
|
|
|
return $has_active_child || $parent_is_active;
|
|
}
|
|
|
|
protected function render_menu_tree_helper($menu_tree, $parent_id = 0, $level = 0) {
|
|
|
|
if (!isset($menu_tree[$parent_id])) {
|
|
return false;
|
|
}
|
|
|
|
$current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
|
|
|
$has_active_child = false;
|
|
$parent_is_active = false;
|
|
|
|
foreach ($menu_tree[$parent_id] as $menu_item) {
|
|
$classes = 'lvl-' . esc_attr($level);
|
|
$is_current = trailingslashit($menu_item->url) === trailingslashit($current_url);
|
|
|
|
if ($is_current) {
|
|
$classes .= ' active';
|
|
$parent_is_active = true;
|
|
}
|
|
|
|
$child_active2 = $this->render_menu_tree_helper($menu_tree, $menu_item->ID, $level + 1);
|
|
|
|
if ($child_active2) {
|
|
$classes .= ' active';
|
|
$has_active_child = true;
|
|
}
|
|
|
|
if (isset($menu_tree[$menu_item->ID])) {
|
|
$this->render_menu_tree_helper($menu_tree, $menu_item->ID, $level + 1);
|
|
}
|
|
}
|
|
|
|
return $has_active_child || $parent_is_active;
|
|
}
|
|
} |