PluginProbe
Filter Everything — WordPress & WooCommerce Filters / 1.5.1
Filter Everything — WordPress & WooCommerce Filters v1.5.1
1.9.7 1.9.6 1.9.5 1.9.4 1.9.3 1.9.2.2 1.9.2.1 trunk 1.2.1 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.4.1 1.4.4 1.4.5 1.4.8 1.4.9 1.5.0 1.5.1 1.6.0 1.6.1 1.6.2 All 52 releases
filter-everything / src / Walkers / WalkerCheckbox.php

WalkerCheckbox.php in Filter Everything — WordPress & WooCommerce Filters 1.5.1, at src/Walkers/WalkerCheckbox.php

278 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FilterEverything\Filter;
4
5 if ( ! defined('WPINC') ) {
6 wp_die();
7 }
8
9
10 class WalkerCheckbox extends \Walker
11 {
12 /**
13 * What the class handles.
14 *
15 * @since 2.1.0
16 * @var string
17 *
18 * @see Walker::$tree_type
19 */
20 public $tree_type = 'Checkbox';
21
22 /**
23 * Database fields to use.
24 *
25 * @since 2.1.0
26 * @var array
27 *
28 * @see Walker::$db_fields
29 * @todo Decouple this
30 */
31 public $db_fields = array(
32 'parent' => 'parent',
33 'id' => 'term_id',
34 );
35
36 public $max_depth = 0;
37
38 public $has_not_empty_children = [];
39
40 public $parent_opened_elements = [];
41
42 /**
43 * Starts the list before the elements are added.
44 *
45 * @since 2.1.0
46 *
47 * @see Walker::start_lvl()
48 *
49 * @param string $output Used to append additional content. Passed by reference.
50 * @param int $depth Optional. Depth of category. Used for tab indentation. Default 0.
51 * @param array $args Optional. An array of arguments. Will only append content if style argument
52 * value is 'list'. See wp_list_categories(). Default empty array.
53 */
54 public function start_lvl( &$output, $depth = 0, $args = array() ) {
55 $indent = str_repeat( "\t", $depth );
56 $output .= "$indent<ul class='children'>\n";
57 }
58
59 /**
60 * Ends the list of after the elements are added.
61 *
62 * @since 2.1.0
63 *
64 * @see Walker::end_lvl()
65 *
66 * @param string $output Used to append additional content. Passed by reference.
67 * @param int $depth Optional. Depth of category. Used for tab indentation. Default 0.
68 * @param array $args Optional. An array of arguments. Will only append content if style argument
69 * value is 'list'. See wp_list_categories(). Default empty array.
70 */
71 public function end_lvl( &$output, $depth = 0, $args = array() ) {
72 $indent = str_repeat( "\t", $depth );
73 $output .= "$indent</ul>\n";
74 }
75
76 /**
77 * Starts the element output.
78 *
79 * @since 2.1.0
80 *
81 * @see Walker::start_el()
82 *
83 * @param string $output Used to append additional content (passed by reference).
84 * @param WP_Term $term Term data object.
85 * @param int $depth Optional. Depth of category in reference to parents. Default 0.
86 * @param array $args Optional. An array of arguments. See wp_list_categories(). Default empty array.
87 * @param int $id Optional. ID of the current category. Default 0.
88 */
89 public function start_el( &$output, $term, $depth = 0, $args = array(), $id = 0 ) {
90
91 $term_name = esc_attr( $term->name );
92 $url_manager = $args['url_manager'];
93 $filter = $args['filter'];
94 $checked = ( in_array( $term->slug, $filter['values'] ) ) ? 1 : 0;
95 $id = $id ? $id : $term->term_id;
96 $toggleButton = '';
97 $visibility_class = '';
98
99 // Don't generate an element if the term name is empty.
100 if ( '' === $term_name ) {
101 return;
102 }
103
104 $atts = array();
105 //$set = isset( $args['set']['ID'] ) ? array( 0 => array('ID' => $args['set']['ID'] ) ) : [];
106 $atts['href'] = $url_manager->getTermUrl( $term->slug, $filter['e_name']/*, $set*/ );
107
108 $attributes = '';
109 foreach ( $atts as $attr => $value ) {
110 if ( is_scalar( $value ) && '' !== $value && false !== $value ) {
111 $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
112 $attributes .= ' ' . $attr . '="' . $value . '"';
113 }
114 }
115
116 $link = apply_filters( 'wpc_filters_checkbox_term_html', '<a'.$attributes.'>'.$term->name.'</a>', $attributes, $term, $filter );
117
118 if ( isset( $args['set']['show_count']['value'] ) && $args['set']['show_count']['value'] === 'yes' ) {
119 $link .= '&nbsp;'. flrt_get_count( $term );
120 }
121
122 $output .= "\t<li";
123 $cross_count = isset( $term->cross_count ) ? esc_attr( $term->cross_count ) : '';
124
125 $parent_opened_elements_flipped = array_flip( $this->parent_opened_elements );
126 if( isset( $parent_opened_elements_flipped[$id] ) ){
127 $visibility_class = ' wpc-opened';
128 }
129
130 if( $this->max_depth > 0) {
131 $visibility_class = ' '. flrt_get_status_css_class( $id, FLRT_HIERARCHY_LIST_COOKIE_NAME );
132 }
133
134 $css_classes = array(
135 0 => 'wpc-checkbox-item',
136 1 => 'wpc-term-item',
137 3 => 'wpc-term-count-' . $cross_count,
138 4 => 'wpc-term-id-'.$id
139 );
140
141 if( $checked ){
142 $css_classes[2] = 'wpc-term-selected';
143 }
144
145 if( $this->has_children ){
146 $css_classes[] = 'wpc-has-children';
147 $toggleButton = '<i class="wpc-toggle-children-list" data-tid="'.esc_attr($term->term_id).'"></i>';
148 }
149
150 $has_not_empty_children_flipped = array_flip( $this->has_not_empty_children );
151 // if( in_array( $id, $this->has_not_empty_children ) ){
152 if( isset( $has_not_empty_children_flipped[$id] ) ){
153 $css_classes[] = 'wpc-has-not-empty-children';
154 }
155
156 $css_classes = implode( ' ', $css_classes );
157 $css_classes .= $visibility_class;
158 $css_classes = $css_classes ? ' class="' . esc_attr( $css_classes ) . '"' : '';
159
160 $output .= $css_classes;
161 $output .= ' id="'.flrt_term_id('term', $filter, $id, false).'">';
162 $output .= '<div class="wpc-term-item-content-wrapper'.esc_attr( $visibility_class ).'"><input '.checked( 1, $checked, false ).' type="checkbox" data-wpc-link="'.esc_url($atts['href']).'"';
163 $output .= ' id="'.flrt_term_id('checkbox', $filter, $id, false).'" />'."\n";
164 $output .= '<label for="'.flrt_term_id('checkbox', $filter, $id, false).'">';
165 $output .= "$link\n";
166 $output .= "</label>\n";
167 $output .= $toggleButton;
168 $output .= "</div>\n";
169
170 }
171
172 /**
173 * Ends the element output, if needed.
174 *
175 * @since 2.1.0
176 *
177 * @see Walker::end_el()
178 *
179 * @param string $output Used to append additional content (passed by reference).
180 * @param object $page Not used.
181 * @param int $depth Optional. Depth of category. Not used.
182 * @param array $args Optional. An array of arguments. Only uses 'list' for whether should append
183 * to output. See wp_list_categories(). Default empty array.
184 */
185 public function end_el( &$output, $page, $depth = 0, $args = array() ) {
186 $output .= "</li>\n";
187 }
188
189 public function walk( $elements, $max_depth, ...$args ) {
190 $output = '';
191
192 $this->max_depth = $max_depth;
193
194 // Invalid parameter or nothing to walk.
195 if ( $max_depth < -1 || empty( $elements ) ) {
196 return $output;
197 }
198
199 $parent_field = $this->db_fields['parent'];
200
201 // Flat display.
202 if ( -1 == $max_depth ) {
203 $empty_array = array();
204 foreach ( $elements as $e ) {
205 $this->display_element( $e, $empty_array, 1, 0, $args, $output );
206 }
207 return $output;
208 }
209
210 /*
211 * Need to display in hierarchical order.
212 * Separate elements into two buckets: top level and children elements.
213 * Children_elements is two dimensional array, eg.
214 * Children_elements[10][] contains all sub-elements whose parent is 10.
215 */
216 $top_level_elements = array();
217 $children_elements = array();
218 $parent_opened_elements = array();
219
220 foreach ( $elements as $e ) {
221 if ( empty( $e->$parent_field ) ) {
222 $top_level_elements[] = $e;
223 } else {
224 $children_elements[ $e->$parent_field ][] = $e;
225 }
226
227 if( ! empty( $args[0]['filter']['values'] ) ){
228 if( in_array( $e->slug, $args[0]['filter']['values'] ) ){
229 $parent_opened_elements[] = $e->$parent_field;
230 flrt_get_all_parents( $elements, $e->$parent_field, $parent_opened_elements );
231 }
232 }
233
234 }
235
236 $this->parent_opened_elements = array_unique($parent_opened_elements);
237 $this->has_not_empty_children = flrt_get_parents_with_not_empty_children($elements);
238
239 /*
240 * When none of the elements is top level.
241 * Assume the first one must be root of the sub elements.
242 */
243 if ( empty( $top_level_elements ) ) {
244
245 $first = array_slice( $elements, 0, 1 );
246 $root = $first[0];
247
248 $top_level_elements = array();
249 $children_elements = array();
250 foreach ( $elements as $e ) {
251 if ( $root->$parent_field == $e->$parent_field ) {
252 $top_level_elements[] = $e;
253 } else {
254 $children_elements[ $e->$parent_field ][] = $e;
255 }
256 }
257 }
258
259 foreach ( $top_level_elements as $e ) {
260 $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
261 }
262
263 /*
264 * If we are displaying all levels, and remaining children_elements is not empty,
265 * then we got orphans, which should be displayed regardless.
266 */
267 if ( ( 0 == $max_depth ) && count( $children_elements ) > 0 ) {
268 $empty_array = array();
269 foreach ( $children_elements as $orphans ) {
270 foreach ( $orphans as $op ) {
271 $this->display_element( $op, $empty_array, 1, 0, $args, $output );
272 }
273 }
274 }
275
276 return $output;
277 }
278 }