54 * class methods. This method is called at the start of the output list. |
53 * class methods. This method is called at the start of the output list. |
55 * |
54 * |
56 * @since 2.1.0 |
55 * @since 2.1.0 |
57 * @abstract |
56 * @abstract |
58 * |
57 * |
59 * @param string $output Passed by reference. Used to append additional content. |
58 * @param string $output Used to append additional content (passed by reference). |
60 * @param int $depth Depth of the item. |
59 * @param int $depth Depth of the item. |
61 * @param array $args An array of additional arguments. |
60 * @param array $args An array of additional arguments. |
62 */ |
61 */ |
63 public function start_lvl( &$output, $depth = 0, $args = array() ) {} |
62 public function start_lvl( &$output, $depth = 0, $args = array() ) {} |
64 |
63 |
69 * class methods. This method finishes the list at the end of output of the elements. |
68 * class methods. This method finishes the list at the end of output of the elements. |
70 * |
69 * |
71 * @since 2.1.0 |
70 * @since 2.1.0 |
72 * @abstract |
71 * @abstract |
73 * |
72 * |
74 * @param string $output Passed by reference. Used to append additional content. |
73 * @param string $output Used to append additional content (passed by reference). |
75 * @param int $depth Depth of the item. |
74 * @param int $depth Depth of the item. |
76 * @param array $args An array of additional arguments. |
75 * @param array $args An array of additional arguments. |
77 */ |
76 */ |
78 public function end_lvl( &$output, $depth = 0, $args = array() ) {} |
77 public function end_lvl( &$output, $depth = 0, $args = array() ) {} |
79 |
78 |
84 * class methods. Includes the element output also. |
83 * class methods. Includes the element output also. |
85 * |
84 * |
86 * @since 2.1.0 |
85 * @since 2.1.0 |
87 * @abstract |
86 * @abstract |
88 * |
87 * |
89 * @param string $output Passed by reference. Used to append additional content. |
88 * @param string $output Used to append additional content (passed by reference). |
90 * @param object $object The data object. |
89 * @param object $object The data object. |
91 * @param int $depth Depth of the item. |
90 * @param int $depth Depth of the item. |
92 * @param array $args An array of additional arguments. |
91 * @param array $args An array of additional arguments. |
93 * @param int $current_object_id ID of the current item. |
92 * @param int $current_object_id ID of the current item. |
94 */ |
93 */ |
100 * The $args parameter holds additional values that may be used with the child class methods. |
99 * The $args parameter holds additional values that may be used with the child class methods. |
101 * |
100 * |
102 * @since 2.1.0 |
101 * @since 2.1.0 |
103 * @abstract |
102 * @abstract |
104 * |
103 * |
105 * @param string $output Passed by reference. Used to append additional content. |
104 * @param string $output Used to append additional content (passed by reference). |
106 * @param object $object The data object. |
105 * @param object $object The data object. |
107 * @param int $depth Depth of the item. |
106 * @param int $depth Depth of the item. |
108 * @param array $args An array of additional arguments. |
107 * @param array $args An array of additional arguments. |
109 */ |
108 */ |
110 public function end_el( &$output, $object, $depth = 0, $args = array() ) {} |
109 public function end_el( &$output, $object, $depth = 0, $args = array() ) {} |
120 * This method should not be called directly, use the walk() method instead. |
119 * This method should not be called directly, use the walk() method instead. |
121 * |
120 * |
122 * @since 2.5.0 |
121 * @since 2.5.0 |
123 * |
122 * |
124 * @param object $element Data object. |
123 * @param object $element Data object. |
125 * @param array $children_elements List of elements to continue traversing. |
124 * @param array $children_elements List of elements to continue traversing (passed by reference). |
126 * @param int $max_depth Max depth to traverse. |
125 * @param int $max_depth Max depth to traverse. |
127 * @param int $depth Depth of current element. |
126 * @param int $depth Depth of current element. |
128 * @param array $args An array of arguments. |
127 * @param array $args An array of arguments. |
129 * @param string $output Passed by reference. Used to append additional content. |
128 * @param string $output Used to append additional content (passed by reference). |
130 * @return null Null on failure with no changes to parameters. |
|
131 */ |
129 */ |
132 public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) { |
130 public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) { |
133 |
131 if ( ! $element ) { |
134 if ( !$element ) |
|
135 return; |
132 return; |
|
133 } |
136 |
134 |
137 $id_field = $this->db_fields['id']; |
135 $id_field = $this->db_fields['id']; |
138 $id = $element->$id_field; |
136 $id = $element->$id_field; |
139 |
137 |
140 //display this element |
138 //display this element |
141 $this->has_children = ! empty( $children_elements[ $id ] ); |
139 $this->has_children = ! empty( $children_elements[ $id ] ); |
142 if ( isset( $args[0] ) && is_array( $args[0] ) ) { |
140 if ( isset( $args[0] ) && is_array( $args[0] ) ) { |
143 $args[0]['has_children'] = $this->has_children; // Backwards compatibility. |
141 $args[0]['has_children'] = $this->has_children; // Back-compat. |
144 } |
142 } |
145 |
143 |
146 $cb_args = array_merge( array(&$output, $element, $depth), $args); |
144 $cb_args = array_merge( array(&$output, $element, $depth), $args); |
147 call_user_func_array(array($this, 'start_el'), $cb_args); |
145 call_user_func_array(array($this, 'start_el'), $cb_args); |
148 |
146 |
149 // descend only when the depth is right and there are childrens for this element |
147 // descend only when the depth is right and there are childrens for this element |
150 if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) { |
148 if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) { |
151 |
149 |
152 foreach( $children_elements[ $id ] as $child ){ |
150 foreach ( $children_elements[ $id ] as $child ){ |
153 |
151 |
154 if ( !isset($newlevel) ) { |
152 if ( !isset($newlevel) ) { |
155 $newlevel = true; |
153 $newlevel = true; |
156 //start the child delimiter |
154 //start the child delimiter |
157 $cb_args = array_merge( array(&$output, $depth), $args); |
155 $cb_args = array_merge( array(&$output, $depth), $args); |
186 * |
184 * |
187 * @param array $elements An array of elements. |
185 * @param array $elements An array of elements. |
188 * @param int $max_depth The maximum hierarchical depth. |
186 * @param int $max_depth The maximum hierarchical depth. |
189 * @return string The hierarchical item output. |
187 * @return string The hierarchical item output. |
190 */ |
188 */ |
191 public function walk( $elements, $max_depth) { |
189 public function walk( $elements, $max_depth ) { |
192 |
|
193 $args = array_slice(func_get_args(), 2); |
190 $args = array_slice(func_get_args(), 2); |
194 $output = ''; |
191 $output = ''; |
195 |
192 |
196 if ($max_depth < -1) //invalid parameter |
193 //invalid parameter or nothing to walk |
|
194 if ( $max_depth < -1 || empty( $elements ) ) { |
197 return $output; |
195 return $output; |
198 |
196 } |
199 if (empty($elements)) //nothing to walk |
|
200 return $output; |
|
201 |
197 |
202 $parent_field = $this->db_fields['parent']; |
198 $parent_field = $this->db_fields['parent']; |
203 |
199 |
204 // flat display |
200 // flat display |
205 if ( -1 == $max_depth ) { |
201 if ( -1 == $max_depth ) { |
216 * Children_elements[10][] contains all sub-elements whose parent is 10. |
212 * Children_elements[10][] contains all sub-elements whose parent is 10. |
217 */ |
213 */ |
218 $top_level_elements = array(); |
214 $top_level_elements = array(); |
219 $children_elements = array(); |
215 $children_elements = array(); |
220 foreach ( $elements as $e) { |
216 foreach ( $elements as $e) { |
221 if ( 0 == $e->$parent_field ) |
217 if ( empty( $e->$parent_field ) ) |
222 $top_level_elements[] = $e; |
218 $top_level_elements[] = $e; |
223 else |
219 else |
224 $children_elements[ $e->$parent_field ][] = $e; |
220 $children_elements[ $e->$parent_field ][] = $e; |
225 } |
221 } |
226 |
222 |
251 * then we got orphans, which should be displayed regardless. |
247 * then we got orphans, which should be displayed regardless. |
252 */ |
248 */ |
253 if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) { |
249 if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) { |
254 $empty_array = array(); |
250 $empty_array = array(); |
255 foreach ( $children_elements as $orphans ) |
251 foreach ( $children_elements as $orphans ) |
256 foreach( $orphans as $op ) |
252 foreach ( $orphans as $op ) |
257 $this->display_element( $op, $empty_array, 1, 0, $args, $output ); |
253 $this->display_element( $op, $empty_array, 1, 0, $args, $output ); |
258 } |
254 } |
259 |
255 |
260 return $output; |
256 return $output; |
261 } |
257 } |
270 * $max_depth = 0 means display all levels. |
266 * $max_depth = 0 means display all levels. |
271 * $max_depth > 0 specifies the number of display levels. |
267 * $max_depth > 0 specifies the number of display levels. |
272 * |
268 * |
273 * @since 2.7.0 |
269 * @since 2.7.0 |
274 * |
270 * |
275 * @param int $max_depth The maximum hierarchical depth. |
271 * @param array $elements |
276 * @param int $page_num The specific page number, beginning with 1. |
272 * @param int $max_depth The maximum hierarchical depth. |
277 * @return string XHTML of the specified page of elements |
273 * @param int $page_num The specific page number, beginning with 1. |
278 */ |
274 * @param int $per_page |
|
275 * @return string XHTML of the specified page of elements |
|
276 */ |
279 public function paged_walk( $elements, $max_depth, $page_num, $per_page ) { |
277 public function paged_walk( $elements, $max_depth, $page_num, $per_page ) { |
280 |
278 if ( empty( $elements ) || $max_depth < -1 ) { |
281 /* sanity check */ |
|
282 if ( empty($elements) || $max_depth < -1 ) |
|
283 return ''; |
279 return ''; |
|
280 } |
284 |
281 |
285 $args = array_slice( func_get_args(), 4 ); |
282 $args = array_slice( func_get_args(), 4 ); |
286 $output = ''; |
283 $output = ''; |
287 |
284 |
288 $parent_field = $this->db_fields['parent']; |
285 $parent_field = $this->db_fields['parent']; |
374 } |
371 } |
375 |
372 |
376 if ( $end >= $total_top && count( $children_elements ) > 0 ) { |
373 if ( $end >= $total_top && count( $children_elements ) > 0 ) { |
377 $empty_array = array(); |
374 $empty_array = array(); |
378 foreach ( $children_elements as $orphans ) |
375 foreach ( $children_elements as $orphans ) |
379 foreach( $orphans as $op ) |
376 foreach ( $orphans as $op ) |
380 $this->display_element( $op, $empty_array, 1, 0, $args, $output ); |
377 $this->display_element( $op, $empty_array, 1, 0, $args, $output ); |
381 } |
378 } |
382 |
379 |
383 return $output; |
380 return $output; |
384 } |
381 } |
385 |
382 |
|
383 /** |
|
384 * Calculates the total number of root elements. |
|
385 * |
|
386 * @since 2.7.0 |
|
387 * |
|
388 * @param array $elements Elements to list. |
|
389 * @return int Number of root elements. |
|
390 */ |
386 public function get_number_of_root_elements( $elements ){ |
391 public function get_number_of_root_elements( $elements ){ |
387 |
|
388 $num = 0; |
392 $num = 0; |
389 $parent_field = $this->db_fields['parent']; |
393 $parent_field = $this->db_fields['parent']; |
390 |
394 |
391 foreach ( $elements as $e) { |
395 foreach ( $elements as $e) { |
392 if ( 0 == $e->$parent_field ) |
396 if ( 0 == $e->$parent_field ) |
393 $num++; |
397 $num++; |
394 } |
398 } |
395 return $num; |
399 return $num; |
396 } |
400 } |
397 |
401 |
398 // Unset all the children for a given top level element. |
402 /** |
|
403 * Unset all the children for a given top level element. |
|
404 * |
|
405 * @since 2.7.0 |
|
406 * |
|
407 * @param object $e |
|
408 * @param array $children_elements |
|
409 */ |
399 public function unset_children( $e, &$children_elements ){ |
410 public function unset_children( $e, &$children_elements ){ |
400 |
411 if ( ! $e || ! $children_elements ) { |
401 if ( !$e || !$children_elements ) |
|
402 return; |
412 return; |
|
413 } |
403 |
414 |
404 $id_field = $this->db_fields['id']; |
415 $id_field = $this->db_fields['id']; |
405 $id = $e->$id_field; |
416 $id = $e->$id_field; |
406 |
417 |
407 if ( !empty($children_elements[$id]) && is_array($children_elements[$id]) ) |
418 if ( !empty($children_elements[$id]) && is_array($children_elements[$id]) ) |
408 foreach ( (array) $children_elements[$id] as $child ) |
419 foreach ( (array) $children_elements[$id] as $child ) |
409 $this->unset_children( $child, $children_elements ); |
420 $this->unset_children( $child, $children_elements ); |
410 |
421 |
411 if ( isset($children_elements[$id]) ) |
422 unset( $children_elements[ $id ] ); |
412 unset( $children_elements[$id] ); |
|
413 |
|
414 } |
423 } |
415 |
424 |
416 } // Walker |
425 } // Walker |