Changes from trunk/wp-includes/functions.php at r17435 to branches/3.0/wp-includes/functions.php at r15995
- File:
-
- 1 edited
-
branches/3.0/wp-includes/functions.php (modified) (38 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/3.0/wp-includes/functions.php
r17435 r15995 28 28 return false; 29 29 30 if ( 'G' == $dateformatstring ) 30 if ( 'G' == $dateformatstring ) { 31 31 return strtotime( $m . ' +0000' ); 32 } 32 33 33 34 $i = strtotime( $m ); … … 36 37 return $i; 37 38 38 if ( $translate )39 return date_i18n( $dateformatstring, $i );39 if ( $translate) 40 return date_i18n( $dateformatstring, $i ); 40 41 else 41 return date( $dateformatstring, $i );42 return date( $dateformatstring, $i ); 42 43 } 43 44 … … 119 120 $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 ); 120 121 } 121 $timezone_formats = array( 'P', 'I', 'O', 'T', 'Z', 'e' );122 $timezone_formats_re = implode( '|', $timezone_formats );123 if ( preg_match( "/$timezone_formats_re/", $dateformatstring ) && wp_timezone_supported() ) {124 $timezone_string = get_option( 'timezone_string' );125 if ( $timezone_string ) {126 $timezone_object = timezone_open( $timezone_string );127 $date_object = date_create( null, $timezone_object );128 foreach( $timezone_formats as $timezone_format ) {129 if ( false !== strpos( $dateformatstring, $timezone_format ) ) {130 $formatted = date_format( $date_object, $timezone_format );131 $dateformatstring = ' '.$dateformatstring;132 $dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );133 $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );134 }135 }136 }137 }138 122 $j = @$datefunc( $dateformatstring, $i ); 139 123 // allow plugins to redo this entirely for languages with untypical grammars … … 247 231 function is_serialized( $data ) { 248 232 // if it isn't a string, it isn't serialized 249 if ( ! is_string( $data ) )233 if ( !is_string( $data ) ) 250 234 return false; 251 235 $data = trim( $data ); 252 if ( 'N;' == $data )236 if ( 'N;' == $data ) 253 237 return true; 254 $length = strlen( $data ); 255 if ( $length < 4 ) 238 if ( !preg_match( '/^([adObis]):/', $data, $badions ) ) 256 239 return false; 257 if ( ':' !== $data[1] ) 258 return false; 259 $lastc = $data[$length-1]; 260 if ( ';' !== $lastc && '}' !== $lastc ) 261 return false; 262 $token = $data[0]; 263 switch ( $token ) { 264 case 's' : 265 if ( '"' !== $data[$length-2] ) 266 return false; 240 switch ( $badions[1] ) { 267 241 case 'a' : 268 242 case 'O' : 269 return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data ); 243 case 's' : 244 if ( preg_match( "/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data ) ) 245 return true; 246 break; 270 247 case 'b' : 271 248 case 'i' : 272 249 case 'd' : 273 return (bool) preg_match( "/^{$token}:[0-9.E-]+;\$/", $data ); 250 if ( preg_match( "/^{$badions[1]}:[0-9.E-]+;\$/", $data ) ) 251 return true; 252 break; 274 253 } 275 254 return false; … … 434 413 $wpdb->suppress_errors($suppress); 435 414 $alloptions = array(); 436 foreach ( (array) $alloptions_db as $o ) {415 foreach ( (array) $alloptions_db as $o ) 437 416 $alloptions[$o->option_name] = $o->option_value; 438 } 439 if ( !defined( 'WP_INSTALLING' ) || !is_multisite() ) 440 wp_cache_add( 'alloptions', $alloptions, 'options' ); 417 if ( !defined( 'WP_INSTALLING' ) || !is_multisite() ) 418 wp_cache_add( 'alloptions', $alloptions, 'options' ); 441 419 } 442 420 … … 462 440 $site_id = $wpdb->siteid; 463 441 464 $core_options = array('site_name', 'siteurl', 'active_sitewide_plugins', '_site_transient_timeout_theme_roots', '_site_transient_theme_roots', 'site_admins', ' can_compress_scripts', 'global_terms_enabled' );442 $core_options = array('site_name', 'siteurl', 'active_sitewide_plugins', '_site_transient_timeout_theme_roots', '_site_transient_theme_roots', 'site_admins', 'dashboard_blog', 'can_compress_scripts', 'global_terms_enabled' ); 465 443 466 444 $core_options_in = "'" . implode("', '", $core_options) . "'"; … … 569 547 * @subpackage Option 570 548 * @since 1.0.0 549 * @link http://alex.vort-x.net/blog/ Thanks Alex Stapleton 571 550 * 572 551 * @uses do_action() Calls 'add_option' hook before adding the option. … … 692 671 global $_wp_using_ext_object_cache; 693 672 694 do_action( 'delete_transient_' . $transient, $transient );673 do_action( 'delete_transient_' . $transient, $transient ); 695 674 696 675 if ( $_wp_using_ext_object_cache ) { … … 780 759 global $_wp_using_ext_object_cache; 781 760 782 $value = apply_filters( 'pre_set_transient_' . $transient, $value );761 $value = apply_filters( 'pre_set_transient_' . $transient, $value ); 783 762 784 763 if ( $_wp_using_ext_object_cache ) { … … 1185 1164 function do_enclose( $content, $post_ID ) { 1186 1165 global $wpdb; 1187 1188 //TODO: Tidy this ghetto code up and make the debug code optional1189 1166 include_once( ABSPATH . WPINC . '/class-IXR.php' ); 1190 1167 … … 1207 1184 foreach ( $pung as $link_test ) { 1208 1185 if ( !in_array( $link_test, $post_links_temp[0] ) ) { // link no longer in post 1209 $mid = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $link_test ). '%') );1186 $mid = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, $link_test . '%') ); 1210 1187 do_action( 'delete_postmeta', $mid ); 1211 1188 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE meta_id IN(%s)", implode( ',', $mid ) ) ); … … 1221 1198 if ( isset( $test['query'] ) ) 1222 1199 $post_links[] = $link_test; 1223 elseif ( isset($test['path']) && ( $test['path'] != '/' ) && ($test['path'] != '' ))1200 elseif ( $test['path'] != '/' && $test['path'] != '' ) 1224 1201 $post_links[] = $link_test; 1225 1202 } … … 1227 1204 1228 1205 foreach ( (array) $post_links as $url ) { 1229 if ( $url != '' && !$wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $url ). '%' ) ) ) {1206 if ( $url != '' && !$wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, $url . '%' ) ) ) { 1230 1207 1231 1208 if ( $headers = wp_get_http_headers( $url) ) { … … 1345 1322 */ 1346 1323 function is_new_day() { 1347 global $ currentday, $previousday;1348 if ( $ currentday != $previousday )1324 global $day, $previousday; 1325 if ( $day != $previousday ) 1349 1326 return 1; 1350 1327 else … … 1643 1620 * by different browsers 1644 1621 * 1645 * @since 2.8 .01622 * @since 2.8 1646 1623 * 1647 1624 * @uses apply_filters() … … 1657 1634 1658 1635 if ( function_exists('apply_filters') ) { 1659 $headers = (array)apply_filters('nocache_headers', $headers);1636 $headers = apply_filters('nocache_headers', $headers); 1660 1637 } 1661 1638 return $headers; … … 1673 1650 function nocache_headers() { 1674 1651 $headers = wp_get_nocache_headers(); 1675 foreach( $headers as $name => $field_value )1652 foreach( (array) $headers as $name => $field_value ) 1676 1653 @header("{$name}: {$field_value}"); 1677 1654 } … … 2082 2059 return true; 2083 2060 2084 if ( strlen($path) == 0 || $path [0]== '.' )2061 if ( strlen($path) == 0 || $path{0} == '.' ) 2085 2062 return false; 2086 2063 … … 2214 2191 * unique. 2215 2192 * 2216 * The callback is passed three parameters, the first one is the directory, the2217 * second is the filename, and the third is the extension.2218 * 2219 * @since 2.5 .02193 * The callback must accept two parameters, the first one is the directory and 2194 * the second is the filename. The callback must be a function. 2195 * 2196 * @since 2.5 2220 2197 * 2221 2198 * @param string $dir 2222 2199 * @param string $filename 2223 * @param mixed $unique_filename_callback Callback.2200 * @param string $unique_filename_callback Function name, must be a function. 2224 2201 * @return string New filename, if given wasn't unique. 2225 2202 */ … … 2237 2214 $name = ''; 2238 2215 2239 // Increment the file number until we have a unique file to save in $dir. Use callbackif supplied.2216 // Increment the file number until we have a unique file to save in $dir. Use $override['unique_filename_callback'] if supplied. 2240 2217 if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) { 2241 $filename = call_user_func( $unique_filename_callback, $dir, $name, $ext);2218 $filename = $unique_filename_callback( $dir, $name ); 2242 2219 } else { 2243 2220 $number = ''; … … 2597 2574 $trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' ); 2598 2575 $trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' ); 2599 $trans['upgrade']['plugin'] = array( __( 'Your attempt to up date this plugin: “%s” has failed.' ), 'use_id' );2576 $trans['upgrade']['plugin'] = array( __( 'Your attempt to upgrade this plugin: “%s” has failed.' ), 'use_id' ); 2600 2577 2601 2578 $trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false ); … … 2681 2658 */ 2682 2659 function wp_die( $message, $title = '', $args = array() ) { 2683 if ( defined( 'DOING_AJAX' ) && DOING_AJAX )2684 die('-1');2685 2686 2660 if ( function_exists( 'apply_filters' ) ) { 2687 2661 $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler'); 2688 } else {2662 }else { 2689 2663 $function = '_default_wp_die_handler'; 2690 2664 } … … 2766 2740 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2767 2741 <!-- Ticket #11289, IE bug fix: always pad the error page with enough characters such that it is greater than 512 bytes, even after gzip compression abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono --> 2768 <html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists( 'language_attributes' ) && function_exists( 'is_rtl' ) ) language_attributes(); else echo "dir='$text_direction'"; ?>>2742 <html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists( 'language_attributes' ) ) language_attributes(); ?>> 2769 2743 <head> 2770 2744 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> … … 3005 2979 3006 2980 /** 3007 * Extract a slice of an array, given a list of keys3008 *3009 * @since 3.1.03010 *3011 * @param array $array The original array3012 * @param array $keys The list of keys3013 * @return array The array slice3014 */3015 function wp_array_slice_assoc( $array, $keys ) {3016 $slice = array();3017 foreach ( $keys as $key )3018 if ( isset( $array[ $key ] ) )3019 $slice[ $key ] = $array[ $key ];3020 3021 return $slice;3022 }3023 3024 /**3025 2981 * Filters a list of objects, based on a set of key => value arguments 3026 2982 * … … 3035 2991 */ 3036 2992 function wp_filter_object_list( $list, $args = array(), $operator = 'and', $field = false ) { 3037 if ( ! is_array( $list) )2993 if ( !is_array($list) ) 3038 2994 return array(); 3039 2995 3040 $list = wp_list_filter( $list, $args, $operator ); 3041 3042 if ( $field ) 3043 $list = wp_list_pluck( $list, $field ); 3044 3045 return $list; 3046 } 3047 3048 /** 3049 * Filters a list of objects, based on a set of key => value arguments 3050 * 3051 * @since 3.1.0 3052 * 3053 * @param array $list An array of objects to filter 3054 * @param array $args An array of key => value arguments to match against each object 3055 * @param string $operator The logical operation to perform: 3056 * 'AND' means all elements from the array must match; 3057 * 'OR' means only one element needs to match; 3058 * 'NOT' means no elements may match. 3059 * The default is 'AND'. 3060 * @return array 3061 */ 3062 function wp_list_filter( $list, $args = array(), $operator = 'AND' ) { 3063 if ( ! is_array( $list ) ) 3064 return array(); 3065 3066 if ( empty( $args ) ) 3067 return $list; 3068 3069 $operator = strtoupper( $operator ); 3070 $count = count( $args ); 2996 if ( empty($args) ) 2997 $args = array(); 2998 2999 if ( empty($args) && !$field ) 3000 return $list; // nothing to do 3001 3002 $count = count($args); 3003 3071 3004 $filtered = array(); 3072 3005 3073 3006 foreach ( $list as $key => $obj ) { 3074 $matched = count( array_intersect_assoc( (array) $obj, $args ) ); 3075 if ( ( 'AND' == $operator && $matched == $count ) 3076 || ( 'OR' == $operator && $matched <= $count ) 3077 || ( 'NOT' == $operator && 0 == $matched ) ) { 3078 $filtered[$key] = $obj; 3007 $matched = count(array_intersect_assoc(get_object_vars($obj), $args)); 3008 if ( ('and' == $operator && $matched == $count) || ('or' == $operator && $matched <= $count) ) { 3009 if ( $field ) 3010 $filtered[] = $obj->$field; 3011 else 3012 $filtered[$key] = $obj; 3079 3013 } 3080 3014 } 3081 3015 3082 3016 return $filtered; 3083 }3084 3085 /**3086 * Pluck a certain field out of each object in a list3087 *3088 * @since 3.1.03089 *3090 * @param array $list A list of objects or arrays3091 * @param int|string $field A field from the object to place instead of the entire object3092 * @return array3093 */3094 function wp_list_pluck( $list, $field ) {3095 foreach ( $list as $key => $value ) {3096 $value = (array) $value;3097 $list[ $key ] = $value[ $field ];3098 }3099 3100 return $list;3101 3017 } 3102 3018 … … 3154 3070 for ($i=0; $i<$levels; $i++) 3155 3071 ob_end_flush(); 3072 } 3073 3074 /** 3075 * Load the correct database class file. 3076 * 3077 * This function is used to load the database class file either at runtime or by 3078 * wp-admin/setup-config.php We must globalise $wpdb to ensure that it is 3079 * defined globally by the inline code in wp-db.php. 3080 * 3081 * @since 2.5.0 3082 * @global $wpdb WordPress Database Object 3083 */ 3084 function require_wp_db() { 3085 global $wpdb; 3086 if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) 3087 require_once( WP_CONTENT_DIR . '/db.php' ); 3088 else 3089 require_once( ABSPATH . WPINC . '/wp-db.php' ); 3156 3090 } 3157 3091 … … 3276 3210 * function. 3277 3211 * 3278 * The current behavior is to trigger a user error if WP_DEBUG is true.3279 * 3280 * This function is to be used in every function that is deprecated.3212 * The current behavior is to trigger an user error if WP_DEBUG is true. 3213 * 3214 * This function is to be used in every function in depreceated.php 3281 3215 * 3282 3216 * @package WordPress … … 3314 3248 * file. 3315 3249 * 3316 * The current behavior is to trigger a user error if WP_DEBUG is true.3317 * 3318 * This function is to be used in every file that is deprec ated.3250 * The current behavior is to trigger an user error if WP_DEBUG is true. 3251 * 3252 * This function is to be used in every file that is depreceated 3319 3253 * 3320 3254 * @package WordPress … … 3362 3296 * argument. 3363 3297 * 3364 * The current behavior is to trigger a user error if WP_DEBUG is true.3298 * The current behavior is to trigger an user error if WP_DEBUG is true. 3365 3299 * 3366 3300 * @package WordPress … … 3388 3322 else 3389 3323 trigger_error( sprintf( __('%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.'), $function, $version ) ); 3390 }3391 }3392 3393 /**3394 * Marks something as being incorrectly called.3395 *3396 * There is a hook doing_it_wrong_run that will be called that can be used3397 * to get the backtrace up to what file and function called the deprecated3398 * function.3399 *3400 * The current behavior is to trigger a user error if WP_DEBUG is true.3401 *3402 * @package WordPress3403 * @subpackage Debug3404 * @since 3.1.03405 * @access private3406 *3407 * @uses do_action() Calls 'doing_it_wrong_run' and passes the function arguments.3408 * @uses apply_filters() Calls 'doing_it_wrong_trigger_error' and expects boolean value of true to do3409 * trigger or false to not trigger error.3410 *3411 * @param string $function The function that was called.3412 * @param string $message A message explaining what has been done incorrectly.3413 * @param string $version The version of WordPress where the message was added.3414 */3415 function _doing_it_wrong( $function, $message, $version ) {3416 3417 do_action( 'doing_it_wrong_run', $function, $message, $version );3418 3419 // Allow plugin to filter the output error trigger3420 if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true ) ) {3421 $version = is_null( $version ) ? '' : sprintf( __( '(This message was added in version %s.)' ), $version );3422 trigger_error( sprintf( __( '%1$s was called <strong>incorrectly</strong>. %2$s %3$s' ), $function, $message, $version ) );3423 3324 } 3424 3325 } … … 3467 3368 3468 3369 /** 3469 * Check if IIS 7 supports pretty permalinks3470 *3471 * @since 2.8.03472 *3473 * @return bool3474 */3475 function iis7_supports_permalinks() {3476 global $is_iis7;3477 3478 $supports_permalinks = false;3479 if ( $is_iis7 ) {3480 /* First we check if the DOMDocument class exists. If it does not exist,3481 * which is the case for PHP 4.X, then we cannot easily update the xml configuration file,3482 * hence we just bail out and tell user that pretty permalinks cannot be used.3483 * This is not a big issue because PHP 4.X is going to be depricated and for IIS it3484 * is recommended to use PHP 5.X NTS.3485 * Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the web site. When3486 * URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'.3487 * Lastly we make sure that PHP is running via FastCGI. This is important because if it runs3488 * via ISAPI then pretty permalinks will not work.3489 */3490 $supports_permalinks = class_exists('DOMDocument') && isset($_SERVER['IIS_UrlRewriteModule']) && ( php_sapi_name() == 'cgi-fcgi' );3491 }3492 3493 return apply_filters('iis7_supports_permalinks', $supports_permalinks);3494 }3495 3496 /**3497 3370 * File validates against allowed set of defined rules. 3498 3371 * … … 3600 3473 $url = preg_replace('|/wp-admin/.*|i', '', $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); 3601 3474 } 3602 return rtrim($url, '/');3475 return $url; 3603 3476 } 3604 3477 … … 3913 3786 global $_wp_using_ext_object_cache; 3914 3787 3915 $value = apply_filters( 'pre_set_site_transient_' . $transient, $value );3788 $value = apply_filters( 'pre_set_site_transient_' . $transient, $value ); 3916 3789 3917 3790 if ( $_wp_using_ext_object_cache ) { … … 4264 4137 4265 4138 /** 4266 * Retrieve metadata from a file. 4267 * 4268 * Searches for metadata in the first 8kiB of a file, such as a plugin or theme. 4269 * Each piece of metadata must be on its own line. Fields can not span multple 4270 * lines, the value will get cut at the end of the first line. 4271 * 4272 * If the file data is not within that first 8kiB, then the author should correct 4273 * their plugin file and move the data headers to the top. 4274 * 4275 * @see http://codex.wordpress.org/File_Header 4139 * Parse the file contents to retrieve its metadata. 4140 * 4141 * Searches for metadata for a file, such as a plugin or theme. Each piece of 4142 * metadata must be on its own line. For a field spanning multple lines, it 4143 * must not have any newlines or only parts of it will be displayed. 4144 * 4145 * Some users have issues with opening large files and manipulating the contents 4146 * for want is usually the first 1kiB or 2kiB. This function stops pulling in 4147 * the file contents when it has all of the required data. 4148 * 4149 * The first 8kiB of the file will be pulled in and if the file data is not 4150 * within that first 8kiB, then the author should correct their plugin file 4151 * and move the data headers to the top. 4152 * 4153 * The file is assumed to have permissions to allow for scripts to read 4154 * the file. This is not checked however and the file is only opened for 4155 * reading. 4276 4156 * 4277 4157 * @since 2.9.0 4158 * 4278 4159 * @param string $file Path to the file 4279 * @param array $default_headers List of headers, in the format array('HeaderKey' => 'Header Name')4280 * @param string $context If specified adds filter hook "extra_ {$context}_headers"4160 * @param bool $markup If the returned data should have HTML markup applied 4161 * @param string $context If specified adds filter hook "extra_<$context>_headers" 4281 4162 */ 4282 4163 function get_file_data( $file, $default_headers, $context = '' ) { … … 4291 4172 4292 4173 if ( $context != '' ) { 4293 $extra_headers = apply_filters( "extra_ {$context}_headers", array() );4174 $extra_headers = apply_filters( "extra_$context".'_headers', array() ); 4294 4175 4295 4176 $extra_headers = array_flip( $extra_headers ); … … 4297 4178 $extra_headers[$key] = $key; 4298 4179 } 4299 $all_headers = array_merge( $extra_headers, (array) $default_headers);4180 $all_headers = array_merge($extra_headers, $default_headers); 4300 4181 } else { 4301 4182 $all_headers = $default_headers; 4302 4183 } 4303 4184 4185 4304 4186 foreach ( $all_headers as $field => $regex ) { 4305 preg_match( '/ ^[ \t\/*#]*' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $file_data, ${$field});4187 preg_match( '/' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $file_data, ${$field}); 4306 4188 if ( !empty( ${$field} ) ) 4307 4189 ${$field} = _cleanup_header_comment( ${$field}[1] ); … … 4314 4196 return $file_data; 4315 4197 } 4316 4317 /** 4198 /* 4318 4199 * Used internally to tidy up the search terms 4319 4200 * … … 4417 4298 } 4418 4299 4419 /**4420 * Finds hierarchy loops using a callback function that maps object IDs to parent IDs.4421 *4422 * @since 3.1.04423 * @access private4424 *4425 * @param callback $callback function that accepts ( ID, $callback_args ) and outputs parent_ID4426 * @param int $start The ID to start the loop check at4427 * @param int $start_parent the parent_ID of $start to use instead of calling $callback( $start ). Use null to always use $callback4428 * @param array $callback_args optional additional arguments to send to $callback4429 * @return array IDs of all members of loop4430 */4431 function wp_find_hierarchy_loop( $callback, $start, $start_parent, $callback_args = array() ) {4432 $override = is_null( $start_parent ) ? array() : array( $start => $start_parent );4433 4434 if ( !$arbitrary_loop_member = wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override, $callback_args ) )4435 return array();4436 4437 return wp_find_hierarchy_loop_tortoise_hare( $callback, $arbitrary_loop_member, $override, $callback_args, true );4438 }4439 4440 /**4441 * Uses the "The Tortoise and the Hare" algorithm to detect loops.4442 *4443 * For every step of the algorithm, the hare takes two steps and the tortoise one.4444 * If the hare ever laps the tortoise, there must be a loop.4445 *4446 * @since 3.1.04447 * @access private4448 *4449 * @param callback $callback function that accupts ( ID, callback_arg, ... ) and outputs parent_ID4450 * @param int $start The ID to start the loop check at4451 * @param array $override an array of ( ID => parent_ID, ... ) to use instead of $callback4452 * @param array $callback_args optional additional arguments to send to $callback4453 * @param bool $_return_loop Return loop members or just detect presence of loop?4454 * Only set to true if you already know the given $start is part of a loop4455 * (otherwise the returned array might include branches)4456 * @return mixed scalar ID of some arbitrary member of the loop, or array of IDs of all members of loop if $_return_loop4457 */4458 function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = array(), $callback_args = array(), $_return_loop = false ) {4459 $tortoise = $hare = $evanescent_hare = $start;4460 $return = array();4461 4462 // Set evanescent_hare to one past hare4463 // Increment hare two steps4464 while (4465 $tortoise4466 &&4467 ( $evanescent_hare = isset( $override[$hare] ) ? $override[$hare] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )4468 &&4469 ( $hare = isset( $override[$evanescent_hare] ) ? $override[$evanescent_hare] : call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) )4470 ) {4471 if ( $_return_loop )4472 $return[$tortoise] = $return[$evanescent_hare] = $return[$hare] = true;4473 4474 // tortoise got lapped - must be a loop4475 if ( $tortoise == $evanescent_hare || $tortoise == $hare )4476 return $_return_loop ? $return : $tortoise;4477 4478 // Increment tortoise by one step4479 $tortoise = isset( $override[$tortoise] ) ? $override[$tortoise] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );4480 }4481 4482 return false;4483 }4484 4485 4300 ?>
Note: See TracChangeset
for help on using the changeset viewer.