WordPress.org

Make WordPress Core

Ticket #15384: 15384-2010-12-20.diff

File 15384-2010-12-20.diff, 61.7 KB (added by norbertm, 7 years ago)
  • wp-login.php

     
    1111/** Make sure that the WordPress bootstrap has run before continuing. */
    1212require( dirname(__FILE__) . '/wp-load.php' );
    1313
    14 // Redirect to https login if forced to use SSL
    15 if ( force_ssl_admin() && !is_ssl() ) {
    16         if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
    17                 wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI']));
    18                 exit();
    19         } else {
    20                 wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
    21                 exit();
    22         }
    23 }
     14/** Include the login class. */
     15require( ABSPATH . WPINC . '/class-wp-login.php' );
    2416
    25 /**
    26  * Outputs the header for the login page.
    27  *
    28  * @uses do_action() Calls the 'login_head' for outputting HTML in the Log In
    29  *              header.
    30  * @uses apply_filters() Calls 'login_headerurl' for the top login link.
    31  * @uses apply_filters() Calls 'login_headertitle' for the top login title.
    32  * @uses apply_filters() Calls 'login_message' on the message to display in the
    33  *              header.
    34  * @uses $error The error global, which is checked for displaying errors.
    35  *
    36  * @param string $title Optional. WordPress Log In Page title to display in
    37  *              <title/> element.
    38  * @param string $message Optional. Message to display in header.
    39  * @param WP_Error $wp_error Optional. WordPress Error Object
    40  */
    41 function login_header($title = 'Log In', $message = '', $wp_error = '') {
    42         global $error, $is_iphone, $interim_login, $current_site;
     17/** Redirects to https login if forced to use SSL. */
     18WP_Login::ensure_ssl_if_required();
    4319
    44         // Don't index any of these forms
    45         add_filter( 'pre_option_blog_public', '__return_zero' );
    46         add_action( 'login_head', 'noindex' );
    47 
    48         if ( empty($wp_error) )
    49                 $wp_error = new WP_Error();
    50 
    51         // Shake it!
    52         $shake_error_codes = array( 'empty_password', 'empty_email', 'invalid_email', 'invalidcombo', 'empty_username', 'invalid_username', 'incorrect_password' );
    53         $shake_error_codes = apply_filters( 'shake_error_codes', $shake_error_codes );
    54 
    55         if ( $shake_error_codes && $wp_error->get_error_code() && in_array( $wp_error->get_error_code(), $shake_error_codes ) )
    56                 add_action( 'login_head', 'wp_shake_js', 12 );
    57 
    58         ?>
    59 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    60 <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
    61 <head>
    62         <title><?php bloginfo('name'); ?> &rsaquo; <?php echo $title; ?></title>
    63         <meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
    64 <?php
    65         wp_admin_css( 'login', true );
    66         wp_admin_css( 'colors-fresh', true );
    67 
    68         if ( $is_iphone ) { ?>
    69         <meta name="viewport" content="width=320; initial-scale=0.9; maximum-scale=1.0; user-scalable=0;" />
    70         <style type="text/css" media="screen">
    71         form { margin-left: 0px; }
    72         #login { margin-top: 20px; }
    73         </style>
    74 <?php
    75         } elseif ( isset($interim_login) && $interim_login ) { ?>
    76         <style type="text/css" media="all">
    77         .login #login { margin: 20px auto; }
    78         </style>
    79 <?php
    80         }
    81 
    82         do_action('login_head'); ?>
    83 </head>
    84 <body class="login">
    85 <?php   if ( !is_multisite() ) { ?>
    86 <div id="login"><h1><a href="<?php echo apply_filters('login_headerurl', 'http://wordpress.org/'); ?>" title="<?php echo apply_filters('login_headertitle', __('Powered by WordPress')); ?>"><?php bloginfo('name'); ?></a></h1>
    87 <?php   } else { ?>
    88 <div id="login"><h1><a href="<?php echo apply_filters('login_headerurl', network_home_url() ); ?>" title="<?php echo apply_filters('login_headertitle', $current_site->site_name ); ?>"><span class="hide"><?php bloginfo('name'); ?></span></a></h1>
    89 <?php   }
    90 
    91         $message = apply_filters('login_message', $message);
    92         if ( !empty( $message ) ) echo $message . "\n";
    93 
    94         // Incase a plugin uses $error rather than the $errors object
    95         if ( !empty( $error ) ) {
    96                 $wp_error->add('error', $error);
    97                 unset($error);
    98         }
    99 
    100         if ( $wp_error->get_error_code() ) {
    101                 $errors = '';
    102                 $messages = '';
    103                 foreach ( $wp_error->get_error_codes() as $code ) {
    104                         $severity = $wp_error->get_error_data($code);
    105                         foreach ( $wp_error->get_error_messages($code) as $error ) {
    106                                 if ( 'message' == $severity )
    107                                         $messages .= '  ' . $error . "<br />\n";
    108                                 else
    109                                         $errors .= '    ' . $error . "<br />\n";
    110                         }
    111                 }
    112                 if ( !empty($errors) )
    113                         echo '<div id="login_error">' . apply_filters('login_errors', $errors) . "</div>\n";
    114                 if ( !empty($messages) )
    115                         echo '<p class="message">' . apply_filters('login_messages', $messages) . "</p>\n";
    116         }
    117 } // End of login_header()
    118 
    119 /**
    120  * Outputs the footer for the login page.
    121  *
    122  * @param string $input_id Which input to auto-focus
    123  */
    124 function login_footer($input_id = '') {
    125         echo "</div>\n";
    126 
    127         if ( !empty($input_id) ) {
    128 ?>
    129 <script type="text/javascript">
    130 try{document.getElementById('<?php echo $input_id; ?>').focus();}catch(e){}
    131 if(typeof wpOnload=='function')wpOnload();
    132 </script>
    133 <?php
    134         }
    135 ?>
    136 <p id="backtoblog"><a href="<?php bloginfo('url'); ?>/" title="<?php _e('Are you lost?') ?>"><?php printf(__('&larr; Back to %s'), get_bloginfo('title', 'display' )); ?></a></p>
    137 <?php do_action('login_footer'); ?>
    138 </body>
    139 </html>
    140 <?php
    141 }
    142 
    143 function wp_shake_js() {
    144         global $is_iphone;
    145         if ( $is_iphone )
    146                 return;
    147 ?>
    148 <script type="text/javascript">
    149 addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
    150 function s(id,pos){g(id).left=pos+'px';}
    151 function g(id){return document.getElementById(id).style;}
    152 function shake(id,a,d){c=a.shift();s(id,c);if(a.length>0){setTimeout(function(){shake(id,a,d);},d);}else{try{g(id).position='static';wp_attempt_focus();}catch(e){}}}
    153 addLoadEvent(function(){ var p=new Array(15,30,15,0,-15,-30,-15,0);p=p.concat(p.concat(p));var i=document.forms[0].id;g(i).position='relative';shake(i,p,20);});
    154 </script>
    155 <?php
    156 }
    157 
    158 /**
    159  * Handles sending password retrieval email to user.
    160  *
    161  * @uses $wpdb WordPress Database object
    162  *
    163  * @return bool|WP_Error True: when finish. WP_Error on error
    164  */
    165 function retrieve_password() {
    166         global $wpdb, $current_site;
    167 
    168         $errors = new WP_Error();
    169 
    170         if ( empty( $_POST['user_login'] ) && empty( $_POST['user_email'] ) )
    171                 $errors->add('empty_username', __('<strong>ERROR</strong>: Enter a username or e-mail address.'));
    172 
    173         if ( strpos($_POST['user_login'], '@') ) {
    174                 $user_data = get_user_by_email(trim($_POST['user_login']));
    175                 if ( empty($user_data) )
    176                         $errors->add('invalid_email', __('<strong>ERROR</strong>: There is no user registered with that email address.'));
    177         } else {
    178                 $login = trim($_POST['user_login']);
    179                 $user_data = get_userdatabylogin($login);
    180         }
    181 
    182         do_action('lostpassword_post');
    183 
    184         if ( $errors->get_error_code() )
    185                 return $errors;
    186 
    187         if ( !$user_data ) {
    188                 $errors->add('invalidcombo', __('<strong>ERROR</strong>: Invalid username or e-mail.'));
    189                 return $errors;
    190         }
    191 
    192         // redefining user_login ensures we return the right case in the email
    193         $user_login = $user_data->user_login;
    194         $user_email = $user_data->user_email;
    195 
    196         do_action('retreive_password', $user_login);  // Misspelled and deprecated
    197         do_action('retrieve_password', $user_login);
    198 
    199         $allow = apply_filters('allow_password_reset', true, $user_data->ID);
    200 
    201         if ( ! $allow )
    202                 return new WP_Error('no_password_reset', __('Password reset is not allowed for this user'));
    203         else if ( is_wp_error($allow) )
    204                 return $allow;
    205 
    206         $key = $wpdb->get_var($wpdb->prepare("SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $user_login));
    207         if ( empty($key) ) {
    208                 // Generate something random for a key...
    209                 $key = wp_generate_password(20, false);
    210                 do_action('retrieve_password_key', $user_login, $key);
    211                 // Now insert the new md5 key into the db
    212                 $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login));
    213         }
    214         $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
    215         $message .= network_site_url() . "\r\n\r\n";
    216         $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
    217         $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
    218         $message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
    219         $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . ">\r\n";
    220 
    221         if ( is_multisite() )
    222                 $blogname = $GLOBALS['current_site']->site_name;
    223         else
    224                 // The blogname option is escaped with esc_html on the way into the database in sanitize_option
    225                 // we want to reverse this for the plain text arena of emails.
    226                 $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
    227 
    228         $title = sprintf( __('[%s] Password Reset'), $blogname );
    229 
    230         $title = apply_filters('retrieve_password_title', $title);
    231         $message = apply_filters('retrieve_password_message', $message, $key);
    232 
    233         if ( $message && !wp_mail($user_email, $title, $message) )
    234                 wp_die( __('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function...') );
    235 
    236         return true;
    237 }
    238 
    239 /**
    240  * Retrieves a user row based on password reset key and login
    241  *
    242  * @uses $wpdb WordPress Database object
    243  *
    244  * @param string $key Hash to validate sending user's password
    245  * @param string $login The user login
    246  *
    247  * @return object|WP_Error
    248  */
    249 function check_password_reset_key($key, $login) {
    250         global $wpdb;
    251 
    252         $key = preg_replace('/[^a-z0-9]/i', '', $key);
    253 
    254         if ( empty( $key ) || !is_string( $key ) )
    255                 return new WP_Error('invalid_key', __('Invalid key'));
    256 
    257         if ( empty($login) || !is_string($login) )
    258                 return new WP_Error('invalid_key', __('Invalid key'));
    259 
    260         $user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_activation_key = %s AND user_login = %s", $key, $login));
    261 
    262         if ( empty( $user ) )
    263                 return new WP_Error('invalid_key', __('Invalid key'));
    264 
    265         return $user;
    266 }
    267 
    268 /**
    269  * Handles resetting the user's password.
    270  *
    271  * @uses $wpdb WordPress Database object
    272  *
    273  * @param string $key Hash to validate sending user's password
    274  */
    275 function reset_password($user, $new_pass) {
    276         do_action('password_reset', $user, $new_pass);
    277 
    278         wp_set_password($new_pass, $user->ID);
    279 
    280         wp_password_change_notification($user);
    281 }
    282 
    283 /**
    284  * Handles registering a new user.
    285  *
    286  * @param string $user_login User's username for logging in
    287  * @param string $user_email User's email address to send password and add
    288  * @return int|WP_Error Either user's ID or error on failure.
    289  */
    290 function register_new_user( $user_login, $user_email ) {
    291         $errors = new WP_Error();
    292 
    293         $sanitized_user_login = sanitize_user( $user_login );
    294         $user_email = apply_filters( 'user_registration_email', $user_email );
    295 
    296         // Check the username
    297         if ( $sanitized_user_login == '' ) {
    298                 $errors->add( 'empty_username', __( '<strong>ERROR</strong>: Please enter a username.' ) );
    299         } elseif ( ! validate_username( $user_login ) ) {
    300                 $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
    301                 $sanitized_user_login = '';
    302         } elseif ( username_exists( $sanitized_user_login ) ) {
    303                 $errors->add( 'username_exists', __( '<strong>ERROR</strong>: This username is already registered, please choose another one.' ) );
    304         }
    305 
    306         // Check the e-mail address
    307         if ( $user_email == '' ) {
    308                 $errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please type your e-mail address.' ) );
    309         } elseif ( ! is_email( $user_email ) ) {
    310                 $errors->add( 'invalid_email', __( '<strong>ERROR</strong>: The email address isn&#8217;t correct.' ) );
    311                 $user_email = '';
    312         } elseif ( email_exists( $user_email ) ) {
    313                 $errors->add( 'email_exists', __( '<strong>ERROR</strong>: This email is already registered, please choose another one.' ) );
    314         }
    315 
    316         do_action( 'register_post', $sanitized_user_login, $user_email, $errors );
    317 
    318         $errors = apply_filters( 'registration_errors', $errors, $sanitized_user_login, $user_email );
    319 
    320         if ( $errors->get_error_code() )
    321                 return $errors;
    322 
    323         $user_pass = wp_generate_password( 12, false);
    324         $user_id = wp_create_user( $sanitized_user_login, $user_pass, $user_email );
    325         if ( ! $user_id ) {
    326                 $errors->add( 'registerfail', sprintf( __( '<strong>ERROR</strong>: Couldn&#8217;t register you... please contact the <a href="mailto:%s">webmaster</a> !' ), get_option( 'admin_email' ) ) );
    327                 return $errors;
    328         }
    329 
    330         update_user_option( $user_id, 'default_password_nag', true, true ); //Set up the Password change nag.
    331 
    332         wp_new_user_notification( $user_id, $user_pass );
    333 
    334         return $user_id;
    335 }
    336 
    337 //
    338 // Main
    339 //
    340 
    341 $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'login';
    342 $errors = new WP_Error();
    343 
    344 if ( isset($_GET['key']) )
    345         $action = 'resetpass';
    346 
    347 // validate action so as to default to the login screen
    348 if ( !in_array($action, array('logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login'), true) && false === has_filter('login_form_' . $action) )
    349         $action = 'login';
    350 
     20/** Output headers. */
    35121nocache_headers();
    352 
    35322header('Content-Type: '.get_bloginfo('html_type').'; charset='.get_bloginfo('charset'));
    35423
    355 if ( defined('RELOCATE') ) { // Move flag is set
    356         if ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != $_SERVER['PHP_SELF']) )
    357                 $_SERVER['PHP_SELF'] = str_replace( $_SERVER['PATH_INFO'], '', $_SERVER['PHP_SELF'] );
     24/** Check for move flag. */
     25WP_Login::relocate_if_required();
    35826
    359         $schema = is_ssl() ? 'https://' : 'http://';
    360         if ( dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) != get_option('siteurl') )
    361                 update_option('siteurl', dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) );
    362 }
     27/** Test for cookies. */
     28WP_Login::send_test_cookies();
    36329
    364 //Set a cookie now to see if they are supported by the browser.
    365 setcookie(TEST_COOKIE, 'WP Cookie check', 0, COOKIEPATH, COOKIE_DOMAIN);
    366 if ( SITECOOKIEPATH != COOKIEPATH )
    367         setcookie(TEST_COOKIE, 'WP Cookie check', 0, SITECOOKIEPATH, COOKIE_DOMAIN);
     30/** Process the request. */
     31WP_Login::dispatch();
    36832
    369 // allow plugins to override the default actions, and to add extra actions if they want
    370 do_action('login_form_' . $action);
     33/*
     34// TODO possible bug in the original file instead of $errors
     35if ( !$error )
    37136
    372 $http_post = ('POST' == $_SERVER['REQUEST_METHOD']);
    373 switch ($action) {
    374 
    375 case 'logout' :
    376         check_admin_referer('log-out');
    377         wp_logout();
    378 
    379         $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : 'wp-login.php?loggedout=true';
    380         wp_safe_redirect( $redirect_to );
    381         exit();
    382 
    383 break;
    384 
    385 case 'lostpassword' :
    386 case 'retrievepassword' :
    387 
    388         if ( $http_post ) {
    389                 $errors = retrieve_password();
    390                 if ( !is_wp_error($errors) ) {
    391                         $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : 'wp-login.php?checkemail=confirm';
    392                         wp_safe_redirect( $redirect_to );
    393                         exit();
    394                 }
    395         }
    396 
    397         if ( isset($_GET['error']) && 'invalidkey' == $_GET['error'] ) $errors->add('invalidkey', __('Sorry, that key does not appear to be valid.'));
    398         $redirect_to = apply_filters( 'lostpassword_redirect', !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '' );
    399 
    400         do_action('lost_password');
    401         login_header(__('Lost Password'), '<p class="message">' . __('Please enter your username or email address. You will receive a link to create a new password via email.') . '</p>', $errors);
    402 
    403         $user_login = isset($_POST['user_login']) ? stripslashes($_POST['user_login']) : '';
    404 
    405 ?>
    406 
    407 <form name="lostpasswordform" id="lostpasswordform" action="<?php echo site_url('wp-login.php?action=lostpassword', 'login_post') ?>" method="post">
    408         <p>
    409                 <label><?php _e('Username or E-mail:') ?><br />
    410                 <input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr($user_login); ?>" size="20" tabindex="10" /></label>
    411         </p>
    412 <?php do_action('lostpassword_form'); ?>
    413         <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
    414         <p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Get New Password'); ?>" tabindex="100" /></p>
    415 </form>
    416 
    417 <p id="nav">
    418 <a href="<?php echo site_url('wp-login.php', 'login') ?>"><?php _e('Log in') ?></a>
    419 <?php if (get_option('users_can_register')) : ?>
    420  | <a href="<?php echo site_url('wp-login.php?action=register', 'login') ?>"><?php _e('Register') ?></a>
    421 <?php endif; ?>
    422 </p>
    423 
    424 <?php
    425 login_footer('user_login');
    426 break;
    427 
    428 case 'resetpass' :
    429 case 'rp' :
    430         $user = check_password_reset_key($_GET['key'], $_GET['login']);
    431 
    432         if ( is_wp_error($user) ) {
    433                 wp_redirect( site_url('wp-login.php?action=lostpassword&error=invalidkey') );
    434                 exit;
    435         }
    436 
    437         $errors = '';
    438 
    439         if ( isset($_POST['pass1']) && $_POST['pass1'] != $_POST['pass2'] ) {
    440                 $errors = new WP_Error('password_reset_mismatch', __('The passwords do not match.'));
    441         } elseif ( isset($_POST['pass1']) && !empty($_POST['pass1']) ) {
    442                 reset_password($user, $_POST['pass1']);
    443                 login_header(__('Password Reset'), '<p class="message reset-pass">' . __('Your password has been reset.') . ' <a href="' . site_url('wp-login.php', 'login') . '">' . __('Log in') . '</a></p>');
    444                 login_footer();
    445                 exit;
    446         }
    447 
    448         wp_enqueue_script('utils');
    449         wp_enqueue_script('user-profile');
    450 
    451         login_header(__('Reset Password'), '<p class="message reset-pass">' . __('Enter your new password below.') . '</p>', $errors );
    452 
    453 ?>
    454 <form name="resetpassform" id="resetpassform" action="<?php echo site_url('wp-login.php?action=resetpass&key=' . urlencode($_GET['key']) . '&login=' . urlencode($_GET['login']), 'login_post') ?>" method="post">
    455         <input type="hidden" id="user_login" value="<?php echo esc_attr( $_GET['login'] ); ?>" autocomplete="off" />
    456 
    457         <p>
    458                 <label><?php _e('New password') ?><br />
    459                 <input type="password" name="pass1" id="pass1" class="input" size="20" value="" autocomplete="off" /></label>
    460         </p>
    461         <p>
    462                 <label><?php _e('Confirm new password') ?><br />
    463                 <input type="password" name="pass2" id="pass2" class="input" size="20" value="" autocomplete="off" /></label>
    464         </p>
    465 
    466         <div id="pass-strength-result" class="hide-if-no-js"><?php _e('Strength indicator'); ?></div>
    467         <p class="description indicator-hint"><?php _e('Hint: The password should be at least seven characters long. To make it stronger, use upper and lower case letters, numbers and symbols like ! " ? $ % ^ &amp; ).'); ?></p>
    468 
    469         <br class="clear" />
    470         <p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Reset Password'); ?>" tabindex="100" /></p>
    471 </form>
    472 
    473 <p id="nav">
    474 <a href="<?php echo site_url('wp-login.php', 'login') ?>"><?php _e('Log in') ?></a>
    475 <?php if (get_option('users_can_register')) : ?>
    476  | <a href="<?php echo site_url('wp-login.php?action=register', 'login') ?>"><?php _e('Register') ?></a>
    477 <?php endif; ?>
    478 </p>
    479 
    480 <?php
    481 login_footer('user_pass');
    482 break;
    483 
    484 case 'register' :
    485         if ( is_multisite() ) {
    486                 // Multisite uses wp-signup.php
    487                 wp_redirect( apply_filters( 'wp_signup_location', site_url('wp-signup.php') ) );
    488                 exit;
    489         }
    490 
    491         if ( !get_option('users_can_register') ) {
    492                 wp_redirect( site_url('wp-login.php?registration=disabled') );
    493                 exit();
    494         }
    495 
    496         $user_login = '';
    497         $user_email = '';
    498         if ( $http_post ) {
    499                 $user_login = $_POST['user_login'];
    500                 $user_email = $_POST['user_email'];
    501                 $errors = register_new_user($user_login, $user_email);
    502                 if ( !is_wp_error($errors) ) {
    503                         $redirect_to = !empty( $_POST['redirect_to'] ) ? $_POST['redirect_to'] : 'wp-login.php?checkemail=registered';
    504                         wp_safe_redirect( $redirect_to );
    505                         exit();
    506                 }
    507         }
    508 
    509         $redirect_to = apply_filters( 'registration_redirect', !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '' );
    510         login_header(__('Registration Form'), '<p class="message register">' . __('Register For This Site') . '</p>', $errors);
    511 ?>
    512 
    513 <form name="registerform" id="registerform" action="<?php echo site_url('wp-login.php?action=register', 'login_post') ?>" method="post">
    514         <p>
    515                 <label><?php _e('Username') ?><br />
    516                 <input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr(stripslashes($user_login)); ?>" size="20" tabindex="10" /></label>
    517         </p>
    518         <p>
    519                 <label><?php _e('E-mail') ?><br />
    520                 <input type="text" name="user_email" id="user_email" class="input" value="<?php echo esc_attr(stripslashes($user_email)); ?>" size="25" tabindex="20" /></label>
    521         </p>
    522 <?php do_action('register_form'); ?>
    523         <p id="reg_passmail"><?php _e('A password will be e-mailed to you.') ?></p>
    524         <br class="clear" />
    525         <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
    526         <p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Register'); ?>" tabindex="100" /></p>
    527 </form>
    528 
    529 <p id="nav">
    530 <a href="<?php echo site_url('wp-login.php', 'login') ?>"><?php _e('Log in') ?></a> |
    531 <a href="<?php echo site_url('wp-login.php?action=lostpassword', 'login') ?>" title="<?php _e('Password Lost and Found') ?>"><?php _e('Lost your password?') ?></a>
    532 </p>
    533 
    534 <?php
    535 login_footer('user_login');
    536 break;
    537 
     37// TODO make sure to include the default callback
    53838case 'login' :
    53939default:
    540         $secure_cookie = '';
    541         $interim_login = isset($_REQUEST['interim-login']);
    54240
    543         // If the user wants ssl but the session is not ssl, force a secure cookie.
    544         if ( !empty($_POST['log']) && !force_ssl_admin() ) {
    545                 $user_name = sanitize_user($_POST['log']);
    546                 if ( $user = get_userdatabylogin($user_name) ) {
    547                         if ( get_user_option('use_ssl', $user->ID) ) {
    548                                 $secure_cookie = true;
    549                                 force_ssl_admin(true);
    550                         }
    551                 }
    552         }
    553 
    554         if ( isset( $_REQUEST['redirect_to'] ) ) {
    555                 $redirect_to = $_REQUEST['redirect_to'];
    556                 // Redirect to https if user wants ssl
    557                 if ( $secure_cookie && false !== strpos($redirect_to, 'wp-admin') )
    558                         $redirect_to = preg_replace('|^http://|', 'https://', $redirect_to);
    559         } else {
    560                 $redirect_to = admin_url();
    561         }
    562 
    563         $reauth = empty($_REQUEST['reauth']) ? false : true;
    564 
    565         // If the user was redirected to a secure login form from a non-secure admin page, and secure login is required but secure admin is not, then don't use a secure
    566         // cookie and redirect back to the referring non-secure admin page.  This allows logins to always be POSTed over SSL while allowing the user to choose visiting
    567         // the admin via http or https.
    568         if ( !$secure_cookie && is_ssl() && force_ssl_login() && !force_ssl_admin() && ( 0 !== strpos($redirect_to, 'https') ) && ( 0 === strpos($redirect_to, 'http') ) )
    569                 $secure_cookie = false;
    570 
    571         $user = wp_signon('', $secure_cookie);
    572 
    573         $redirect_to = apply_filters('login_redirect', $redirect_to, isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '', $user);
    574 
    575         if ( !is_wp_error($user) && !$reauth ) {
    576                 if ( $interim_login ) {
    577                         $message = '<p class="message">' . __('You have logged in successfully.') . '</p>';
    578                         login_header( '', $message ); ?>
    579                         <script type="text/javascript">setTimeout( function(){window.close()}, 8000);</script>
    580                         <p class="alignright">
    581                         <input type="button" class="button-primary" value="<?php esc_attr_e('Close'); ?>" onclick="window.close()" /></p>
    582                         </div></body></html>
    583 <?php           exit;
    584                 }
    585 
    586                 // If the user doesn't belong to a blog, send them to user admin. If the user can't edit posts, send them to their profile.
    587                 if ( is_multisite() && !get_active_blog_for_user($user->id) )
    588                         $redirect_to = user_admin_url();
    589                 elseif ( !is_multisite() && !$user->has_cap('read') )
    590                         $redirect_to = user_admin_url();
    591                 elseif ( !$user->has_cap('edit_posts') && ( empty( $redirect_to ) || $redirect_to == 'wp-admin/' || $redirect_to == admin_url() ) )
    592                         $redirect_to = admin_url('profile.php');
    593                 wp_safe_redirect($redirect_to);
    594                 exit();
    595         }
    596 
    597         $errors = $user;
    598         // Clear errors if loggedout is set.
    599         if ( !empty($_GET['loggedout']) || $reauth )
    600                 $errors = new WP_Error();
    601 
    602         // If cookies are disabled we can't log in even with a valid user+pass
    603         if ( isset($_POST['testcookie']) && empty($_COOKIE[TEST_COOKIE]) )
    604                 $errors->add('test_cookie', __("<strong>ERROR</strong>: Cookies are blocked or not supported by your browser. You must <a href='http://www.google.com/cookies.html'>enable cookies</a> to use WordPress."));
    605 
    606         // Some parts of this script use the main login form to display a message
    607         if              ( isset($_GET['loggedout']) && TRUE == $_GET['loggedout'] )
    608                 $errors->add('loggedout', __('You are now logged out.'), 'message');
    609         elseif  ( isset($_GET['registration']) && 'disabled' == $_GET['registration'] )
    610                 $errors->add('registerdisabled', __('User registration is currently not allowed.'));
    611         elseif  ( isset($_GET['checkemail']) && 'confirm' == $_GET['checkemail'] )
    612                 $errors->add('confirm', __('Check your e-mail for the confirmation link.'), 'message');
    613         elseif  ( isset($_GET['checkemail']) && 'newpass' == $_GET['checkemail'] )
    614                 $errors->add('newpass', __('Check your e-mail for your new password.'), 'message');
    615         elseif  ( isset($_GET['checkemail']) && 'registered' == $_GET['checkemail'] )
    616                 $errors->add('registered', __('Registration complete. Please check your e-mail.'), 'message');
    617         elseif  ( $interim_login )
    618                 $errors->add('expired', __('Your session has expired. Please log-in again.'), 'message');
    619 
    620         // Clear any stale cookies.
    621         if ( $reauth )
    622                 wp_clear_auth_cookie();
    623 
    624         login_header(__('Log In'), '', $errors);
    625 
    626         if ( isset($_POST['log']) )
    627                 $user_login = ( 'incorrect_password' == $errors->get_error_code() || 'empty_password' == $errors->get_error_code() ) ? esc_attr(stripslashes($_POST['log'])) : '';
    628         $rememberme = ! empty( $_POST['rememberme'] );
    629 ?>
    630 
    631 <form name="loginform" id="loginform" action="<?php echo site_url('wp-login.php', 'login_post') ?>" method="post">
    632         <p>
    633                 <label><?php _e('Username') ?><br />
    634                 <input type="text" name="log" id="user_login" class="input" value="<?php echo esc_attr($user_login); ?>" size="20" tabindex="10" /></label>
    635         </p>
    636         <p>
    637                 <label><?php _e('Password') ?><br />
    638                 <input type="password" name="pwd" id="user_pass" class="input" value="" size="20" tabindex="20" /></label>
    639         </p>
    640 <?php do_action('login_form'); ?>
    641         <p class="forgetmenot"><label><input name="rememberme" type="checkbox" id="rememberme" value="forever" tabindex="90"<?php checked( $rememberme ); ?> /> <?php esc_attr_e('Remember Me'); ?></label></p>
    642         <p class="submit">
    643                 <input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Log In'); ?>" tabindex="100" />
    644 <?php   if ( $interim_login ) { ?>
    645                 <input type="hidden" name="interim-login" value="1" />
    646 <?php   } else { ?>
    647                 <input type="hidden" name="redirect_to" value="<?php echo esc_attr($redirect_to); ?>" />
    648 <?php   } ?>
    649                 <input type="hidden" name="testcookie" value="1" />
    650         </p>
    651 </form>
    652 
    653 <?php if ( !$interim_login ) { ?>
    654 <p id="nav">
    655 <?php if ( isset($_GET['checkemail']) && in_array( $_GET['checkemail'], array('confirm', 'newpass') ) ) : ?>
    656 <?php elseif ( get_option('users_can_register') ) : ?>
    657 <a href="<?php echo site_url('wp-login.php?action=register', 'login') ?>"><?php _e('Register') ?></a> |
    658 <a href="<?php echo site_url('wp-login.php?action=lostpassword', 'login') ?>" title="<?php _e('Password Lost and Found') ?>"><?php _e('Lost your password?') ?></a>
    659 <?php else : ?>
    660 <a href="<?php echo site_url('wp-login.php?action=lostpassword', 'login') ?>" title="<?php _e('Password Lost and Found') ?>"><?php _e('Lost your password?') ?></a>
    661 <?php endif; ?>
    662 </p>
    663 </div>
    664 <p id="backtoblog"><a href="<?php bloginfo('url'); ?>/" title="<?php _e('Are you lost?') ?>"><?php printf(__('&larr; Back to %s'), get_bloginfo('title', 'display' )); ?></a></p>
    665 <?php } else { ?>
    666 </div>
    667 <?php } ?>
    668 
    669 <script type="text/javascript">
    670 function wp_attempt_focus(){
    671 setTimeout( function(){ try{
    672 <?php if ( $user_login || $interim_login ) { ?>
    673 d = document.getElementById('user_pass');
    674 d.value = '';
    675 <?php } else { ?>
    676 d = document.getElementById('user_login');
    677 <?php if ( 'invalid_username' == $errors->get_error_code() ) { ?>
    678 if( d.value != '' )
    679 d.value = '';
    680 <?php
    681 }
    682 }?>
    683 d.focus();
    684 d.select();
    685 } catch(e){}
    686 }, 200);
    687 }
    688 
    689 <?php if ( !$error ) { ?>
    690 wp_attempt_focus();
    691 <?php } ?>
    692 if(typeof wpOnload=='function')wpOnload();
    693 </script>
    694 <?php do_action( 'login_footer' ); ?>
    695 </body>
    696 </html>
    697 <?php
    698 
    699 break;
    700 } // end action switch
    701 ?>
     41// TODO why empty string vs WP_Error
     42$errors = '';
     43*/
     44       
     45?>
     46 No newline at end of file
  • wp-includes/class-wp-login.php

     
     1<?php
     2/**
     3 * Class for handling user registration, login and related actions.
     4 *
     5 * Dispatch routes the request to the proper action.
     6 *
     7 * Process functions do the action processing and return errors if any.
     8 * They call the Do functions which do the actual service level work.
     9 *
     10 * Finally the errors returned are passed to a Render function,
     11 * which in turn calls one or many Output functions to output the HTML.
     12 *
     13 * @package WordPress
     14 * @since 3.2.0
     15 */
     16class WP_Login {
     17        /**
     18         * Redirects to https if forced to use SSL.
     19         */
     20        function ensure_ssl_if_required() {
     21                if ( force_ssl_admin() && !is_ssl() ) {
     22                        if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
     23                                wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI']));
     24                                exit();
     25                        } else {
     26                                wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
     27                                exit();
     28                        }
     29                }
     30        }
     31
     32        /**
     33         * Sets some cookies for render_login() to see if the browser supports them.
     34         */
     35        function send_test_cookies() {
     36                //Set a cookie now to see if they are supported by the browser.
     37                setcookie(TEST_COOKIE, 'WP Cookie check', 0, COOKIEPATH, COOKIE_DOMAIN);
     38                if ( SITECOOKIEPATH != COOKIEPATH )
     39                        setcookie(TEST_COOKIE, 'WP Cookie check', 0, SITECOOKIEPATH, COOKIE_DOMAIN);
     40        }
     41
     42        /**
     43         * Checks for move flag.
     44         */
     45        function relocate_if_required() {
     46                if ( defined('RELOCATE') ) { // Move flag is set
     47                        if ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != $_SERVER['PHP_SELF']) )
     48                                $_SERVER['PHP_SELF'] = str_replace( $_SERVER['PATH_INFO'], '', $_SERVER['PHP_SELF'] );
     49
     50                        $schema = is_ssl() ? 'https://' : 'http://';
     51                        if ( dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) != get_option('siteurl') )
     52                                update_option('siteurl', dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) );
     53                }
     54        }
     55
     56        /**
     57         * Dispatches to a controller based on the action requested.
     58         */
     59        function dispatch() {
     60                $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'login';
     61
     62                if ( isset($_GET['key']) )
     63                        $action = 'resetpass';
     64
     65                // aliases for backwards compatibility
     66                $aliases = array(
     67                        'rp' => 'resetpass',
     68                        'retrievepassword' => 'lostpassword'
     69                );
     70                if ( array_key_exists( $action, $aliases ) ) {
     71                        $action = $aliases[$action];
     72                }
     73
     74                // validate action so as to default to the login screen
     75                if ( !in_array($action, array('logout', 'lostpassword', 'resetpass', 'register', 'login'), true) && false === has_filter('login_form_' . $action) )
     76                        $action = 'login';
     77
     78                // allow plugins to override the default actions, and to add extra actions if they want
     79                do_action('login_form_' . $action);
     80
     81                $errors = new WP_Error();
     82
     83                // if there is a separate method for processing, let's call that first
     84                $method = 'process_' . $action;
     85                if ( method_exists( __CLASS__, $method ) ) {
     86                        $errors = call_user_func( array( __CLASS__, $method ) );
     87                }
     88
     89                // render the output with any errors during processing
     90                $method = 'render_' . $action;
     91                if ( !method_exists( __CLASS__, $method ) ) {
     92                        // This should never happen.
     93                        echo "'Action handler '" . __CLASS__ . '::' . $method . "()' does not exist.";
     94                        exit();
     95                }
     96
     97                call_user_func( array( __CLASS__, $method ), $errors );
     98                exit();
     99        }
     100
     101        /**
     102         * Handles user logout.
     103         */
     104        function process_logout() {
     105                check_admin_referer('log-out');
     106                wp_logout();
     107
     108                WP_Login::do_safe_redirect( 'wp-login.php?loggedout=true' );
     109                exit();
     110        }
     111
     112        /**
     113         * Processes the password retrieval request.
     114         *
     115         * @return WP_Error
     116         */
     117        function process_lostpassword() {
     118                $errors = new WP_Error();
     119
     120                if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) {
     121                        $errors = WP_Login::do_retrieve_password();
     122                        if ( !is_wp_error($errors) ) {
     123                                WP_Login::do_safe_redirect( 'wp-login.php?checkemail=confirm' );
     124                                exit();
     125                        }
     126                }
     127
     128                if ( isset($_GET['error']) && 'invalidkey' == $_GET['error'] ) $errors->add('invalidkey', __('Sorry, that key does not appear to be valid.'));
     129
     130                do_action('lost_password');
     131
     132                return $errors;
     133        }
     134
     135        /**
     136         * Processes the reset password request.
     137         *
     138         * @return WP_Error
     139         */
     140        function process_resetpass() {
     141                $user = WP_Login::do_check_password_reset_key($_GET['key'], $_GET['login']);
     142                if ( is_wp_error($user) ) {
     143                        wp_redirect( site_url('wp-login.php?action=lostpassword&error=invalidkey') );
     144                        exit;
     145                }
     146
     147                $errors = '';
     148
     149                if ( isset($_POST['pass1']) && $_POST['pass1'] != $_POST['pass2'] ) {
     150                        $errors = new WP_Error('password_reset_mismatch', __('The passwords do not match.'));
     151                } elseif ( isset($_POST['pass1']) && !empty($_POST['pass1']) ) {
     152                        WP_Login::do_reset_password($user, $_POST['pass1']);
     153                        WP_Login::output_resetpass_completed_html();
     154                        exit();
     155                }
     156
     157                return $errors;
     158        }
     159
     160        /**
     161         * Processes the user registration request.
     162         *
     163         * @return WP_Error
     164         */
     165        function process_register() {
     166                if ( is_multisite() ) {
     167                        // Multisite uses wp-signup.php
     168                        wp_redirect( apply_filters( 'wp_signup_location', site_url('wp-signup.php') ) );
     169                        exit;
     170                }
     171
     172                if ( !get_option('users_can_register') ) {
     173                        wp_redirect( site_url('wp-login.php?registration=disabled') );
     174                        exit();
     175                }
     176
     177                $errors = new WP_Error();
     178
     179                if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) {
     180                        $user_login = $_POST['user_login'];
     181                        $user_email = $_POST['user_email'];
     182
     183                        $errors = WP_Login::do_register_new_user($user_login, $user_email);
     184                        if ( !is_wp_error($errors) ) {
     185                                $redirect_to = !empty( $_POST['redirect_to'] ) ? $_POST['redirect_to'] : 'wp-login.php?checkemail=registered';
     186                                wp_safe_redirect( $redirect_to );
     187                                exit();
     188                        }
     189                }
     190
     191                return $errors;
     192        }
     193
     194        /**
     195         * Processes the login request.
     196         *
     197         * @return WP_Error
     198         */
     199        function process_login() {
     200                $errors = new WP_Error();
     201               
     202                // TBI by splitting up render_login()
     203               
     204                return $errors;
     205        }
     206
     207        /**
     208         * Renders the link retrieval form.
     209         *
     210         * @param WP_Error $errors
     211         */
     212        function render_lostpassword( $errors ) {
     213                $redirect_to = apply_filters( 'lostpassword_redirect', !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '' );
     214
     215                $user_login = isset($_POST['user_login']) ? stripslashes($_POST['user_login']) : '';
     216
     217                WP_Login::output_lostpassword_form_html($user_login, $errors, $redirect_to);
     218        }
     219
     220        /**
     221         * Renders the password change form.
     222         *
     223         * @param WP_Error $errors
     224         */
     225        function render_resetpass( $errors ) {
     226                wp_enqueue_script('utils');
     227                wp_enqueue_script('user-profile');
     228
     229                WP_Login::output_resetpass_form_html( $errors );
     230        }
     231
     232        /**
     233         * Renders the registration form.
     234         *
     235         * @param WP_Error $errors
     236         */
     237        function render_register( $errors ) {
     238                $user_login = '';
     239                $user_email = '';
     240
     241                if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) {
     242                        $user_login = $_POST['user_login'];
     243                        $user_email = $_POST['user_email'];
     244                }
     245
     246                $redirect_to = apply_filters( 'registration_redirect', !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '' );
     247
     248                WP_Login::output_register_form_html( $user_login, $user_email, $redirect_to, $errors );
     249        }
     250
     251        /**
     252         * Renders the login form.
     253         *
     254         * @param WP_Error $errors
     255         */
     256        function render_login( $errors ) {
     257               
     258                // TBI split this up, see process_login() above, challenging because of $redirect_to
     259               
     260                $secure_cookie = '';
     261                $interim_login = isset($_REQUEST['interim-login']);
     262
     263                // If the user wants ssl but the session is not ssl, force a secure cookie.
     264                if ( !empty($_POST['log']) && !force_ssl_admin() ) {
     265                        $user_name = sanitize_user($_POST['log']);
     266                        if ( $user = get_userdatabylogin($user_name) ) {
     267                                if ( get_user_option('use_ssl', $user->ID) ) {
     268                                        $secure_cookie = true;
     269                                        force_ssl_admin(true);
     270                                }
     271                        }
     272                }
     273
     274                if ( isset( $_REQUEST['redirect_to'] ) ) {
     275                        $redirect_to = $_REQUEST['redirect_to'];
     276                        // Redirect to https if user wants ssl
     277                        if ( $secure_cookie && false !== strpos($redirect_to, 'wp-admin') )
     278                                $redirect_to = preg_replace('|^http://|', 'https://', $redirect_to);
     279                } else {
     280                        $redirect_to = admin_url();
     281                }
     282
     283                $reauth = empty($_REQUEST['reauth']) ? false : true;
     284
     285                // If the user was redirected to a secure login form from a non-secure admin page, and secure login is required but secure admin is not, then don't use a secure
     286                // cookie and redirect back to the referring non-secure admin page.  This allows logins to always be POSTed over SSL while allowing the user to choose visiting
     287                // the admin via http or https.
     288                if ( !$secure_cookie && is_ssl() && force_ssl_login() && !force_ssl_admin() && ( 0 !== strpos($redirect_to, 'https') ) && ( 0 === strpos($redirect_to, 'http') ) )
     289                        $secure_cookie = false;
     290
     291                $user = wp_signon('', $secure_cookie);
     292
     293                $redirect_to = apply_filters('login_redirect', $redirect_to, isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '', $user);
     294
     295                if ( !is_wp_error($user) && !$reauth ) {
     296                        if ( $interim_login ) {
     297                                WP_Login::output_login_interim_html();
     298                                exit();
     299                        }
     300
     301                        // If the user doesn't belong to a blog, send them to user admin. If the user can't edit posts, send them to their profile.
     302                        if ( is_multisite() && !get_active_blog_for_user($user->id) )
     303                                $redirect_to = user_admin_url();
     304                        elseif ( !is_multisite() && !$user->has_cap('read') )
     305                                $redirect_to = user_admin_url();
     306                        elseif ( !$user->has_cap('edit_posts') && ( empty( $redirect_to ) || $redirect_to == 'wp-admin/' || $redirect_to == admin_url() ) )
     307                                $redirect_to = admin_url('profile.php');
     308
     309                        wp_safe_redirect($redirect_to);
     310                        exit();
     311                }
     312
     313                $errors = $user;
     314                // Clear errors if loggedout is set.
     315                if ( !empty($_GET['loggedout']) || $reauth )
     316                        $errors = new WP_Error();
     317
     318                // If cookies are disabled we can't log in even with a valid user+pass
     319                if ( isset($_POST['testcookie']) && empty($_COOKIE[TEST_COOKIE]) )
     320                        $errors->add('test_cookie', __("<strong>ERROR</strong>: Cookies are blocked or not supported by your browser. You must <a href='http://www.google.com/cookies.html'>enable cookies</a> to use WordPress."));
     321
     322                // Some parts of this script use the main login form to display a message
     323                if      ( isset($_GET['loggedout']) && TRUE == $_GET['loggedout'] )
     324                        $errors->add('loggedout', __('You are now logged out.'), 'message');
     325                elseif  ( isset($_GET['registration']) && 'disabled' == $_GET['registration'] )
     326                        $errors->add('registerdisabled', __('User registration is currently not allowed.'));
     327                elseif  ( isset($_GET['checkemail']) && 'confirm' == $_GET['checkemail'] )
     328                        $errors->add('confirm', __('Check your e-mail for the confirmation link.'), 'message');
     329                elseif  ( isset($_GET['checkemail']) && 'newpass' == $_GET['checkemail'] )
     330                        $errors->add('newpass', __('Check your e-mail for your new password.'), 'message');
     331                elseif  ( isset($_GET['checkemail']) && 'registered' == $_GET['checkemail'] )
     332                        $errors->add('registered', __('Registration complete. Please check your e-mail.'), 'message');
     333                elseif  ( $interim_login )
     334                        $errors->add('expired', __('Your session has expired. Please log-in again.'), 'message');
     335
     336                // Clear any stale cookies.
     337                if ( $reauth )
     338                        wp_clear_auth_cookie();
     339
     340                if ( isset($_POST['log']) )
     341                        $user_login = ( 'incorrect_password' == $errors->get_error_code() || 'empty_password' == $errors->get_error_code() ) ? esc_attr(stripslashes($_POST['log'])) : '';
     342
     343                $rememberme = ! empty( $_POST['rememberme'] );
     344
     345                WP_Login::output_login_form_html( $user_login, $rememberme, $interim_login, $redirect_to, $errors);
     346        }
     347
     348        /**
     349         * Retrieves user password.
     350         *
     351         * @uses $wpdb WordPress Database object
     352         *
     353         * @return bool|WP_Error True: when finish. WP_Error on error
     354         */
     355        function do_retrieve_password() {
     356                global $wpdb, $current_site;
     357
     358                $errors = new WP_Error();
     359
     360                if ( empty( $_POST['user_login'] ) && empty( $_POST['user_email'] ) )
     361                        $errors->add('empty_username', __('<strong>ERROR</strong>: Enter a username or e-mail address.'));
     362
     363                if ( strpos($_POST['user_login'], '@') ) {
     364                        $user_data = get_user_by_email(trim($_POST['user_login']));
     365                        if ( empty($user_data) )
     366                                $errors->add('invalid_email', __('<strong>ERROR</strong>: There is no user registered with that email address.'));
     367                } else {
     368                        $login = trim($_POST['user_login']);
     369                        $user_data = get_userdatabylogin($login);
     370                }
     371
     372                do_action('lostpassword_post');
     373
     374                if ( $errors->get_error_code() )
     375                        return $errors;
     376
     377                if ( !$user_data ) {
     378                        $errors->add('invalidcombo', __('<strong>ERROR</strong>: Invalid username or e-mail.'));
     379                        return $errors;
     380                }
     381
     382                // redefining user_login ensures we return the right case in the email
     383                $user_login = $user_data->user_login;
     384                $user_email = $user_data->user_email;
     385
     386                do_action('retreive_password', $user_login);  // Misspelled and deprecated
     387                do_action('retrieve_password', $user_login);
     388
     389                $allow = apply_filters('allow_password_reset', true, $user_data->ID);
     390
     391                if ( ! $allow )
     392                        return new WP_Error('no_password_reset', __('Password reset is not allowed for this user'));
     393
     394                if ( is_wp_error($allow) )
     395                        return $allow;
     396
     397                $key = $wpdb->get_var($wpdb->prepare("SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $user_login));
     398                if ( empty($key) ) {
     399                        // Generate something random for a key...
     400                        $key = wp_generate_password(20, false);
     401                        do_action('retrieve_password_key', $user_login, $key);
     402                        // Now insert the new md5 key into the db
     403                        $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login));
     404                }
     405
     406                WP_Login::do_retrieve_password_email( $user_login, $user_email, $key );
     407
     408                return true;
     409        }
     410
     411        /**
     412         * Sends out the requested password retrieval email.
     413         *
     414         * @param string $user_login The user login
     415         * @param string $user_email Email address to send to
     416         * @param string $key Hash to include within the link
     417         */
     418        function do_retrieve_password_email( $user_login, $user_email, $key ) {
     419                $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
     420                $message .= network_site_url() . "\r\n\r\n";
     421                $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
     422                $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
     423                $message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
     424                $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . ">\r\n";
     425
     426                if ( is_multisite() )
     427                        $blogname = $GLOBALS['current_site']->site_name;
     428                else
     429                        // The blogname option is escaped with esc_html on the way into the database in sanitize_option
     430                        // we want to reverse this for the plain text arena of emails.
     431                        $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
     432
     433                $title = sprintf( __('[%s] Password Reset'), $blogname );
     434
     435                $title = apply_filters('retrieve_password_title', $title);
     436                $message = apply_filters('retrieve_password_message', $message, $key);
     437
     438                if ( $message && !wp_mail($user_email, $title, $message) )
     439                        wp_die( __('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function...') );
     440        }
     441
     442        /**
     443         * Retrieves a user row based on password reset key and login
     444         *
     445         * @uses $wpdb WordPress Database object
     446         *
     447         * @param string $key Hash to validate sending user's password
     448         * @param string $login The user login
     449         *
     450         * @return object|WP_Error
     451         */
     452        function do_check_password_reset_key($key, $login) {
     453                global $wpdb;
     454
     455                $key = preg_replace('/[^a-z0-9]/i', '', $key);
     456
     457                if ( empty( $key ) || !is_string( $key ) )
     458                        return new WP_Error('invalid_key', __('Invalid key'));
     459
     460                if ( empty($login) || !is_string($login) )
     461                        return new WP_Error('invalid_key', __('Invalid key'));
     462
     463                $user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_activation_key = %s AND user_login = %s", $key, $login));
     464
     465                if ( empty( $user ) )
     466                        return new WP_Error('invalid_key', __('Invalid key'));
     467
     468                return $user;
     469        }
     470
     471        /**
     472         * Handles resetting the user's password.
     473         *
     474         * @uses $wpdb WordPress Database object
     475         *
     476         * @param string $key Hash to validate sending user's password
     477         */
     478        function do_reset_password($user, $new_pass) {
     479                do_action('password_reset', $user, $new_pass);
     480
     481                wp_set_password($new_pass, $user->ID);
     482
     483                wp_password_change_notification($user);
     484        }
     485
     486        /**
     487         * Handles registering a new user.
     488         *
     489         * @param string $user_login User's username for logging in
     490         * @param string $user_email User's email address to send password and add
     491         * @return int|WP_Error Either user's ID or error on failure.
     492         */
     493        function do_register_new_user( $user_login, $user_email ) {
     494                $errors = new WP_Error();
     495
     496                $sanitized_user_login = sanitize_user( $user_login );
     497                $user_email = apply_filters( 'user_registration_email', $user_email );
     498
     499                // Check the username
     500                if ( $sanitized_user_login == '' ) {
     501                        $errors->add( 'empty_username', __( '<strong>ERROR</strong>: Please enter a username.' ) );
     502                } elseif ( ! validate_username( $user_login ) ) {
     503                        $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
     504                        $sanitized_user_login = '';
     505                } elseif ( username_exists( $sanitized_user_login ) ) {
     506                        $errors->add( 'username_exists', __( '<strong>ERROR</strong>: This username is already registered, please choose another one.' ) );
     507                }
     508
     509                // Check the e-mail address
     510                if ( $user_email == '' ) {
     511                        $errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please type your e-mail address.' ) );
     512                } elseif ( ! is_email( $user_email ) ) {
     513                        $errors->add( 'invalid_email', __( '<strong>ERROR</strong>: The email address isn&#8217;t correct.' ) );
     514                        $user_email = '';
     515                } elseif ( email_exists( $user_email ) ) {
     516                        $errors->add( 'email_exists', __( '<strong>ERROR</strong>: This email is already registered, please choose another one.' ) );
     517                }
     518
     519                do_action( 'register_post', $sanitized_user_login, $user_email, $errors );
     520
     521                $errors = apply_filters( 'registration_errors', $errors, $sanitized_user_login, $user_email );
     522
     523                if ( $errors->get_error_code() )
     524                        return $errors;
     525
     526                $user_pass = wp_generate_password( 12, false);
     527                $user_id = wp_create_user( $sanitized_user_login, $user_pass, $user_email );
     528                if ( ! $user_id ) {
     529                        $errors->add( 'registerfail', sprintf( __( '<strong>ERROR</strong>: Couldn&#8217;t register you... please contact the <a href="mailto:%s">webmaster</a> !' ), get_option( 'admin_email' ) ) );
     530                        return $errors;
     531                }
     532
     533                update_user_option( $user_id, 'default_password_nag', true, true ); //Set up the Password change nag.
     534
     535                wp_new_user_notification( $user_id, $user_pass );
     536
     537                return $user_id;
     538        }
     539
     540        /**
     541         * Redirects to the URL specified in the request.
     542         * Defaults to the URL passed in the first parameter.
     543         *
     544         * @param string $url The URL to redirect to in case there was no URL specified in the request.
     545         */
     546        function do_safe_redirect( $url ) {
     547                $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : $url;
     548                wp_safe_redirect( $redirect_to );
     549        }
     550
     551        /**
     552         * Outputs the header for the login page.
     553         *
     554         * @uses do_action() Calls the 'login_head' for outputting HTML in the Log In
     555         *              header.
     556         * @uses apply_filters() Calls 'login_headerurl' for the top login link.
     557         * @uses apply_filters() Calls 'login_headertitle' for the top login title.
     558         * @uses apply_filters() Calls 'login_message' on the message to display in the
     559         *              header.
     560         * @uses $error The error global, which is checked for displaying errors.
     561         *
     562         * @param string $title Optional. WordPress Log In Page title to display in
     563         *              <title/> element.
     564         * @param string $message Optional. Message to display in header.
     565         * @param WP_Error $wp_error Optional. WordPress Error Object
     566         */
     567        function output_page_header_html($title = 'Log In', $message = '', $wp_error = '') {
     568                global $error, $is_iphone, $interim_login, $current_site;
     569
     570                // Don't index any of these forms
     571                add_filter( 'pre_option_blog_public', '__return_zero' );
     572                add_action( 'login_head', 'noindex' );
     573
     574                if ( empty($wp_error) )
     575                        $wp_error = new WP_Error();
     576
     577                // Shake it!
     578                $shake_error_codes = array( 'empty_password', 'empty_email', 'invalid_email', 'invalidcombo', 'empty_username', 'invalid_username', 'incorrect_password' );
     579                $shake_error_codes = apply_filters( 'shake_error_codes', $shake_error_codes );
     580
     581                if ( $shake_error_codes && $wp_error->get_error_code() && in_array( $wp_error->get_error_code(), $shake_error_codes ) )
     582                        add_action( 'login_head', array('WP_Login', 'output_page_shake_js'), 12 );
     583
     584?>
     585<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     586<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
     587<head>
     588        <title><?php bloginfo('name'); ?> &rsaquo; <?php echo $title; ?></title>
     589        <meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
     590<?php
     591        wp_admin_css( 'login', true );
     592        wp_admin_css( 'colors-fresh', true );
     593
     594        if ( $is_iphone ) { ?>
     595        <meta name="viewport" content="width=320; initial-scale=0.9; maximum-scale=1.0; user-scalable=0;" />
     596        <style type="text/css" media="screen">
     597        form { margin-left: 0px; }
     598        #login { margin-top: 20px; }
     599        </style>
     600<?php
     601        } elseif ( isset($interim_login) && $interim_login ) { ?>
     602        <style type="text/css" media="all">
     603        .login #login { margin: 20px auto; }
     604        </style>
     605<?php
     606        }
     607
     608        do_action('login_head'); ?>
     609</head>
     610<body class="login">
     611<?php   if ( !is_multisite() ) { ?>
     612<div id="login"><h1><a href="<?php echo apply_filters('login_headerurl', 'http://wordpress.org/'); ?>" title="<?php echo apply_filters('login_headertitle', __('Powered by WordPress')); ?>"><?php bloginfo('name'); ?></a></h1>
     613<?php   } else { ?>
     614<div id="login"><h1><a href="<?php echo apply_filters('login_headerurl', network_home_url() ); ?>" title="<?php echo apply_filters('login_headertitle', $current_site->site_name ); ?>"><span class="hide"><?php bloginfo('name'); ?></span></a></h1>
     615<?php   }
     616
     617                $message = apply_filters('login_message', $message);
     618                if ( !empty( $message ) ) echo $message . "\n";
     619
     620                // Incase a plugin uses $error rather than the $errors object
     621                if ( !empty( $error ) ) {
     622                        $wp_error->add('error', $error);
     623                        unset($error);
     624                }
     625
     626                if ( $wp_error->get_error_code() ) {
     627                        $errors = '';
     628                        $messages = '';
     629                        foreach ( $wp_error->get_error_codes() as $code ) {
     630                                $severity = $wp_error->get_error_data($code);
     631                                foreach ( $wp_error->get_error_messages($code) as $error ) {
     632                                        if ( 'message' == $severity )
     633                                                $messages .= '  ' . $error . "<br />\n";
     634                                        else
     635                                                $errors .= '    ' . $error . "<br />\n";
     636                                }
     637                        }
     638                        if ( !empty($errors) )
     639                                echo '<div id="login_error">' . apply_filters('login_errors', $errors) . "</div>\n";
     640                        if ( !empty($messages) )
     641                                echo '<p class="message">' . apply_filters('login_messages', $messages) . "</p>\n";
     642                }
     643        }
     644
     645        /**
     646         *
     647         */
     648        function output_login_interim_html() {
     649                $message = '<p class="message">' . __('You have logged in successfully.') . '</p>';
     650                WP_Login::output_page_header_html( '', $message ); ?>
     651<script type="text/javascript">setTimeout( function(){window.close()}, 8000);</script>
     652<p class="alignright">
     653<input type="button" class="button-primary" value="<?php esc_attr_e('Close'); ?>" onclick="window.close()" /></p>
     654</div></body></html>
     655<?php
     656        }
     657
     658        /**
     659         * Renders the login form.
     660         *
     661         * @param string $user_login User name
     662         * @param $rememberme
     663         * @param $interim_login
     664         * @param string $redirect_to URL to redirect to.
     665         * @param WP_Error $errors Errors, if any.
     666         */
     667        function output_login_form_html( $user_login, $rememberme, $interim_login, $redirect_to, $errors ) {
     668                WP_Login::output_page_header_html(__('Log In'), '', $errors);
     669?>
     670
     671<form name="loginform" id="loginform" action="<?php echo site_url('wp-login.php', 'login_post') ?>" method="post">
     672        <p>
     673                <label><?php _e('Username') ?><br />
     674                <input type="text" name="log" id="user_login" class="input" value="<?php echo esc_attr($user_login); ?>" size="20" tabindex="10" /></label>
     675        </p>
     676        <p>
     677                <label><?php _e('Password') ?><br />
     678                <input type="password" name="pwd" id="user_pass" class="input" value="" size="20" tabindex="20" /></label>
     679        </p>
     680<?php do_action('login_form'); ?>
     681        <p class="forgetmenot"><label><input name="rememberme" type="checkbox" id="rememberme" value="forever" tabindex="90"<?php checked( $rememberme ); ?> /> <?php esc_attr_e('Remember Me'); ?></label></p>
     682        <p class="submit">
     683                <input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Log In'); ?>" tabindex="100" />
     684<?php   if ( $interim_login ) { ?>
     685                <input type="hidden" name="interim-login" value="1" />
     686<?php   } else { ?>
     687                <input type="hidden" name="redirect_to" value="<?php echo esc_attr($redirect_to); ?>" />
     688<?php   } ?>
     689                <input type="hidden" name="testcookie" value="1" />
     690        </p>
     691</form>
     692
     693<?php if ( !$interim_login ) { ?>
     694<p id="nav">
     695<?php if ( isset($_GET['checkemail']) && in_array( $_GET['checkemail'], array('confirm', 'newpass') ) ) : ?>
     696<?php elseif ( get_option('users_can_register') ) : ?>
     697<a href="<?php echo site_url('wp-login.php?action=register', 'login') ?>"><?php _e('Register') ?></a> |
     698<a href="<?php echo site_url('wp-login.php?action=lostpassword', 'login') ?>" title="<?php _e('Password Lost and Found') ?>"><?php _e('Lost your password?') ?></a>
     699<?php else : ?>
     700<a href="<?php echo site_url('wp-login.php?action=lostpassword', 'login') ?>" title="<?php _e('Password Lost and Found') ?>"><?php _e('Lost your password?') ?></a>
     701<?php endif; ?>
     702</p>
     703</div>
     704<p id="backtoblog"><a href="<?php bloginfo('url'); ?>/" title="<?php _e('Are you lost?') ?>"><?php printf(__('&larr; Back to %s'), get_bloginfo('title', 'display' )); ?></a></p>
     705<?php } else { ?>
     706</div>
     707<?php } ?>
     708
     709<script type="text/javascript">
     710function wp_attempt_focus(){
     711setTimeout( function(){ try{
     712<?php if ( $user_login || $interim_login ) { ?>
     713d = document.getElementById('user_pass');
     714d.value = '';
     715<?php } else { ?>
     716d = document.getElementById('user_login');
     717<?php if ( 'invalid_username' == $errors->get_error_code() ) { ?>
     718if( d.value != '' )
     719d.value = '';
     720<?php
     721}
     722}?>
     723d.focus();
     724d.select();
     725} catch(e){}
     726}, 200);
     727}
     728
     729<?php if ( !$error ) { ?>
     730wp_attempt_focus();
     731<?php } ?>
     732if(typeof wpOnload=='function')wpOnload();
     733</script>
     734<?php do_action( 'login_footer' ); ?>
     735</body>
     736</html>
     737<?php
     738        }
     739
     740        /**
     741         * Outputs the password retrieval form.
     742         *
     743         * @param string $user_login User name
     744         * @param WP_Error $errors Errors, if any.
     745         * @param $redirect_to URL to redirect to.
     746         */
     747        function output_lostpassword_form_html( $user_login, $errors, $redirect_to ) {
     748                WP_Login::output_page_header_html(__('Lost Password'), '<p class="message">' . __('Please enter your username or email address. You will receive a link to create a new password via email.') . '</p>', $errors);
     749?>
     750<form name="lostpasswordform" id="lostpasswordform" action="<?php echo site_url('wp-login.php?action=lostpassword', 'login_post') ?>" method="post">
     751        <p>
     752                <label><?php _e('Username or E-mail:') ?><br />
     753                <input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr($user_login); ?>" size="20" tabindex="10" /></label>
     754        </p>
     755<?php do_action('lostpassword_form'); ?>
     756        <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
     757        <p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Get New Password'); ?>" tabindex="100" /></p>
     758</form>
     759
     760<p id="nav">
     761<a href="<?php echo site_url('wp-login.php', 'login') ?>"><?php _e('Log in') ?></a>
     762<?php if (get_option('users_can_register')) : ?>
     763 | <a href="<?php echo site_url('wp-login.php?action=register', 'login') ?>"><?php _e('Register') ?></a>
     764<?php endif; ?>
     765</p>
     766
     767<?php
     768                WP_Login::output_page_footer_html('user_login');
     769        }
     770
     771        /**
     772         * Outputs the password successfully changed message.
     773         */
     774        function output_resetpass_completed_html() {
     775                WP_Login::output_page_header_html(__('Password Reset'), '<p class="message reset-pass">' . __('Your password has been reset.') . ' <a href="' . site_url('wp-login.php', 'login') . '">' . __('Log in') . '</a></p>');
     776                WP_Login::output_page_footer_html();
     777        }
     778
     779        /**
     780         * Outputs the password change form.
     781         *
     782         * @param WP_Error $errors Errors, if any.
     783         */
     784        function output_resetpass_form_html( $errors ) {
     785                WP_Login::output_page_header_html(__('Reset Password'), '<p class="message reset-pass">' . __('Enter your new password below.') . '</p>', $errors );
     786?>
     787<form name="resetpassform" id="resetpassform" action="<?php echo site_url('wp-login.php?action=resetpass&key=' . urlencode($_GET['key']) . '&login=' . urlencode($_GET['login']), 'login_post') ?>" method="post">
     788        <input type="hidden" id="user_login" value="<?php echo esc_attr( $_GET['login'] ); ?>" autocomplete="off" />
     789
     790        <p>
     791                <label><?php _e('New password') ?><br />
     792                <input type="password" name="pass1" id="pass1" class="input" size="20" value="" autocomplete="off" /></label>
     793        </p>
     794        <p>
     795                <label><?php _e('Confirm new password') ?><br />
     796                <input type="password" name="pass2" id="pass2" class="input" size="20" value="" autocomplete="off" /></label>
     797        </p>
     798
     799        <div id="pass-strength-result" class="hide-if-no-js"><?php _e('Strength indicator'); ?></div>
     800        <p class="description indicator-hint"><?php _e('Hint: The password should be at least seven characters long. To make it stronger, use upper and lower case letters, numbers and symbols like ! " ? $ % ^ &amp; ).'); ?></p>
     801
     802        <br class="clear" />
     803        <p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Reset Password'); ?>" tabindex="100" /></p>
     804</form>
     805
     806<p id="nav">
     807<a href="<?php echo site_url('wp-login.php', 'login') ?>"><?php _e('Log in') ?></a>
     808<?php if (get_option('users_can_register')) : ?>
     809 | <a href="<?php echo site_url('wp-login.php?action=register', 'login') ?>"><?php _e('Register') ?></a>
     810<?php endif; ?>
     811</p>
     812
     813<?php
     814                WP_Login::output_page_footer_html('user_pass');
     815        }
     816
     817        /**
     818         * Outputs the registration form.
     819         *
     820         * @param string $user_login User name
     821         * @param string $user_email User email
     822         * @param string $redirect_to URL to redirect to after login.
     823         * @param WP_Error $errors Errors, if any.
     824         */
     825        function output_register_form_html( $user_login, $user_email, $redirect_to, $errors ) {
     826                WP_Login::output_page_header_html(__('Registration Form'), '<p class="message register">' . __('Register For This Site') . '</p>', $errors);
     827?>
     828
     829<form name="registerform" id="registerform" action="<?php echo site_url('wp-login.php?action=register', 'login_post') ?>" method="post">
     830        <p>
     831                <label><?php _e('Username') ?><br />
     832                <input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr(stripslashes($user_login)); ?>" size="20" tabindex="10" /></label>
     833        </p>
     834        <p>
     835                <label><?php _e('E-mail') ?><br />
     836                <input type="text" name="user_email" id="user_email" class="input" value="<?php echo esc_attr(stripslashes($user_email)); ?>" size="25" tabindex="20" /></label>
     837        </p>
     838<?php do_action('register_form'); ?>
     839        <p id="reg_passmail"><?php _e('A password will be e-mailed to you.') ?></p>
     840        <br class="clear" />
     841        <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
     842        <p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Register'); ?>" tabindex="100" /></p>
     843</form>
     844
     845<p id="nav">
     846<a href="<?php echo site_url('wp-login.php', 'login') ?>"><?php _e('Log in') ?></a> |
     847<a href="<?php echo site_url('wp-login.php?action=lostpassword', 'login') ?>" title="<?php _e('Password Lost and Found') ?>"><?php _e('Lost your password?') ?></a>
     848</p>
     849
     850<?php
     851                WP_Login::output_page_footer_html('user_login');
     852        }
     853
     854        /**
     855         * Outputs the footer for the login page.
     856         *
     857         * @param string $input_id Which input to auto-focus
     858         */
     859        function output_page_footer_html( $input_id = '' ) {
     860                echo "</div>\n";
     861
     862                if ( !empty($input_id) ) {
     863        ?>
     864<script type="text/javascript">
     865try{document.getElementById('<?php echo $input_id; ?>').focus();}catch(e){}
     866if(typeof wpOnload=='function')wpOnload();
     867</script>
     868<?php
     869        }
     870?>
     871<p id="backtoblog"><a href="<?php bloginfo('url'); ?>/" title="<?php _e('Are you lost?') ?>"><?php printf(__('&larr; Back to %s'), get_bloginfo('title', 'display' )); ?></a></p>
     872<?php do_action('login_footer'); ?>
     873</body>
     874</html>
     875        <?php
     876        }
     877
     878        /**
     879         * Shakes the entire page for the user to see there was an error.
     880         */
     881        function output_page_shake_js() {
     882                global $is_iphone;
     883                if ( $is_iphone )
     884                        return;
     885        ?>
     886<script type="text/javascript">
     887addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
     888function s(id,pos){g(id).left=pos+'px';}
     889function g(id){return document.getElementById(id).style;}
     890function shake(id,a,d){c=a.shift();s(id,c);if(a.length>0){setTimeout(function(){shake(id,a,d);},d);}else{try{g(id).position='static';wp_attempt_focus();}catch(e){}}}
     891addLoadEvent(function(){ var p=new Array(15,30,15,0,-15,-30,-15,0);p=p.concat(p.concat(p));var i=document.forms[0].id;g(i).position='relative';shake(i,p,20);});
     892</script>
     893        <?php
     894        }
     895}
     896?>
     897 No newline at end of file