¿Cómo editar un perfil de usuario en el front-end?
¿Cómo puedo editar un perfil de usuario en el front-end usando un formulario?
nombre, apellido, nombre de usuario, dirección de correo electrónico y contraseña

Puedes hacerlo copiando el archivo page.php de tu tema a un nuevo archivo llamado algo como user-profile.php y agregar al inicio el siguiente código:
<?php
/**
* Template Name: Perfil de Usuario
*
* Permite a los usuarios actualizar sus perfiles desde el Frontend.
*
*/
/* Obtener información del usuario. */
global $current_user, $wp_roles;
//get_currentuserinfo(); //obsoleto desde la versión 3.1
/* Cargar archivo de registro. */
//require_once( ABSPATH . WPINC . '/registration.php' ); //obsoleto desde la versión 3.1
$error = array();
/* Si el perfil fue guardado, actualizar perfil. */
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == 'update-user' ) {
/* Actualizar contraseña del usuario. */
if ( !empty($_POST['pass1'] ) && !empty( $_POST['pass2'] ) ) {
if ( $_POST['pass1'] == $_POST['pass2'] )
wp_update_user( array( 'ID' => $current_user->ID, 'user_pass' => esc_attr( $_POST['pass1'] ) ) );
else
$error[] = __('Las contraseñas que ingresaste no coinciden. Tu contraseña no fue actualizada.', 'profile');
}
/* Actualizar información del usuario. */
if ( !empty( $_POST['url'] ) )
wp_update_user( array( 'ID' => $current_user->ID, 'user_url' => esc_url( $_POST['url'] ) ) );
if ( !empty( $_POST['email'] ) ){
if (!is_email(esc_attr( $_POST['email'] )))
$error[] = __('El correo electrónico que ingresaste no es válido. Por favor, inténtalo de nuevo.', 'profile');
elseif(email_exists(esc_attr( $_POST['email'] )) != $current_user->ID )
$error[] = __('Este correo electrónico ya está siendo utilizado por otro usuario. Prueba con uno diferente.', 'profile');
else{
wp_update_user( array ('ID' => $current_user->ID, 'user_email' => esc_attr( $_POST['email'] )));
}
}
if ( !empty( $_POST['first-name'] ) )
update_user_meta( $current_user->ID, 'first_name', esc_attr( $_POST['first-name'] ) );
if ( !empty( $_POST['last-name'] ) )
update_user_meta($current_user->ID, 'last_name', esc_attr( $_POST['last-name'] ) );
if ( !empty( $_POST['description'] ) )
update_user_meta( $current_user->ID, 'description', esc_attr( $_POST['description'] ) );
/* Redirigir para que la página muestre la información actualizada.*/
/*No soy el autor de este código - No sé por qué pero funcionó para mí después de cambiar la siguiente línea a if ( count($error) == 0 ){ */
if ( count($error) == 0 ) {
//acción para plugins y guardado de campos adicionales
do_action('edit_user_profile_update', $current_user->ID);
wp_redirect( get_permalink() );
exit;
}
}
?>
luego reemplaza el loop de esa página con este:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<div id="post-<?php the_ID(); ?>">
<div class="entry-content entry">
<?php the_content(); ?>
<?php if ( !is_user_logged_in() ) : ?>
<p class="warning">
<?php _e('Debes iniciar sesión para editar tu perfil.', 'profile'); ?>
</p><!-- .warning -->
<?php else : ?>
<?php if ( count($error) > 0 ) echo '<p class="error">' . implode("<br />", $error) . '</p>'; ?>
<form method="post" id="adduser" action="<?php the_permalink(); ?>">
<p class="form-username">
<label for="first-name"><?php _e('Nombre', 'profile'); ?></label>
<input class="text-input" name="first-name" type="text" id="first-name" value="<?php the_author_meta( 'first_name', $current_user->ID ); ?>" />
</p><!-- .form-username -->
<p class="form-username">
<label for="last-name"><?php _e('Apellido', 'profile'); ?></label>
<input class="text-input" name="last-name" type="text" id="last-name" value="<?php the_author_meta( 'last_name', $current_user->ID ); ?>" />
</p><!-- .form-username -->
<p class="form-email">
<label for="email"><?php _e('Correo electrónico *', 'profile'); ?></label>
<input class="text-input" name="email" type="text" id="email" value="<?php the_author_meta( 'user_email', $current_user->ID ); ?>" />
</p><!-- .form-email -->
<p class="form-url">
<label for="url"><?php _e('Sitio web', 'profile'); ?></label>
<input class="text-input" name="url" type="text" id="url" value="<?php the_author_meta( 'user_url', $current_user->ID ); ?>" />
</p><!-- .form-url -->
<p class="form-password">
<label for="pass1"><?php _e('Contraseña *', 'profile'); ?> </label>
<input class="text-input" name="pass1" type="password" id="pass1" />
</p><!-- .form-password -->
<p class="form-password">
<label for="pass2"><?php _e('Repetir contraseña *', 'profile'); ?></label>
<input class="text-input" name="pass2" type="password" id="pass2" />
</p><!-- .form-password -->
<p class="form-textarea">
<label for="description"><?php _e('Información biográfica', 'profile') ?></label>
<textarea name="description" id="description" rows="3" cols="50"><?php the_author_meta( 'description', $current_user->ID ); ?></textarea>
</p><!-- .form-textarea -->
<?php
//acción para plugin y campos adicionales
do_action('edit_user_profile',$current_user);
?>
<p class="form-submit">
<?php //echo $referer; ?>
<input name="updateuser" type="submit" id="updateuser" class="submit button" value="<?php _e('Actualizar', 'profile'); ?>" />
<?php wp_nonce_field( 'update-user' ) ?>
<input name="action" type="hidden" id="action" value="update-user" />
</p><!-- .form-submit -->
</form><!-- #adduser -->
<?php endif; ?>
</div><!-- .entry-content -->
</div><!-- .hentry .post -->
<?php endwhile; ?>
<?php else: ?>
<p class="no-data">
<?php _e('Lo sentimos, ninguna página coincide con tus criterios.', 'profile'); ?>
</p><!-- .no-data -->
<?php endif; ?>
y todo lo que queda por hacer es crear una nueva página y seleccionar "Perfil de Usuario" como la plantilla de página.
Ahora, si todo esto es demasiado, puedes usar algunos plugins que hacen el trabajo duro por ti como:

¡Tu respuesta funcionó muy bien para mí! ¿Podría usar un método similar para editar una publicación existente? Mira mi pregunta aquí: http://wordpress.stackexchange.com/questions/9912/front-end-post-editing-using-a-form

¿este método funciona también con campos personalizados en el formulario de registro?

Gracias por esto, funciona genial. ¿Cómo podría agregar un mensaje que aparezca después de que el perfil se haya actualizado correctamente? Actualmente no hace nada.

Creo que lo tengo funcionando, ¿es aceptable? Modifiqué tu código para que quedara:
if ( !$error ) {
wp_redirect( get_permalink() .'?updated=true' );
exit;
}
y luego añadí <?php if ( $_GET['updated'] == 'true' ) : ?> <p>Tu perfil ha sido actualizado</p> <?php endif; ?>

Gracias por esto, sin embargo, el correo no se actualiza y tampoco el sitio web. Los otros campos sí se actualizan. ¿Se te ocurre alguna razón por la que esto pueda estar pasando? Gracias.

@Nicola, tuve el mismo problema. Es porque el correo y la URL del sitio web no son metadatos de usuario; se almacenan en la tabla wp_users
(frente a la tabla wp_usermeta
). Para actualizar el correo y la URL, necesitas usar wp_update_user()
, en lugar de update_usermeta()
.

Parece que esto no está verificando direcciones de correo electrónico duplicadas, lo que puede causar problemas como en mi caso donde permito que los usuarios inicien sesión mediante correo electrónico.

Es un ejemplo que puedes editar y agregar tus propias verificaciones

@BandonRandon Actualicé el código con una validación simple de correo electrónico, verificación de duplicados y agregué algunos action hooks que WordPress utiliza para permitir la integración de plugins. Gracias

Increíble, ya he empezado a modificar esto y funciona bastante bien. Solo para señalar lo que otros han mencionado, el correo electrónico usa wp_update_user
no update_usermeta
pero eso es un arreglo fácil

Por favor lee esto @Bainternet. No me sorprendió cuando llegué al final y vi tu avatar

Error: registration.php está obsoleto desde la versión 3.1 sin alternativa disponible. Este archivo ya no necesita ser incluido.

No es recomendable, siempre debes validar la solicitud con tantos métodos como puedas, y este es solo uno de ellos.

@Bainternet gracias por el fragmento de código. Edité algunas correcciones y comenté algunas líneas obsoletas.

Usamos la versión PRO de ProfilePress (https://profilepress.net) para editar el perfil desde el front-end y no podríamos estar más contentos con ello.

esta variable $referer está siempre sola en el código. Supongo que por eso no me redirige después de la actualización.

He utilizado este código para que mis usuarios invitados puedan cambiar solo su Nombre para Mostrar, pueden recuperar los campos requeridos, pero no pueden guardar. Adjunto está el archivo PHP en pastebin:https://pastebin.com/4sXXu8MU
