[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * These functions can be replaced via plugins. If plugins do not redefine these 4 * functions, then these will be used instead. 5 * 6 * @package WordPress 7 */ 8 9 if ( !function_exists('wp_set_current_user') ) : 10 /** 11 * Changes the current user by ID or name. 12 * 13 * Set $id to null and specify a name if you do not know a user's ID. 14 * 15 * Some WordPress functionality is based on the current user and not based on 16 * the signed in user. Therefore, it opens the ability to edit and perform 17 * actions on users who aren't signed in. 18 * 19 * @since 2.0.3 20 * @global object $current_user The current user object which holds the user data. 21 * @uses do_action() Calls 'set_current_user' hook after setting the current user. 22 * 23 * @param int $id User ID 24 * @param string $name User's username 25 * @return WP_User Current user User object 26 */ 27 function wp_set_current_user($id, $name = '') { 28 global $current_user; 29 30 if ( isset( $current_user ) && ( $current_user instanceof WP_User ) && ( $id == $current_user->ID ) ) 31 return $current_user; 32 33 $current_user = new WP_User( $id, $name ); 34 35 setup_userdata( $current_user->ID ); 36 37 do_action('set_current_user'); 38 39 return $current_user; 40 } 41 endif; 42 43 if ( !function_exists('wp_get_current_user') ) : 44 /** 45 * Retrieve the current user object. 46 * 47 * @since 2.0.3 48 * 49 * @return WP_User Current user WP_User object 50 */ 51 function wp_get_current_user() { 52 global $current_user; 53 54 get_currentuserinfo(); 55 56 return $current_user; 57 } 58 endif; 59 60 if ( !function_exists('get_currentuserinfo') ) : 61 /** 62 * Populate global variables with information about the currently logged in user. 63 * 64 * Will set the current user, if the current user is not set. The current user 65 * will be set to the logged in person. If no user is logged in, then it will 66 * set the current user to 0, which is invalid and won't have any permissions. 67 * 68 * @since 0.71 69 * @uses $current_user Checks if the current user is set 70 * @uses wp_validate_auth_cookie() Retrieves current logged in user. 71 * 72 * @return bool|null False on XMLRPC Request and invalid auth cookie. Null when current user set 73 */ 74 function get_currentuserinfo() { 75 global $current_user; 76 77 if ( ! empty( $current_user ) ) { 78 if ( $current_user instanceof WP_User ) 79 return; 80 81 // Upgrade stdClass to WP_User 82 if ( is_object( $current_user ) && isset( $current_user->ID ) ) { 83 $cur_id = $current_user->ID; 84 $current_user = null; 85 wp_set_current_user( $cur_id ); 86 return; 87 } 88 89 // $current_user has a junk value. Force to WP_User with ID 0. 90 $current_user = null; 91 wp_set_current_user( 0 ); 92 return false; 93 } 94 95 if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) { 96 wp_set_current_user( 0 ); 97 return false; 98 } 99 100 if ( ! $user = wp_validate_auth_cookie() ) { 101 if ( is_blog_admin() || is_network_admin() || empty( $_COOKIE[LOGGED_IN_COOKIE] ) || !$user = wp_validate_auth_cookie( $_COOKIE[LOGGED_IN_COOKIE], 'logged_in' ) ) { 102 wp_set_current_user( 0 ); 103 return false; 104 } 105 } 106 107 wp_set_current_user( $user ); 108 } 109 endif; 110 111 if ( !function_exists('get_userdata') ) : 112 /** 113 * Retrieve user info by user ID. 114 * 115 * @since 0.71 116 * 117 * @param int $user_id User ID 118 * @return WP_User|bool WP_User object on success, false on failure. 119 */ 120 function get_userdata( $user_id ) { 121 return get_user_by( 'id', $user_id ); 122 } 123 endif; 124 125 if ( !function_exists('get_user_by') ) : 126 /** 127 * Retrieve user info by a given field 128 * 129 * @since 2.8.0 130 * 131 * @param string $field The field to retrieve the user with. id | slug | email | login 132 * @param int|string $value A value for $field. A user ID, slug, email address, or login name. 133 * @return WP_User|bool WP_User object on success, false on failure. 134 */ 135 function get_user_by( $field, $value ) { 136 $userdata = WP_User::get_data_by( $field, $value ); 137 138 if ( !$userdata ) 139 return false; 140 141 $user = new WP_User; 142 $user->init( $userdata ); 143 144 return $user; 145 } 146 endif; 147 148 if ( !function_exists('cache_users') ) : 149 /** 150 * Retrieve info for user lists to prevent multiple queries by get_userdata() 151 * 152 * @since 3.0.0 153 * 154 * @param array $user_ids User ID numbers list 155 */ 156 function cache_users( $user_ids ) { 157 global $wpdb; 158 159 $clean = _get_non_cached_ids( $user_ids, 'users' ); 160 161 if ( empty( $clean ) ) 162 return; 163 164 $list = implode( ',', $clean ); 165 166 $users = $wpdb->get_results( "SELECT * FROM $wpdb->users WHERE ID IN ($list)" ); 167 168 $ids = array(); 169 foreach ( $users as $user ) { 170 update_user_caches( $user ); 171 $ids[] = $user->ID; 172 } 173 update_meta_cache( 'user', $ids ); 174 } 175 endif; 176 177 if ( !function_exists( 'wp_mail' ) ) : 178 /** 179 * Send mail, similar to PHP's mail 180 * 181 * A true return value does not automatically mean that the user received the 182 * email successfully. It just only means that the method used was able to 183 * process the request without any errors. 184 * 185 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from 186 * creating a from address like 'Name <email@address.com>' when both are set. If 187 * just 'wp_mail_from' is set, then just the email address will be used with no 188 * name. 189 * 190 * The default content type is 'text/plain' which does not allow using HTML. 191 * However, you can set the content type of the email by using the 192 * 'wp_mail_content_type' filter. 193 * 194 * The default charset is based on the charset used on the blog. The charset can 195 * be set using the 'wp_mail_charset' filter. 196 * 197 * @since 1.2.1 198 * @uses apply_filters() Calls 'wp_mail' hook on an array of all of the parameters. 199 * @uses apply_filters() Calls 'wp_mail_from' hook to get the from email address. 200 * @uses apply_filters() Calls 'wp_mail_from_name' hook to get the from address name. 201 * @uses apply_filters() Calls 'wp_mail_content_type' hook to get the email content type. 202 * @uses apply_filters() Calls 'wp_mail_charset' hook to get the email charset 203 * @uses do_action_ref_array() Calls 'phpmailer_init' hook on the reference to 204 * phpmailer object. 205 * @uses PHPMailer 206 * 207 * @param string|array $to Array or comma-separated list of email addresses to send message. 208 * @param string $subject Email subject 209 * @param string $message Message contents 210 * @param string|array $headers Optional. Additional headers. 211 * @param string|array $attachments Optional. Files to attach. 212 * @return bool Whether the email contents were sent successfully. 213 */ 214 function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) { 215 // Compact the input, apply the filters, and extract them back out 216 extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) ) ); 217 218 if ( !is_array($attachments) ) 219 $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) ); 220 221 global $phpmailer; 222 223 // (Re)create it, if it's gone missing 224 if ( !is_object( $phpmailer ) || !is_a( $phpmailer, 'PHPMailer' ) ) { 225 require_once ABSPATH . WPINC . '/class-phpmailer.php'; 226 require_once ABSPATH . WPINC . '/class-smtp.php'; 227 $phpmailer = new PHPMailer( true ); 228 } 229 230 // Headers 231 if ( empty( $headers ) ) { 232 $headers = array(); 233 } else { 234 if ( !is_array( $headers ) ) { 235 // Explode the headers out, so this function can take both 236 // string headers and an array of headers. 237 $tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) ); 238 } else { 239 $tempheaders = $headers; 240 } 241 $headers = array(); 242 $cc = array(); 243 $bcc = array(); 244 245 // If it's actually got contents 246 if ( !empty( $tempheaders ) ) { 247 // Iterate through the raw headers 248 foreach ( (array) $tempheaders as $header ) { 249 if ( strpos($header, ':') === false ) { 250 if ( false !== stripos( $header, 'boundary=' ) ) { 251 $parts = preg_split('/boundary=/i', trim( $header ) ); 252 $boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) ); 253 } 254 continue; 255 } 256 // Explode them out 257 list( $name, $content ) = explode( ':', trim( $header ), 2 ); 258 259 // Cleanup crew 260 $name = trim( $name ); 261 $content = trim( $content ); 262 263 switch ( strtolower( $name ) ) { 264 // Mainly for legacy -- process a From: header if it's there 265 case 'from': 266 if ( strpos($content, '<' ) !== false ) { 267 // So... making my life hard again? 268 $from_name = substr( $content, 0, strpos( $content, '<' ) - 1 ); 269 $from_name = str_replace( '"', '', $from_name ); 270 $from_name = trim( $from_name ); 271 272 $from_email = substr( $content, strpos( $content, '<' ) + 1 ); 273 $from_email = str_replace( '>', '', $from_email ); 274 $from_email = trim( $from_email ); 275 } else { 276 $from_email = trim( $content ); 277 } 278 break; 279 case 'content-type': 280 if ( strpos( $content, ';' ) !== false ) { 281 list( $type, $charset ) = explode( ';', $content ); 282 $content_type = trim( $type ); 283 if ( false !== stripos( $charset, 'charset=' ) ) { 284 $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset ) ); 285 } elseif ( false !== stripos( $charset, 'boundary=' ) ) { 286 $boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset ) ); 287 $charset = ''; 288 } 289 } else { 290 $content_type = trim( $content ); 291 } 292 break; 293 case 'cc': 294 $cc = array_merge( (array) $cc, explode( ',', $content ) ); 295 break; 296 case 'bcc': 297 $bcc = array_merge( (array) $bcc, explode( ',', $content ) ); 298 break; 299 default: 300 // Add it to our grand headers array 301 $headers[trim( $name )] = trim( $content ); 302 break; 303 } 304 } 305 } 306 } 307 308 // Empty out the values that may be set 309 $phpmailer->ClearAllRecipients(); 310 $phpmailer->ClearAttachments(); 311 $phpmailer->ClearCustomHeaders(); 312 $phpmailer->ClearReplyTos(); 313 314 // From email and name 315 // If we don't have a name from the input headers 316 if ( !isset( $from_name ) ) 317 $from_name = 'WordPress'; 318 319 /* If we don't have an email from the input headers default to wordpress@$sitename 320 * Some hosts will block outgoing mail from this address if it doesn't exist but 321 * there's no easy alternative. Defaulting to admin_email might appear to be another 322 * option but some hosts may refuse to relay mail from an unknown domain. See 323 * http://trac.wordpress.org/ticket/5007. 324 */ 325 326 if ( !isset( $from_email ) ) { 327 // Get the site domain and get rid of www. 328 $sitename = strtolower( $_SERVER['SERVER_NAME'] ); 329 if ( substr( $sitename, 0, 4 ) == 'www.' ) { 330 $sitename = substr( $sitename, 4 ); 331 } 332 333 $from_email = 'wordpress@' . $sitename; 334 } 335 336 // Plugin authors can override the potentially troublesome default 337 $phpmailer->From = apply_filters( 'wp_mail_from' , $from_email ); 338 $phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name ); 339 340 // Set destination addresses 341 if ( !is_array( $to ) ) 342 $to = explode( ',', $to ); 343 344 foreach ( (array) $to as $recipient ) { 345 try { 346 // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>" 347 $recipient_name = ''; 348 if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { 349 if ( count( $matches ) == 3 ) { 350 $recipient_name = $matches[1]; 351 $recipient = $matches[2]; 352 } 353 } 354 $phpmailer->AddAddress( $recipient, $recipient_name); 355 } catch ( phpmailerException $e ) { 356 continue; 357 } 358 } 359 360 // Set mail's subject and body 361 $phpmailer->Subject = $subject; 362 $phpmailer->Body = $message; 363 364 // Add any CC and BCC recipients 365 if ( !empty( $cc ) ) { 366 foreach ( (array) $cc as $recipient ) { 367 try { 368 // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>" 369 $recipient_name = ''; 370 if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { 371 if ( count( $matches ) == 3 ) { 372 $recipient_name = $matches[1]; 373 $recipient = $matches[2]; 374 } 375 } 376 $phpmailer->AddCc( $recipient, $recipient_name ); 377 } catch ( phpmailerException $e ) { 378 continue; 379 } 380 } 381 } 382 383 if ( !empty( $bcc ) ) { 384 foreach ( (array) $bcc as $recipient) { 385 try { 386 // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>" 387 $recipient_name = ''; 388 if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { 389 if ( count( $matches ) == 3 ) { 390 $recipient_name = $matches[1]; 391 $recipient = $matches[2]; 392 } 393 } 394 $phpmailer->AddBcc( $recipient, $recipient_name ); 395 } catch ( phpmailerException $e ) { 396 continue; 397 } 398 } 399 } 400 401 // Set to use PHP's mail() 402 $phpmailer->IsMail(); 403 404 // Set Content-Type and charset 405 // If we don't have a content-type from the input headers 406 if ( !isset( $content_type ) ) 407 $content_type = 'text/plain'; 408 409 $content_type = apply_filters( 'wp_mail_content_type', $content_type ); 410 411 $phpmailer->ContentType = $content_type; 412 413 // Set whether it's plaintext, depending on $content_type 414 if ( 'text/html' == $content_type ) 415 $phpmailer->IsHTML( true ); 416 417 // If we don't have a charset from the input headers 418 if ( !isset( $charset ) ) 419 $charset = get_bloginfo( 'charset' ); 420 421 // Set the content-type and charset 422 $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset ); 423 424 // Set custom headers 425 if ( !empty( $headers ) ) { 426 foreach( (array) $headers as $name => $content ) { 427 $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) ); 428 } 429 430 if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) ) 431 $phpmailer->AddCustomHeader( sprintf( "Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) ); 432 } 433 434 if ( !empty( $attachments ) ) { 435 foreach ( $attachments as $attachment ) { 436 try { 437 $phpmailer->AddAttachment($attachment); 438 } catch ( phpmailerException $e ) { 439 continue; 440 } 441 } 442 } 443 444 do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) ); 445 446 // Send! 447 try { 448 return $phpmailer->Send(); 449 } catch ( phpmailerException $e ) { 450 return false; 451 } 452 } 453 endif; 454 455 if ( !function_exists('wp_authenticate') ) : 456 /** 457 * Checks a user's login information and logs them in if it checks out. 458 * 459 * @since 2.5.0 460 * 461 * @param string $username User's username 462 * @param string $password User's password 463 * @return WP_User|WP_Error WP_User object if login successful, otherwise WP_Error object. 464 */ 465 function wp_authenticate($username, $password) { 466 $username = sanitize_user($username); 467 $password = trim($password); 468 469 $user = apply_filters('authenticate', null, $username, $password); 470 471 if ( $user == null ) { 472 // TODO what should the error message be? (Or would these even happen?) 473 // Only needed if all authentication handlers fail to return anything. 474 $user = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.')); 475 } 476 477 $ignore_codes = array('empty_username', 'empty_password'); 478 479 if (is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes) ) { 480 do_action('wp_login_failed', $username); 481 } 482 483 return $user; 484 } 485 endif; 486 487 if ( !function_exists('wp_logout') ) : 488 /** 489 * Log the current user out. 490 * 491 * @since 2.5.0 492 */ 493 function wp_logout() { 494 wp_clear_auth_cookie(); 495 do_action('wp_logout'); 496 } 497 endif; 498 499 if ( !function_exists('wp_validate_auth_cookie') ) : 500 /** 501 * Validates authentication cookie. 502 * 503 * The checks include making sure that the authentication cookie is set and 504 * pulling in the contents (if $cookie is not used). 505 * 506 * Makes sure the cookie is not expired. Verifies the hash in cookie is what is 507 * should be and compares the two. 508 * 509 * @since 2.5 510 * 511 * @param string $cookie Optional. If used, will validate contents instead of cookie's 512 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in 513 * @return bool|int False if invalid cookie, User ID if valid. 514 */ 515 function wp_validate_auth_cookie($cookie = '', $scheme = '') { 516 if ( ! $cookie_elements = wp_parse_auth_cookie($cookie, $scheme) ) { 517 do_action('auth_cookie_malformed', $cookie, $scheme); 518 return false; 519 } 520 521 extract($cookie_elements, EXTR_OVERWRITE); 522 523 $expired = $expiration; 524 525 // Allow a grace period for POST and AJAX requests 526 if ( defined('DOING_AJAX') || 'POST' == $_SERVER['REQUEST_METHOD'] ) 527 $expired += HOUR_IN_SECONDS; 528 529 // Quick check to see if an honest cookie has expired 530 if ( $expired < time() ) { 531 do_action('auth_cookie_expired', $cookie_elements); 532 return false; 533 } 534 535 $user = get_user_by('login', $username); 536 if ( ! $user ) { 537 do_action('auth_cookie_bad_username', $cookie_elements); 538 return false; 539 } 540 541 $pass_frag = substr($user->user_pass, 8, 4); 542 543 $key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme); 544 $hash = hash_hmac('md5', $username . '|' . $expiration, $key); 545 546 if ( $hmac != $hash ) { 547 do_action('auth_cookie_bad_hash', $cookie_elements); 548 return false; 549 } 550 551 if ( $expiration < time() ) // AJAX/POST grace period set above 552 $GLOBALS['login_grace_period'] = 1; 553 554 do_action('auth_cookie_valid', $cookie_elements, $user); 555 556 return $user->ID; 557 } 558 endif; 559 560 if ( !function_exists('wp_generate_auth_cookie') ) : 561 /** 562 * Generate authentication cookie contents. 563 * 564 * @since 2.5 565 * @uses apply_filters() Calls 'auth_cookie' hook on $cookie contents, User ID 566 * and expiration of cookie. 567 * 568 * @param int $user_id User ID 569 * @param int $expiration Cookie expiration in seconds 570 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in 571 * @return string Authentication cookie contents 572 */ 573 function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth') { 574 $user = get_userdata($user_id); 575 576 $pass_frag = substr($user->user_pass, 8, 4); 577 578 $key = wp_hash($user->user_login . $pass_frag . '|' . $expiration, $scheme); 579 $hash = hash_hmac('md5', $user->user_login . '|' . $expiration, $key); 580 581 $cookie = $user->user_login . '|' . $expiration . '|' . $hash; 582 583 return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme); 584 } 585 endif; 586 587 if ( !function_exists('wp_parse_auth_cookie') ) : 588 /** 589 * Parse a cookie into its components 590 * 591 * @since 2.7 592 * 593 * @param string $cookie 594 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in 595 * @return array Authentication cookie components 596 */ 597 function wp_parse_auth_cookie($cookie = '', $scheme = '') { 598 if ( empty($cookie) ) { 599 switch ($scheme){ 600 case 'auth': 601 $cookie_name = AUTH_COOKIE; 602 break; 603 case 'secure_auth': 604 $cookie_name = SECURE_AUTH_COOKIE; 605 break; 606 case "logged_in": 607 $cookie_name = LOGGED_IN_COOKIE; 608 break; 609 default: 610 if ( is_ssl() ) { 611 $cookie_name = SECURE_AUTH_COOKIE; 612 $scheme = 'secure_auth'; 613 } else { 614 $cookie_name = AUTH_COOKIE; 615 $scheme = 'auth'; 616 } 617 } 618 619 if ( empty($_COOKIE[$cookie_name]) ) 620 return false; 621 $cookie = $_COOKIE[$cookie_name]; 622 } 623 624 $cookie_elements = explode('|', $cookie); 625 if ( count($cookie_elements) != 3 ) 626 return false; 627 628 list($username, $expiration, $hmac) = $cookie_elements; 629 630 return compact('username', 'expiration', 'hmac', 'scheme'); 631 } 632 endif; 633 634 if ( !function_exists('wp_set_auth_cookie') ) : 635 /** 636 * Sets the authentication cookies based User ID. 637 * 638 * The $remember parameter increases the time that the cookie will be kept. The 639 * default the cookie is kept without remembering is two days. When $remember is 640 * set, the cookies will be kept for 14 days or two weeks. 641 * 642 * @since 2.5 643 * 644 * @param int $user_id User ID 645 * @param bool $remember Whether to remember the user 646 */ 647 function wp_set_auth_cookie($user_id, $remember = false, $secure = '') { 648 if ( $remember ) { 649 $expiration = time() + apply_filters('auth_cookie_expiration', 14 * DAY_IN_SECONDS, $user_id, $remember); 650 // Ensure the browser will continue to send the cookie after the expiration time is reached. 651 // Needed for the login grace period in wp_validate_auth_cookie(). 652 $expire = $expiration + ( 12 * HOUR_IN_SECONDS ); 653 } else { 654 $expiration = time() + apply_filters('auth_cookie_expiration', 2 * DAY_IN_SECONDS, $user_id, $remember); 655 $expire = 0; 656 } 657 658 if ( '' === $secure ) 659 $secure = is_ssl(); 660 661 $secure = apply_filters('secure_auth_cookie', $secure, $user_id); 662 $secure_logged_in_cookie = apply_filters('secure_logged_in_cookie', false, $user_id, $secure); 663 664 if ( $secure ) { 665 $auth_cookie_name = SECURE_AUTH_COOKIE; 666 $scheme = 'secure_auth'; 667 } else { 668 $auth_cookie_name = AUTH_COOKIE; 669 $scheme = 'auth'; 670 } 671 672 $auth_cookie = wp_generate_auth_cookie($user_id, $expiration, $scheme); 673 $logged_in_cookie = wp_generate_auth_cookie($user_id, $expiration, 'logged_in'); 674 675 do_action('set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme); 676 do_action('set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in'); 677 678 setcookie($auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure, true); 679 setcookie($auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true); 680 setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true); 681 if ( COOKIEPATH != SITECOOKIEPATH ) 682 setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true); 683 } 684 endif; 685 686 if ( !function_exists('wp_clear_auth_cookie') ) : 687 /** 688 * Removes all of the cookies associated with authentication. 689 * 690 * @since 2.5 691 */ 692 function wp_clear_auth_cookie() { 693 do_action('clear_auth_cookie'); 694 695 setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN ); 696 setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN ); 697 setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN ); 698 setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN ); 699 setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); 700 setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); 701 702 // Old cookies 703 setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); 704 setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); 705 setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); 706 setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); 707 708 // Even older cookies 709 setcookie( USER_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); 710 setcookie( PASS_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); 711 setcookie( USER_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); 712 setcookie( PASS_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); 713 } 714 endif; 715 716 if ( !function_exists('is_user_logged_in') ) : 717 /** 718 * Checks if the current visitor is a logged in user. 719 * 720 * @since 2.0.0 721 * 722 * @return bool True if user is logged in, false if not logged in. 723 */ 724 function is_user_logged_in() { 725 $user = wp_get_current_user(); 726 727 if ( ! $user->exists() ) 728 return false; 729 730 return true; 731 } 732 endif; 733 734 if ( !function_exists('auth_redirect') ) : 735 /** 736 * Checks if a user is logged in, if not it redirects them to the login page. 737 * 738 * @since 1.5 739 */ 740 function auth_redirect() { 741 // Checks if a user is logged in, if not redirects them to the login page 742 743 $secure = ( is_ssl() || force_ssl_admin() ); 744 745 $secure = apply_filters('secure_auth_redirect', $secure); 746 747 // If https is required and request is http, redirect 748 if ( $secure && !is_ssl() && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) { 749 if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) { 750 wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) ); 751 exit(); 752 } else { 753 wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); 754 exit(); 755 } 756 } 757 758 if ( is_user_admin() ) 759 $scheme = 'logged_in'; 760 else 761 $scheme = apply_filters( 'auth_redirect_scheme', '' ); 762 763 if ( $user_id = wp_validate_auth_cookie( '', $scheme) ) { 764 do_action('auth_redirect', $user_id); 765 766 // If the user wants ssl but the session is not ssl, redirect. 767 if ( !$secure && get_user_option('use_ssl', $user_id) && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) { 768 if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) { 769 wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) ); 770 exit(); 771 } else { 772 wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); 773 exit(); 774 } 775 } 776 777 return; // The cookie is good so we're done 778 } 779 780 // The cookie is no good so force login 781 nocache_headers(); 782 783 $redirect = ( strpos( $_SERVER['REQUEST_URI'], '/options.php' ) && wp_get_referer() ) ? wp_get_referer() : set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); 784 785 $login_url = wp_login_url($redirect, true); 786 787 wp_redirect($login_url); 788 exit(); 789 } 790 endif; 791 792 if ( !function_exists('check_admin_referer') ) : 793 /** 794 * Makes sure that a user was referred from another admin page. 795 * 796 * To avoid security exploits. 797 * 798 * @since 1.2.0 799 * @uses do_action() Calls 'check_admin_referer' on $action. 800 * 801 * @param string $action Action nonce 802 * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5) 803 */ 804 function check_admin_referer($action = -1, $query_arg = '_wpnonce') { 805 if ( -1 == $action ) 806 _doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '3.2' ); 807 808 $adminurl = strtolower(admin_url()); 809 $referer = strtolower(wp_get_referer()); 810 $result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false; 811 if ( !$result && !(-1 == $action && strpos($referer, $adminurl) === 0) ) { 812 wp_nonce_ays($action); 813 die(); 814 } 815 do_action('check_admin_referer', $action, $result); 816 return $result; 817 } 818 endif; 819 820 if ( !function_exists('check_ajax_referer') ) : 821 /** 822 * Verifies the AJAX request to prevent processing requests external of the blog. 823 * 824 * @since 2.0.3 825 * 826 * @param string $action Action nonce 827 * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5) 828 */ 829 function check_ajax_referer( $action = -1, $query_arg = false, $die = true ) { 830 $nonce = ''; 831 832 if ( $query_arg && isset( $_REQUEST[ $query_arg ] ) ) 833 $nonce = $_REQUEST[ $query_arg ]; 834 elseif ( isset( $_REQUEST['_ajax_nonce'] ) ) 835 $nonce = $_REQUEST['_ajax_nonce']; 836 elseif ( isset( $_REQUEST['_wpnonce'] ) ) 837 $nonce = $_REQUEST['_wpnonce']; 838 839 $result = wp_verify_nonce( $nonce, $action ); 840 841 if ( $die && false == $result ) { 842 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) 843 wp_die( -1 ); 844 else 845 die( '-1' ); 846 } 847 848 do_action('check_ajax_referer', $action, $result); 849 850 return $result; 851 } 852 endif; 853 854 if ( !function_exists('wp_redirect') ) : 855 /** 856 * Redirects to another page. 857 * 858 * @since 1.5.1 859 * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status. 860 * 861 * @param string $location The path to redirect to. 862 * @param int $status Status code to use. 863 * @return bool False if $location is not provided, true otherwise. 864 */ 865 function wp_redirect($location, $status = 302) { 866 global $is_IIS; 867 868 /** 869 * Filter the redirect location. 870 * 871 * @since 2.1.0 872 * 873 * @param string $location The path to redirect to. 874 * @param int $status Status code to use. 875 */ 876 $location = apply_filters( 'wp_redirect', $location, $status ); 877 878 /** 879 * Filter the redirect status code. 880 * 881 * @since 2.3.0 882 * 883 * @param int $status Status code to use. 884 * @param string $location The path to redirect to. 885 */ 886 $status = apply_filters( 'wp_redirect_status', $status, $location ); 887 888 if ( ! $location ) 889 return false; 890 891 $location = wp_sanitize_redirect($location); 892 893 if ( !$is_IIS && php_sapi_name() != 'cgi-fcgi' ) 894 status_header($status); // This causes problems on IIS and some FastCGI setups 895 896 header("Location: $location", true, $status); 897 898 return true; 899 } 900 endif; 901 902 if ( !function_exists('wp_sanitize_redirect') ) : 903 /** 904 * Sanitizes a URL for use in a redirect. 905 * 906 * @since 2.3 907 * 908 * @return string redirect-sanitized URL 909 **/ 910 function wp_sanitize_redirect($location) { 911 $location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location); 912 $location = wp_kses_no_null($location); 913 914 // remove %0d and %0a from location 915 $strip = array('%0d', '%0a', '%0D', '%0A'); 916 $location = _deep_replace($strip, $location); 917 return $location; 918 } 919 endif; 920 921 if ( !function_exists('wp_safe_redirect') ) : 922 /** 923 * Performs a safe (local) redirect, using wp_redirect(). 924 * 925 * Checks whether the $location is using an allowed host, if it has an absolute 926 * path. A plugin can therefore set or remove allowed host(s) to or from the 927 * list. 928 * 929 * If the host is not allowed, then the redirect is to wp-admin on the siteurl 930 * instead. This prevents malicious redirects which redirect to another host, 931 * but only used in a few places. 932 * 933 * @since 2.3 934 * @uses wp_validate_redirect() To validate the redirect is to an allowed host. 935 * 936 * @return void Does not return anything 937 **/ 938 function wp_safe_redirect($location, $status = 302) { 939 940 // Need to look at the URL the way it will end up in wp_redirect() 941 $location = wp_sanitize_redirect($location); 942 943 $location = wp_validate_redirect($location, admin_url()); 944 945 wp_redirect($location, $status); 946 } 947 endif; 948 949 if ( !function_exists('wp_validate_redirect') ) : 950 /** 951 * Validates a URL for use in a redirect. 952 * 953 * Checks whether the $location is using an allowed host, if it has an absolute 954 * path. A plugin can therefore set or remove allowed host(s) to or from the 955 * list. 956 * 957 * If the host is not allowed, then the redirect is to $default supplied 958 * 959 * @since 2.8.1 960 * @uses apply_filters() Calls 'allowed_redirect_hosts' on an array containing 961 * WordPress host string and $location host string. 962 * 963 * @param string $location The redirect to validate 964 * @param string $default The value to return if $location is not allowed 965 * @return string redirect-sanitized URL 966 **/ 967 function wp_validate_redirect($location, $default = '') { 968 $location = trim( $location ); 969 // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//' 970 if ( substr($location, 0, 2) == '//' ) 971 $location = 'http:' . $location; 972 973 // In php 5 parse_url may fail if the URL query part contains http://, bug #38143 974 $test = ( $cut = strpos($location, '?') ) ? substr( $location, 0, $cut ) : $location; 975 976 $lp = parse_url($test); 977 978 // Give up if malformed URL 979 if ( false === $lp ) 980 return $default; 981 982 // Allow only http and https schemes. No data:, etc. 983 if ( isset($lp['scheme']) && !('http' == $lp['scheme'] || 'https' == $lp['scheme']) ) 984 return $default; 985 986 // Reject if scheme is set but host is not. This catches urls like https:host.com for which parse_url does not set the host field. 987 if ( isset($lp['scheme']) && !isset($lp['host']) ) 988 return $default; 989 990 $wpp = parse_url(home_url()); 991 992 $allowed_hosts = (array) apply_filters('allowed_redirect_hosts', array($wpp['host']), isset($lp['host']) ? $lp['host'] : ''); 993 994 if ( isset($lp['host']) && ( !in_array($lp['host'], $allowed_hosts) && $lp['host'] != strtolower($wpp['host'])) ) 995 $location = $default; 996 997 return $location; 998 } 999 endif; 1000 1001 if ( ! function_exists('wp_notify_postauthor') ) : 1002 /** 1003 * Notify an author (and/or others) of a comment/trackback/pingback on a post. 1004 * 1005 * @since 1.0.0 1006 * 1007 * @param int $comment_id Comment ID 1008 * @param string $deprecated Not used 1009 * @return bool True on completion. False if no email addresses were specified. 1010 */ 1011 function wp_notify_postauthor( $comment_id, $deprecated = null ) { 1012 if ( null !== $deprecated ) { 1013 _deprecated_argument( __FUNCTION__, '3.8' ); 1014 } 1015 1016 $comment = get_comment( $comment_id ); 1017 if ( empty( $comment ) ) 1018 return false; 1019 1020 $post = get_post( $comment->comment_post_ID ); 1021 $author = get_userdata( $post->post_author ); 1022 1023 // Who to notify? By default, just the post author, but others can be added. 1024 $emails = array( $author->user_email ); 1025 1026 /** 1027 * Filter the list of emails to receive a comment notification. 1028 * 1029 * Normally just post authors are notified of emails. 1030 * This filter lets you add others. 1031 * 1032 * @since 3.7.0 1033 * 1034 * @param array $emails Array of email addresses to receive a comment notification. 1035 * @param int $comment_id The comment ID. 1036 */ 1037 $emails = apply_filters( 'comment_notification_recipients', $emails, $comment_id ); 1038 $emails = array_filter( $emails ); 1039 1040 // If there are no addresses to send the comment to, bail. 1041 if ( ! count( $emails ) ) { 1042 return false; 1043 } 1044 1045 // Facilitate unsetting below without knowing the keys. 1046 $emails = array_flip( $emails ); 1047 1048 /** 1049 * Filter whether to notify comment authors of their comments on their own posts. 1050 * 1051 * By default, comment authors don't get notified of their comments 1052 * on their own post. This lets you override that. 1053 * 1054 * @since 3.8.0 1055 * 1056 * @param bool $notify Whether to notify the post author of their own comment. Default false. 1057 * @param int $comment_id The comment ID. 1058 */ 1059 $notify_author = apply_filters( 'comment_notification_notify_author', false, $comment_id ); 1060 1061 // The comment was left by the author 1062 if ( ! $notify_author && $comment->user_id == $post->post_author ) { 1063 unset( $emails[ $author->user_email ] ); 1064 } 1065 1066 // The author moderated a comment on their own post 1067 if ( ! $notify_author && $post->post_author == get_current_user_id() ) { 1068 unset( $emails[ $author->user_email ] ); 1069 } 1070 1071 // The post author is no longer a member of the blog 1072 if ( ! $notify_author && ! user_can( $post->post_author, 'read_post', $post->ID ) ) { 1073 unset( $emails[ $author->user_email ] ); 1074 } 1075 1076 // If there's no email to send the comment to, bail, otherwise flip array back around for use below 1077 if ( ! count( $emails ) ) { 1078 return false; 1079 } else { 1080 $emails = array_flip( $emails ); 1081 } 1082 1083 $comment_author_domain = @gethostbyaddr($comment->comment_author_IP); 1084 1085 // The blogname option is escaped with esc_html on the way into the database in sanitize_option 1086 // we want to reverse this for the plain text arena of emails. 1087 $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); 1088 1089 switch ( $comment->comment_type ) { 1090 case 'trackback': 1091 $notify_message = sprintf( __( 'New trackback on your post "%s"' ), $post->post_title ) . "\r\n"; 1092 /* translators: 1: website name, 2: author IP, 3: author domain */ 1093 $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; 1094 $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; 1095 $notify_message .= __('Excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; 1096 $notify_message .= __('You can see all trackbacks on this post here: ') . "\r\n"; 1097 /* translators: 1: blog name, 2: post title */ 1098 $subject = sprintf( __('[%1$s] Trackback: "%2$s"'), $blogname, $post->post_title ); 1099 break; 1100 case 'pingback': 1101 $notify_message = sprintf( __( 'New pingback on your post "%s"' ), $post->post_title ) . "\r\n"; 1102 /* translators: 1: comment author, 2: author IP, 3: author domain */ 1103 $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; 1104 $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; 1105 $notify_message .= __('Excerpt: ') . "\r\n" . sprintf('[...] %s [...]', $comment->comment_content ) . "\r\n\r\n"; 1106 $notify_message .= __('You can see all pingbacks on this post here: ') . "\r\n"; 1107 /* translators: 1: blog name, 2: post title */ 1108 $subject = sprintf( __('[%1$s] Pingback: "%2$s"'), $blogname, $post->post_title ); 1109 break; 1110 default: // Comments 1111 $notify_message = sprintf( __( 'New comment on your post "%s"' ), $post->post_title ) . "\r\n"; 1112 /* translators: 1: comment author, 2: author IP, 3: author domain */ 1113 $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; 1114 $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n"; 1115 $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; 1116 $notify_message .= sprintf( __('Whois : http://whois.arin.net/rest/ip/%s'), $comment->comment_author_IP ) . "\r\n"; 1117 $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; 1118 $notify_message .= __('You can see all comments on this post here: ') . "\r\n"; 1119 /* translators: 1: blog name, 2: post title */ 1120 $subject = sprintf( __('[%1$s] Comment: "%2$s"'), $blogname, $post->post_title ); 1121 break; 1122 } 1123 $notify_message .= get_permalink($comment->comment_post_ID) . "#comments\r\n\r\n"; 1124 $notify_message .= sprintf( __('Permalink: %s'), get_permalink( $comment->comment_post_ID ) . '#comment-' . $comment_id ) . "\r\n"; 1125 1126 if ( user_can( $post->post_author, 'edit_comment', $comment_id ) ) { 1127 if ( EMPTY_TRASH_DAYS ) 1128 $notify_message .= sprintf( __('Trash it: %s'), admin_url("comment.php?action=trash&c=$comment_id") ) . "\r\n"; 1129 else 1130 $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=delete&c=$comment_id") ) . "\r\n"; 1131 $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=spam&c=$comment_id") ) . "\r\n"; 1132 } 1133 1134 $wp_email = 'wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])); 1135 1136 if ( '' == $comment->comment_author ) { 1137 $from = "From: \"$blogname\" <$wp_email>"; 1138 if ( '' != $comment->comment_author_email ) 1139 $reply_to = "Reply-To: $comment->comment_author_email"; 1140 } else { 1141 $from = "From: \"$comment->comment_author\" <$wp_email>"; 1142 if ( '' != $comment->comment_author_email ) 1143 $reply_to = "Reply-To: \"$comment->comment_author_email\" <$comment->comment_author_email>"; 1144 } 1145 1146 $message_headers = "$from\n" 1147 . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; 1148 1149 if ( isset($reply_to) ) 1150 $message_headers .= $reply_to . "\n"; 1151 1152 $notify_message = apply_filters( 'comment_notification_text', $notify_message, $comment_id ); 1153 $subject = apply_filters( 'comment_notification_subject', $subject, $comment_id ); 1154 $message_headers = apply_filters( 'comment_notification_headers', $message_headers, $comment_id ); 1155 1156 foreach ( $emails as $email ) { 1157 @wp_mail( $email, $subject, $notify_message, $message_headers ); 1158 } 1159 1160 return true; 1161 } 1162 endif; 1163 1164 if ( !function_exists('wp_notify_moderator') ) : 1165 /** 1166 * Notifies the moderator of the blog about a new comment that is awaiting approval. 1167 * 1168 * @since 1.0 1169 * @uses $wpdb 1170 * 1171 * @param int $comment_id Comment ID 1172 * @return bool Always returns true 1173 */ 1174 function wp_notify_moderator($comment_id) { 1175 global $wpdb; 1176 1177 if ( 0 == get_option( 'moderation_notify' ) ) 1178 return true; 1179 1180 $comment = get_comment($comment_id); 1181 $post = get_post($comment->comment_post_ID); 1182 $user = get_userdata( $post->post_author ); 1183 // Send to the administration and to the post author if the author can modify the comment. 1184 $emails = array( get_option( 'admin_email' ) ); 1185 if ( user_can( $user->ID, 'edit_comment', $comment_id ) && ! empty( $user->user_email ) ) { 1186 if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) 1187 $emails[] = $user->user_email; 1188 } 1189 1190 $comment_author_domain = @gethostbyaddr($comment->comment_author_IP); 1191 $comments_waiting = $wpdb->get_var("SELECT count(comment_ID) FROM $wpdb->comments WHERE comment_approved = '0'"); 1192 1193 // The blogname option is escaped with esc_html on the way into the database in sanitize_option 1194 // we want to reverse this for the plain text arena of emails. 1195 $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); 1196 1197 switch ( $comment->comment_type ) { 1198 case 'trackback': 1199 $notify_message = sprintf( __('A new trackback on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; 1200 $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; 1201 $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; 1202 $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; 1203 $notify_message .= __('Trackback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; 1204 break; 1205 case 'pingback': 1206 $notify_message = sprintf( __('A new pingback on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; 1207 $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; 1208 $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; 1209 $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; 1210 $notify_message .= __('Pingback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; 1211 break; 1212 default: // Comments 1213 $notify_message = sprintf( __('A new comment on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; 1214 $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; 1215 $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; 1216 $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n"; 1217 $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; 1218 $notify_message .= sprintf( __('Whois : http://whois.arin.net/rest/ip/%s'), $comment->comment_author_IP ) . "\r\n"; 1219 $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; 1220 break; 1221 } 1222 1223 $notify_message .= sprintf( __('Approve it: %s'), admin_url("comment.php?action=approve&c=$comment_id") ) . "\r\n"; 1224 if ( EMPTY_TRASH_DAYS ) 1225 $notify_message .= sprintf( __('Trash it: %s'), admin_url("comment.php?action=trash&c=$comment_id") ) . "\r\n"; 1226 else 1227 $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=delete&c=$comment_id") ) . "\r\n"; 1228 $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=spam&c=$comment_id") ) . "\r\n"; 1229 1230 $notify_message .= sprintf( _n('Currently %s comment is waiting for approval. Please visit the moderation panel:', 1231 'Currently %s comments are waiting for approval. Please visit the moderation panel:', $comments_waiting), number_format_i18n($comments_waiting) ) . "\r\n"; 1232 $notify_message .= admin_url("edit-comments.php?comment_status=moderated") . "\r\n"; 1233 1234 $subject = sprintf( __('[%1$s] Please moderate: "%2$s"'), $blogname, $post->post_title ); 1235 $message_headers = ''; 1236 1237 $emails = apply_filters( 'comment_moderation_recipients', $emails, $comment_id ); 1238 $notify_message = apply_filters( 'comment_moderation_text', $notify_message, $comment_id ); 1239 $subject = apply_filters( 'comment_moderation_subject', $subject, $comment_id ); 1240 $message_headers = apply_filters( 'comment_moderation_headers', $message_headers, $comment_id ); 1241 1242 foreach ( $emails as $email ) { 1243 @wp_mail( $email, $subject, $notify_message, $message_headers ); 1244 } 1245 1246 return true; 1247 } 1248 endif; 1249 1250 if ( !function_exists('wp_password_change_notification') ) : 1251 /** 1252 * Notify the blog admin of a user changing password, normally via email. 1253 * 1254 * @since 2.7 1255 * 1256 * @param object $user User Object 1257 */ 1258 function wp_password_change_notification(&$user) { 1259 // send a copy of password change notification to the admin 1260 // but check to see if it's the admin whose password we're changing, and skip this 1261 if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) { 1262 $message = sprintf(__('Password Lost and Changed for user: %s'), $user->user_login) . "\r\n"; 1263 // The blogname option is escaped with esc_html on the way into the database in sanitize_option 1264 // we want to reverse this for the plain text arena of emails. 1265 $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); 1266 wp_mail(get_option('admin_email'), sprintf(__('[%s] Password Lost/Changed'), $blogname), $message); 1267 } 1268 } 1269 endif; 1270 1271 if ( !function_exists('wp_new_user_notification') ) : 1272 /** 1273 * Notify the blog admin of a new user, normally via email. 1274 * 1275 * @since 2.0 1276 * 1277 * @param int $user_id User ID 1278 * @param string $plaintext_pass Optional. The user's plaintext password 1279 */ 1280 function wp_new_user_notification($user_id, $plaintext_pass = '') { 1281 $user = get_userdata( $user_id ); 1282 1283 // The blogname option is escaped with esc_html on the way into the database in sanitize_option 1284 // we want to reverse this for the plain text arena of emails. 1285 $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); 1286 1287 $message = sprintf(__('New user registration on your site %s:'), $blogname) . "\r\n\r\n"; 1288 $message .= sprintf(__('Username: %s'), $user->user_login) . "\r\n\r\n"; 1289 $message .= sprintf(__('E-mail: %s'), $user->user_email) . "\r\n"; 1290 1291 @wp_mail(get_option('admin_email'), sprintf(__('[%s] New User Registration'), $blogname), $message); 1292 1293 if ( empty($plaintext_pass) ) 1294 return; 1295 1296 $message = sprintf(__('Username: %s'), $user->user_login) . "\r\n"; 1297 $message .= sprintf(__('Password: %s'), $plaintext_pass) . "\r\n"; 1298 $message .= wp_login_url() . "\r\n"; 1299 1300 wp_mail($user->user_email, sprintf(__('[%s] Your username and password'), $blogname), $message); 1301 1302 } 1303 endif; 1304 1305 if ( !function_exists('wp_nonce_tick') ) : 1306 /** 1307 * Get the time-dependent variable for nonce creation. 1308 * 1309 * A nonce has a lifespan of two ticks. Nonces in their second tick may be 1310 * updated, e.g. by autosave. 1311 * 1312 * @since 2.5 1313 * 1314 * @return int 1315 */ 1316 function wp_nonce_tick() { 1317 $nonce_life = apply_filters( 'nonce_life', DAY_IN_SECONDS ); 1318 1319 return ceil(time() / ( $nonce_life / 2 )); 1320 } 1321 endif; 1322 1323 if ( !function_exists('wp_verify_nonce') ) : 1324 /** 1325 * Verify that correct nonce was used with time limit. 1326 * 1327 * The user is given an amount of time to use the token, so therefore, since the 1328 * UID and $action remain the same, the independent variable is the time. 1329 * 1330 * @since 2.0.3 1331 * 1332 * @param string $nonce Nonce that was used in the form to verify 1333 * @param string|int $action Should give context to what is taking place and be the same when nonce was created. 1334 * @return bool Whether the nonce check passed or failed. 1335 */ 1336 function wp_verify_nonce($nonce, $action = -1) { 1337 $user = wp_get_current_user(); 1338 $uid = (int) $user->ID; 1339 if ( ! $uid ) 1340 $uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); 1341 1342 $i = wp_nonce_tick(); 1343 1344 // Nonce generated 0-12 hours ago 1345 if ( substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10) === $nonce ) 1346 return 1; 1347 // Nonce generated 12-24 hours ago 1348 if ( substr(wp_hash(($i - 1) . $action . $uid, 'nonce'), -12, 10) === $nonce ) 1349 return 2; 1350 // Invalid nonce 1351 return false; 1352 } 1353 endif; 1354 1355 if ( !function_exists('wp_create_nonce') ) : 1356 /** 1357 * Creates a random, one time use token. 1358 * 1359 * @since 2.0.3 1360 * 1361 * @param string|int $action Scalar value to add context to the nonce. 1362 * @return string The one use form token 1363 */ 1364 function wp_create_nonce($action = -1) { 1365 $user = wp_get_current_user(); 1366 $uid = (int) $user->ID; 1367 if ( ! $uid ) 1368 $uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); 1369 1370 $i = wp_nonce_tick(); 1371 1372 return substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10); 1373 } 1374 endif; 1375 1376 if ( !function_exists('wp_salt') ) : 1377 /** 1378 * Get salt to add to hashes. 1379 * 1380 * Salts are created using secret keys. Secret keys are located in two places: 1381 * in the database and in the wp-config.php file. The secret key in the database 1382 * is randomly generated and will be appended to the secret keys in wp-config.php. 1383 * 1384 * The secret keys in wp-config.php should be updated to strong, random keys to maximize 1385 * security. Below is an example of how the secret key constants are defined. 1386 * Do not paste this example directly into wp-config.php. Instead, have a 1387 * {@link https://api.wordpress.org/secret-key/1.1/salt/ secret key created} just 1388 * for you. 1389 * 1390 * <code> 1391 * define('AUTH_KEY', ' Xakm<o xQy rw4EMsLKM-?!T+,PFF})H4lzcW57AF0U@N@< >M%G4Yt>f`z]MON'); 1392 * define('SECURE_AUTH_KEY', 'LzJ}op]mr|6+![P}Ak:uNdJCJZd>(Hx.-Mh#Tz)pCIU#uGEnfFz|f ;;eU%/U^O~'); 1393 * define('LOGGED_IN_KEY', '|i|Ux`9<p-h$aFf(qnT:sDO:D1P^wZ$$/Ra@miTJi9G;ddp_<q}6H1)o|a +&JCM'); 1394 * define('NONCE_KEY', '%:R{[P|,s.KuMltH5}cI;/k<Gx~j!f0I)m_sIyu+&NJZ)-iO>z7X>QYR0Z_XnZ@|'); 1395 * define('AUTH_SALT', 'eZyT)-Naw]F8CwA*VaW#q*|.)g@o}||wf~@C-YSt}(dh_r6EbI#A,y|nU2{B#JBW'); 1396 * define('SECURE_AUTH_SALT', '!=oLUTXh,QW=H `}`L|9/^4-3 STz},T(w}W<I`.JjPi)<Bmf1v,HpGe}T1:Xt7n'); 1397 * define('LOGGED_IN_SALT', '+XSqHc;@Q*K_b|Z?NC[3H!!EONbh.n<+=uKR:>*c(u`g~EJBf#8u#R{mUEZrozmm'); 1398 * define('NONCE_SALT', 'h`GXHhD>SLWVfg1(1(N{;.V!MoE(SfbA_ksP@&`+AycHcAV$+?@3q+rxV{%^VyKT'); 1399 * </code> 1400 * 1401 * Salting passwords helps against tools which has stored hashed values of 1402 * common dictionary strings. The added values makes it harder to crack. 1403 * 1404 * @since 2.5 1405 * 1406 * @link https://api.wordpress.org/secret-key/1.1/salt/ Create secrets for wp-config.php 1407 * 1408 * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce) 1409 * @return string Salt value 1410 */ 1411 function wp_salt( $scheme = 'auth' ) { 1412 static $cached_salts = array(); 1413 if ( isset( $cached_salts[ $scheme ] ) ) 1414 return apply_filters( 'salt', $cached_salts[ $scheme ], $scheme ); 1415 1416 static $duplicated_keys; 1417 if ( null === $duplicated_keys ) { 1418 $duplicated_keys = array( 'put your unique phrase here' => true ); 1419 foreach ( array( 'AUTH', 'SECURE_AUTH', 'LOGGED_IN', 'NONCE', 'SECRET' ) as $first ) { 1420 foreach ( array( 'KEY', 'SALT' ) as $second ) { 1421 if ( ! defined( "{$first}_{$second}" ) ) 1422 continue; 1423 $value = constant( "{$first}_{$second}" ); 1424 $duplicated_keys[ $value ] = isset( $duplicated_keys[ $value ] ); 1425 } 1426 } 1427 } 1428 1429 $key = $salt = ''; 1430 if ( defined( 'SECRET_KEY' ) && SECRET_KEY && empty( $duplicated_keys[ SECRET_KEY ] ) ) 1431 $key = SECRET_KEY; 1432 if ( 'auth' == $scheme && defined( 'SECRET_SALT' ) && SECRET_SALT && empty( $duplicated_keys[ SECRET_SALT ] ) ) 1433 $salt = SECRET_SALT; 1434 1435 if ( in_array( $scheme, array( 'auth', 'secure_auth', 'logged_in', 'nonce' ) ) ) { 1436 foreach ( array( 'key', 'salt' ) as $type ) { 1437 $const = strtoupper( "{$scheme}_{$type}" ); 1438 if ( defined( $const ) && constant( $const ) && empty( $duplicated_keys[ constant( $const ) ] ) ) { 1439 $$type = constant( $const ); 1440 } elseif ( ! $$type ) { 1441 $$type = get_site_option( "{$scheme}_{$type}" ); 1442 if ( ! $$type ) { 1443 $$type = wp_generate_password( 64, true, true ); 1444 update_site_option( "{$scheme}_{$type}", $$type ); 1445 } 1446 } 1447 } 1448 } else { 1449 if ( ! $key ) { 1450 $key = get_site_option( 'secret_key' ); 1451 if ( ! $key ) { 1452 $key = wp_generate_password( 64, true, true ); 1453 update_site_option( 'secret_key', $key ); 1454 } 1455 } 1456 $salt = hash_hmac( 'md5', $scheme, $key ); 1457 } 1458 1459 $cached_salts[ $scheme ] = $key . $salt; 1460 return apply_filters( 'salt', $cached_salts[ $scheme ], $scheme ); 1461 } 1462 endif; 1463 1464 if ( !function_exists('wp_hash') ) : 1465 /** 1466 * Get hash of given string. 1467 * 1468 * @since 2.0.3 1469 * @uses wp_salt() Get WordPress salt 1470 * 1471 * @param string $data Plain text to hash 1472 * @return string Hash of $data 1473 */ 1474 function wp_hash($data, $scheme = 'auth') { 1475 $salt = wp_salt($scheme); 1476 1477 return hash_hmac('md5', $data, $salt); 1478 } 1479 endif; 1480 1481 if ( !function_exists('wp_hash_password') ) : 1482 /** 1483 * Create a hash (encrypt) of a plain text password. 1484 * 1485 * For integration with other applications, this function can be overwritten to 1486 * instead use the other package password checking algorithm. 1487 * 1488 * @since 2.5 1489 * @global object $wp_hasher PHPass object 1490 * @uses PasswordHash::HashPassword 1491 * 1492 * @param string $password Plain text user password to hash 1493 * @return string The hash string of the password 1494 */ 1495 function wp_hash_password($password) { 1496 global $wp_hasher; 1497 1498 if ( empty($wp_hasher) ) { 1499 require_once ( ABSPATH . 'wp-includes/class-phpass.php'); 1500 // By default, use the portable hash from phpass 1501 $wp_hasher = new PasswordHash(8, true); 1502 } 1503 1504 return $wp_hasher->HashPassword( trim( $password ) ); 1505 } 1506 endif; 1507 1508 if ( !function_exists('wp_check_password') ) : 1509 /** 1510 * Checks the plaintext password against the encrypted Password. 1511 * 1512 * Maintains compatibility between old version and the new cookie authentication 1513 * protocol using PHPass library. The $hash parameter is the encrypted password 1514 * and the function compares the plain text password when encrypted similarly 1515 * against the already encrypted password to see if they match. 1516 * 1517 * For integration with other applications, this function can be overwritten to 1518 * instead use the other package password checking algorithm. 1519 * 1520 * @since 2.5 1521 * @global object $wp_hasher PHPass object used for checking the password 1522 * against the $hash + $password 1523 * @uses PasswordHash::CheckPassword 1524 * 1525 * @param string $password Plaintext user's password 1526 * @param string $hash Hash of the user's password to check against. 1527 * @return bool False, if the $password does not match the hashed password 1528 */ 1529 function wp_check_password($password, $hash, $user_id = '') { 1530 global $wp_hasher; 1531 1532 // If the hash is still md5... 1533 if ( strlen($hash) <= 32 ) { 1534 $check = ( $hash == md5($password) ); 1535 if ( $check && $user_id ) { 1536 // Rehash using new hash. 1537 wp_set_password($password, $user_id); 1538 $hash = wp_hash_password($password); 1539 } 1540 1541 return apply_filters('check_password', $check, $password, $hash, $user_id); 1542 } 1543 1544 // If the stored hash is longer than an MD5, presume the 1545 // new style phpass portable hash. 1546 if ( empty($wp_hasher) ) { 1547 require_once ( ABSPATH . 'wp-includes/class-phpass.php'); 1548 // By default, use the portable hash from phpass 1549 $wp_hasher = new PasswordHash(8, true); 1550 } 1551 1552 $check = $wp_hasher->CheckPassword($password, $hash); 1553 1554 return apply_filters('check_password', $check, $password, $hash, $user_id); 1555 } 1556 endif; 1557 1558 if ( !function_exists('wp_generate_password') ) : 1559 /** 1560 * Generates a random password drawn from the defined set of characters. 1561 * 1562 * @since 2.5 1563 * 1564 * @param int $length The length of password to generate 1565 * @param bool $special_chars Whether to include standard special characters. Default true. 1566 * @param bool $extra_special_chars Whether to include other special characters. Used when 1567 * generating secret keys and salts. Default false. 1568 * @return string The random password 1569 **/ 1570 function wp_generate_password( $length = 12, $special_chars = true, $extra_special_chars = false ) { 1571 $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; 1572 if ( $special_chars ) 1573 $chars .= '!@#$%^&*()'; 1574 if ( $extra_special_chars ) 1575 $chars .= '-_ []{}<>~`+=,.;:/?|'; 1576 1577 $password = ''; 1578 for ( $i = 0; $i < $length; $i++ ) { 1579 $password .= substr($chars, wp_rand(0, strlen($chars) - 1), 1); 1580 } 1581 1582 // random_password filter was previously in random_password function which was deprecated 1583 return apply_filters('random_password', $password); 1584 } 1585 endif; 1586 1587 if ( !function_exists('wp_rand') ) : 1588 /** 1589 * Generates a random number 1590 * 1591 * @since 2.6.2 1592 * 1593 * @param int $min Lower limit for the generated number 1594 * @param int $max Upper limit for the generated number 1595 * @return int A random number between min and max 1596 */ 1597 function wp_rand( $min = 0, $max = 0 ) { 1598 global $rnd_value; 1599 1600 // Reset $rnd_value after 14 uses 1601 // 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value 1602 if ( strlen($rnd_value) < 8 ) { 1603 if ( defined( 'WP_SETUP_CONFIG' ) ) 1604 static $seed = ''; 1605 else 1606 $seed = get_transient('random_seed'); 1607 $rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed ); 1608 $rnd_value .= sha1($rnd_value); 1609 $rnd_value .= sha1($rnd_value . $seed); 1610 $seed = md5($seed . $rnd_value); 1611 if ( ! defined( 'WP_SETUP_CONFIG' ) ) 1612 set_transient('random_seed', $seed); 1613 } 1614 1615 // Take the first 8 digits for our value 1616 $value = substr($rnd_value, 0, 8); 1617 1618 // Strip the first eight, leaving the remainder for the next call to wp_rand(). 1619 $rnd_value = substr($rnd_value, 8); 1620 1621 $value = abs(hexdec($value)); 1622 1623 // Some misconfigured 32bit environments (Entropy PHP, for example) truncate integers larger than PHP_INT_MAX to PHP_INT_MAX rather than overflowing them to floats. 1624 $max_random_number = 3000000000 === 2147483647 ? (float) "4294967295" : 4294967295; // 4294967295 = 0xffffffff 1625 1626 // Reduce the value to be within the min - max range 1627 if ( $max != 0 ) 1628 $value = $min + ( $max - $min + 1 ) * $value / ( $max_random_number + 1 ); 1629 1630 return abs(intval($value)); 1631 } 1632 endif; 1633 1634 if ( !function_exists('wp_set_password') ) : 1635 /** 1636 * Updates the user's password with a new encrypted one. 1637 * 1638 * For integration with other applications, this function can be overwritten to 1639 * instead use the other package password checking algorithm. 1640 * 1641 * @since 2.5 1642 * @uses $wpdb WordPress database object for queries 1643 * @uses wp_hash_password() Used to encrypt the user's password before passing to the database 1644 * 1645 * @param string $password The plaintext new user password 1646 * @param int $user_id User ID 1647 */ 1648 function wp_set_password( $password, $user_id ) { 1649 global $wpdb; 1650 1651 $hash = wp_hash_password( $password ); 1652 $wpdb->update($wpdb->users, array('user_pass' => $hash, 'user_activation_key' => ''), array('ID' => $user_id) ); 1653 1654 wp_cache_delete($user_id, 'users'); 1655 } 1656 endif; 1657 1658 if ( !function_exists( 'get_avatar' ) ) : 1659 /** 1660 * Retrieve the avatar for a user who provided a user ID or email address. 1661 * 1662 * @since 2.5 1663 * @param int|string|object $id_or_email A user ID, email address, or comment object 1664 * @param int $size Size of the avatar image 1665 * @param string $default URL to a default image to use if no avatar is available 1666 * @param string $alt Alternative text to use in image tag. Defaults to blank 1667 * @return string <img> tag for the user's avatar 1668 */ 1669 function get_avatar( $id_or_email, $size = '96', $default = '', $alt = false ) { 1670 if ( ! get_option('show_avatars') ) 1671 return false; 1672 1673 if ( false === $alt) 1674 $safe_alt = ''; 1675 else 1676 $safe_alt = esc_attr( $alt ); 1677 1678 if ( !is_numeric($size) ) 1679 $size = '96'; 1680 1681 $email = ''; 1682 if ( is_numeric($id_or_email) ) { 1683 $id = (int) $id_or_email; 1684 $user = get_userdata($id); 1685 if ( $user ) 1686 $email = $user->user_email; 1687 } elseif ( is_object($id_or_email) ) { 1688 // No avatar for pingbacks or trackbacks 1689 $allowed_comment_types = apply_filters( 'get_avatar_comment_types', array( 'comment' ) ); 1690 if ( ! empty( $id_or_email->comment_type ) && ! in_array( $id_or_email->comment_type, (array) $allowed_comment_types ) ) 1691 return false; 1692 1693 if ( ! empty( $id_or_email->user_id ) ) { 1694 $id = (int) $id_or_email->user_id; 1695 $user = get_userdata($id); 1696 if ( $user ) 1697 $email = $user->user_email; 1698 } 1699 1700 if ( ! $email && ! empty( $id_or_email->comment_author_email ) ) 1701 $email = $id_or_email->comment_author_email; 1702 } else { 1703 $email = $id_or_email; 1704 } 1705 1706 if ( empty($default) ) { 1707 $avatar_default = get_option('avatar_default'); 1708 if ( empty($avatar_default) ) 1709 $default = 'mystery'; 1710 else 1711 $default = $avatar_default; 1712 } 1713 1714 if ( !empty($email) ) 1715 $email_hash = md5( strtolower( trim( $email ) ) ); 1716 1717 if ( is_ssl() ) { 1718 $host = 'https://secure.gravatar.com'; 1719 } else { 1720 if ( !empty($email) ) 1721 $host = sprintf( "http://%d.gravatar.com", ( hexdec( $email_hash[0] ) % 2 ) ); 1722 else 1723 $host = 'http://0.gravatar.com'; 1724 } 1725 1726 if ( 'mystery' == $default ) 1727 $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com') 1728 elseif ( 'blank' == $default ) 1729 $default = $email ? 'blank' : includes_url( 'images/blank.gif' ); 1730 elseif ( !empty($email) && 'gravatar_default' == $default ) 1731 $default = ''; 1732 elseif ( 'gravatar_default' == $default ) 1733 $default = "$host/avatar/?s={$size}"; 1734 elseif ( empty($email) ) 1735 $default = "$host/avatar/?d=$default&s={$size}"; 1736 elseif ( strpos($default, 'http://') === 0 ) 1737 $default = add_query_arg( 's', $size, $default ); 1738 1739 if ( !empty($email) ) { 1740 $out = "$host/avatar/"; 1741 $out .= $email_hash; 1742 $out .= '?s='.$size; 1743 $out .= '&d=' . urlencode( $default ); 1744 1745 $rating = get_option('avatar_rating'); 1746 if ( !empty( $rating ) ) 1747 $out .= "&r={$rating}"; 1748 1749 $out = str_replace( '&', '&', esc_url( $out ) ); 1750 $avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />"; 1751 } else { 1752 $avatar = "<img alt='{$safe_alt}' src='{$default}' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />"; 1753 } 1754 1755 return apply_filters('get_avatar', $avatar, $id_or_email, $size, $default, $alt); 1756 } 1757 endif; 1758 1759 if ( !function_exists( 'wp_text_diff' ) ) : 1760 /** 1761 * Displays a human readable HTML representation of the difference between two strings. 1762 * 1763 * The Diff is available for getting the changes between versions. The output is 1764 * HTML, so the primary use is for displaying the changes. If the two strings 1765 * are equivalent, then an empty string will be returned. 1766 * 1767 * The arguments supported and can be changed are listed below. 1768 * 1769 * 'title' : Default is an empty string. Titles the diff in a manner compatible 1770 * with the output. 1771 * 'title_left' : Default is an empty string. Change the HTML to the left of the 1772 * title. 1773 * 'title_right' : Default is an empty string. Change the HTML to the right of 1774 * the title. 1775 * 1776 * @since 2.6 1777 * @see wp_parse_args() Used to change defaults to user defined settings. 1778 * @uses Text_Diff 1779 * @uses WP_Text_Diff_Renderer_Table 1780 * 1781 * @param string $left_string "old" (left) version of string 1782 * @param string $right_string "new" (right) version of string 1783 * @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults. 1784 * @return string Empty string if strings are equivalent or HTML with differences. 1785 */ 1786 function wp_text_diff( $left_string, $right_string, $args = null ) { 1787 $defaults = array( 'title' => '', 'title_left' => '', 'title_right' => '' ); 1788 $args = wp_parse_args( $args, $defaults ); 1789 1790 if ( !class_exists( 'WP_Text_Diff_Renderer_Table' ) ) 1791 require ( ABSPATH . WPINC . '/wp-diff.php' ); 1792 1793 $left_string = normalize_whitespace($left_string); 1794 $right_string = normalize_whitespace($right_string); 1795 1796 $left_lines = explode("\n", $left_string); 1797 $right_lines = explode("\n", $right_string); 1798 $text_diff = new Text_Diff($left_lines, $right_lines); 1799 $renderer = new WP_Text_Diff_Renderer_Table( $args ); 1800 $diff = $renderer->render($text_diff); 1801 1802 if ( !$diff ) 1803 return ''; 1804 1805 $r = "<table class='diff'>\n"; 1806 1807 if ( ! empty( $args[ 'show_split_view' ] ) ) { 1808 $r .= "<col class='content diffsplit left' /><col class='content diffsplit middle' /><col class='content diffsplit right' />"; 1809 } else { 1810 $r .= "<col class='content' />"; 1811 } 1812 1813 if ( $args['title'] || $args['title_left'] || $args['title_right'] ) 1814 $r .= "<thead>"; 1815 if ( $args['title'] ) 1816 $r .= "<tr class='diff-title'><th colspan='4'>$args[title]</th></tr>\n"; 1817 if ( $args['title_left'] || $args['title_right'] ) { 1818 $r .= "<tr class='diff-sub-title'>\n"; 1819 $r .= "\t<td></td><th>$args[title_left]</th>\n"; 1820 $r .= "\t<td></td><th>$args[title_right]</th>\n"; 1821 $r .= "</tr>\n"; 1822 } 1823 if ( $args['title'] || $args['title_left'] || $args['title_right'] ) 1824 $r .= "</thead>\n"; 1825 1826 $r .= "<tbody>\n$diff\n</tbody>\n"; 1827 $r .= "</table>"; 1828 1829 return $r; 1830 } 1831 endif; 1832
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |