[ PHPXref.com ] [ Generated: Thu Aug 19 03:45:23 2010 ] [ WordPress 3.0.1 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/wp-includes/ -> pluggable.php (source)

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


[ Powered by PHPXref - Served by Debian GNU/Linux ]