'parent',
'id' => 'term_id',
);
public $max_depth = 0;
public $has_not_empty_children = [];
public $parent_opened_elements = [];
/**
* Starts the list before the elements are added.
*
* @since 2.1.0
*
* @see Walker::start_lvl()
*
* @param string $output Used to append additional content. Passed by reference.
* @param int $depth Optional. Depth of category. Used for tab indentation. Default 0.
* @param array $args Optional. An array of arguments. Will only append content if style argument
* value is 'list'. See wp_list_categories(). Default empty array.
*/
public function start_lvl( &$output, $depth = 0, $args = array() ) {
$indent = str_repeat( "\t", $depth );
$output .= "$indent
\n";
}
/**
* Ends the list of after the elements are added.
*
* @since 2.1.0
*
* @see Walker::end_lvl()
*
* @param string $output Used to append additional content. Passed by reference.
* @param int $depth Optional. Depth of category. Used for tab indentation. Default 0.
* @param array $args Optional. An array of arguments. Will only append content if style argument
* value is 'list'. See wp_list_categories(). Default empty array.
*/
public function end_lvl( &$output, $depth = 0, $args = array() ) {
$indent = str_repeat( "\t", $depth );
$output .= "$indent
\n";
}
/**
* Starts the element output.
*
* @since 2.1.0
*
* @see Walker::start_el()
*
* @param string $output Used to append additional content (passed by reference).
* @param WP_Term $term Term data object.
* @param int $depth Optional. Depth of category in reference to parents. Default 0.
* @param array $args Optional. An array of arguments. See wp_list_categories(). Default empty array.
* @param int $id Optional. ID of the current category. Default 0.
*/
public function start_el( &$output, $term, $depth = 0, $args = array(), $id = 0 ) {
$term_name = esc_attr( $term->name );
$url_manager = $args['url_manager'];
$filter = $args['filter'];
$checked = ( in_array( $term->slug, $filter['values'] ) ) ? 1 : 0;
$disabled = 0;
if( isset( $term->wp_queried ) && $term->wp_queried ){
$checked = 1;
$disabled = 1;
}
$id = $id ? $id : $term->term_id;
$toggleButton = '';
$visibility_class = '';
// Don't generate an element if the term name is empty.
if ( '' === $term_name ) {
return;
}
$atts = array();
$atts['href'] = flrt_get_filtered_term_url($term, $filter, $url_manager);
$atts['class'] = 'wpc-filter-link';
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( is_scalar( $value ) && '' !== $value && false !== $value ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
$link = apply_filters( 'wpc_filters_checkbox_term_html', ''.$term->name.'', $attributes, $term, $filter );
if ( isset( $args['set']['show_count']['value'] ) && $args['set']['show_count']['value'] === 'yes' ) {
$link .= flrt_filter_get_count( $term );
}
$is_hide_empty_terms = (isset($args['set']['hide_empty']['value']) && $args['set']['hide_empty']['value'] === 'yes');
$hide_for_apply_button_mode = flrt_check_apply_buttom_mode($args['set']);
$show_with_parent_class = '';
$isShowWithParentClass = false;
if(isset($term->show_with_parent)) {
if($term->show_with_parent === true){
$isShowWithParentClass = true;
$show_with_parent_class = 'wpc-show-with-parent-true';
}else{
$show_with_parent_class = 'wpc-show-with-parent-false';
}
}
if (!isset($term->show_with_parent)) {
if ($args['ask_to_select_parent'] !== false && $args['use_apply_button']) {
if ((!$checked)) {
$show_with_parent_class = 'wpc-show-with-parent-false';
}
}
}
$hidden_class_for_apply_button_mode = '';
$more_less_hidden_class = '';
if ($args['isMoreLess']) {
if (!empty($term->apply_button_style) && $term->apply_button_style === true) {
$more_less_hidden_class = 'wpc-not-hidden-term';
}
}
if($hide_for_apply_button_mode){
$hidden_class_for_apply_button_mode = ($term->cross_count <= 0 && $is_hide_empty_terms) ? esc_attr(' wpc-term-count-hidden-0') : '';
if($checked){
$hidden_class_for_apply_button_mode .= esc_attr('wpc-term-count-hidden-checked-0');
}
}
$output .= "\t
\n";
}
/**
* Ends the element output, if needed.
*
* @since 2.1.0
*
* @see Walker::end_el()
*
* @param string $output Used to append additional content (passed by reference).
* @param object $page Not used.
* @param int $depth Optional. Depth of category. Not used.
* @param array $args Optional. An array of arguments. Only uses 'list' for whether should append
* to output. See wp_list_categories(). Default empty array.
*/
public function end_el( &$output, $page, $depth = 0, $args = array() ) {
$output .= "
\n";
}
public function walk( $elements, $max_depth, ...$args ) {
$output = '';
$this->max_depth = $max_depth;
// Invalid parameter or nothing to walk.
if ( $max_depth < -1 || empty( $elements ) ) {
return $output;
}
$parent_field = $this->db_fields['parent'];
// Flat display.
$flrt_more_less_count = flrt_more_less_count();
$isParentFilter = flrtParentFilter($args[0]['filter']);
$hidden_terms_count = 1;
if ( -1 == $max_depth ) {
$empty_array = array();
foreach ( $elements as $e ) {
if ( $args[0]['isMoreLess'] ) {
$is_visible = !$isParentFilter || ( isset( $e->show_with_parent ) && $e->show_with_parent === true ) || !isset( $e->show_with_parent );
$has_results = !$args[0]['is_hide_empty_terms'] || $e->cross_count > 0;
if ( $is_visible && $has_results ) {
if ( $hidden_terms_count <= $flrt_more_less_count ) {
$e->apply_button_style = true;
}
$hidden_terms_count++;
}
}
$this->display_element( $e, $empty_array, 1, 0, $args, $output );
}
return $output;
}
/*
* Need to display in hierarchical order.
* Separate elements into two buckets: top level and children elements.
* Children_elements is two dimensional array, eg.
* Children_elements[10][] contains all sub-elements whose parent is 10.
*/
$top_level_elements = array();
$children_elements = array();
$parent_opened_elements = array();
foreach ( $elements as $e ) {
if ( empty( $e->$parent_field ) ) {
$top_level_elements[] = $e;
} else {
$children_elements[ $e->$parent_field ][] = $e;
}
if( ! empty( $args[0]['filter']['values'] ) ){
if( in_array( $e->slug, $args[0]['filter']['values'] ) ){
$parent_opened_elements[] = $e->$parent_field;
flrt_get_all_parents( $elements, $e->$parent_field, $parent_opened_elements );
}
}
}
$this->parent_opened_elements = array_unique($parent_opened_elements);
$this->has_not_empty_children = flrt_get_parents_with_not_empty_children($elements);
/*
* When none of the elements is top level.
* Assume the first one must be root of the sub elements.
*/
if ( empty( $top_level_elements ) ) {
$first = array_slice( $elements, 0, 1 );
$root = $first[0];
$top_level_elements = array();
$children_elements = array();
foreach ( $elements as $e ) {
if ( $root->$parent_field == $e->$parent_field ) {
$top_level_elements[] = $e;
} else {
$children_elements[ $e->$parent_field ][] = $e;
}
}
}
/*
* Same More/Less marking as in the flat branch above. Only top-level terms
* are counted: the reveal CSS (.wpc-filters-ul-list > li.wpc-not-hidden-term)
* targets direct children of the list, nested children follow their parent.
* Without this, a hierarchical More/Less list renders with all terms hidden
* until JS re-marks them.
*/
if ( $args[0]['isMoreLess'] ) {
$has_not_empty_children_flipped = array_flip( $this->has_not_empty_children );
foreach ( $top_level_elements as $e ) {
$is_visible = !$isParentFilter || ( isset( $e->show_with_parent ) && $e->show_with_parent === true ) || !isset( $e->show_with_parent );
$has_results = !$args[0]['is_hide_empty_terms'] || $e->cross_count > 0 || isset( $has_not_empty_children_flipped[ $e->term_id ] );
if ( $is_visible && $has_results ) {
if ( $hidden_terms_count <= $flrt_more_less_count ) {
$e->apply_button_style = true;
}
$hidden_terms_count++;
}
}
}
foreach ( $top_level_elements as $e ) {
$this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
}
/*
* If we are displaying all levels, and remaining children_elements is not empty,
* then we got orphans, which should be displayed regardless.
*/
if ( ( 0 == $max_depth ) && count( $children_elements ) > 0 ) {
$empty_array = array();
foreach ( $children_elements as $orphans ) {
foreach ( $orphans as $op ) {
$this->display_element( $op, $empty_array, 1, 0, $args, $output );
}
}
}
return $output;
}
}