wp_find_hierarchy_loop_tortoise_hare

Use the "The Tortoise and the Hare" algorithm to detect loops.

Description

wp_find_hierarchy_loop_tortoise_hare( (callable) $callback, (int) $start, (array) $override = array(), (array) $callback_args = array(), (bool) $_return_loop = false ); 

For every step of the algorithm, the hare takes two steps and the tortoise one. If the hare ever laps the tortoise, there must be a loop.

Parameters (5)

0. $callback (callable)
Function that accepts ( ID, callback_arg, ... ) and outputs parent_ID.
1. $start (int)
The ID to start the loop check at.
2. $override — Optional. (array) => array()
An array of ( ID => parent_ID, ... ) to use instead of $callback. Default empty array.
3. $callback_args — Optional. (array) => array()
Additional arguments to send to $callback. Default empty array.
4. $return_loop — Optional. (bool)
Return loop members or just detect presence of loop? Only set to true if you already know the given $start is part of a loop (otherwise the returned array might include branches). Default false.

Usage

  1. if ( !function_exists( 'wp_find_hierarchy_loop_tortoise_hare' ) ) { 
  2. require_once ABSPATH . WPINC . '/functions.php'; 
  3.  
  4. // Function that accepts ( ID, callback_arg, ... ) and outputs parent_ID. 
  5. $callback = null; 
  6.  
  7. // The ID to start the loop check at. 
  8. $start = -1; 
  9.  
  10. // Optional. An array of ( ID => parent_ID, ... ) to use instead of $callback. 
  11. // Default empty array. 
  12. $override = array(); 
  13.  
  14. // Optional. Additional arguments to send to $callback. Default empty array. 
  15. $callback_args = array(); 
  16. $return_loop = true; 
  17.  
  18. // NOTICE! Understand what this does before running. 
  19. $result = wp_find_hierarchy_loop_tortoise_hare($callback, $start, $override, $callback_args, $return_loop); 
  20.  

Defined (1)

The function is defined in the following location(s).

/wp-includes/functions.php  
  1. function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = array(), $callback_args = array(), $_return_loop = false ) { 
  2. $tortoise = $hare = $evanescent_hare = $start; 
  3. $return = array(); 
  4.  
  5. // Set evanescent_hare to one past hare 
  6. // Increment hare two steps 
  7. while ( 
  8. $tortoise 
  9. && 
  10. ( $evanescent_hare = isset( $override[$hare] ) ? $override[$hare] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) ) 
  11. && 
  12. ( $hare = isset( $override[$evanescent_hare] ) ? $override[$evanescent_hare] : call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) ) 
  13. ) { 
  14. if ( $_return_loop ) 
  15. $return[$tortoise] = $return[$evanescent_hare] = $return[$hare] = true; 
  16.  
  17. // tortoise got lapped - must be a loop 
  18. if ( $tortoise == $evanescent_hare || $tortoise == $hare ) 
  19. return $_return_loop ? $return : $tortoise; 
  20.  
  21. // Increment tortoise by one step 
  22. $tortoise = isset( $override[$tortoise] ) ? $override[$tortoise] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) ); 
  23.  
  24. return false;