1. Code
  2. WordPress
  3. Plugin Development

Cómo crear un plugin de administración de avatares de WordPress: Toques finales

Scroll to top
This post is part of a series called How to Create a WordPress Avatar Management Plugin from Scratch.
How to Create a WordPress Avatar Management Plugin from Scratch: Getting Started

Spanish (Español) translation by Eva Collados Pascual (you can also view the original English article)

Avatar Manager para WordPress es un plugin sencillo y agradable que almacena fácilmente avatares de forma local y mucho más.

Mejora tu sitio web de WordPress permitiendo que tus usuarios elijan entre usar Gravatar o una imagen de avatar autoalojada directamente desde la pantalla Tu perfil. Flujo de trabajo mejorado, generación de imágenes a petición y permisos de usuario personalizados en una interfaz nativa. Dá la bienvenida al plugin Avatar Manager.


Una rápida recapitulación

En la primera parte de nuestro tutorial, revisamos lo siguiente:

  • qué es un plugin de WordPress;
  • cómo crear un plugin básico de WordPress, y cómo elegir una licencia y un formato apropiados para el número de versión;
  • qué son los ganchos de acción y filtro y cómo usarlos para crear nuestro plugin;
  • cómo añadir nuevos ajustes a las pantallas de configuración existentes;
  • cómo hacer que un plugin sea más flexible mediante el uso de opciones personalizadas.

Hoy, llevaremos las cosas más allá y terminaremos nuestro plugin: gestionaremos las cargas de avatares y la generación de imágenes bajo demanda, internacionalizaremos nuestro plugin y mucho más.


Paso 1. Cambiar el tamaño de una imagen de avatar

Comencemos escribiendo la siguiente función:

1
/**

2
 * Generates a resized copy of the specified avatar image.

3
 *

4
 * @uses wp_upload_dir() For retrieving path information on the currently

5
 * configured uploads directory.

6
 * @uses wp_basename() For i18n friendly version of basename().

7
 * @uses wp_get_image_editor() For retrieving a WP_Image_Editor instance and

8
 * loading a file into it.

9
 * @uses is_wp_error() For checking whether the passed variable is a WordPress

10
 * Error.

11
 * @uses do_action() For calling the functions added to an action hook.

12
 *

13
 * @since Avatar Manager 1.0.0

14
 *

15
 * @param string $url URL of the avatar image to resize.

16
 * @param int $size Size of the new avatar image.

17
 * @return array Array with the URL of the new avatar image.

18
 */
19
function avatar_manager_avatar_resize( $url, $size ) {
20
	// Retrieves path information on the currently configured uploads directory.

21
	$upload_dir = wp_upload_dir();
22
23
	$filename  = str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $url );
24
	$pathinfo  = pathinfo( $filename );
25
	$dirname   = $pathinfo['dirname'];
26
	$extension = $pathinfo['extension'];
27
28
	// i18n friendly version of basename().

29
	$basename = wp_basename( $filename, '.' . $extension );
30
31
	$suffix    = $size . 'x' . $size;
32
	$dest_path = $dirname . '/' . $basename . '-' . $suffix . '.' . $extension;
33
	$avatar    = array();
34
35
	if ( file_exists( $dest_path ) ) {
36
		$avatar['url']  = str_replace( $upload_dir['basedir'], $upload_dir['baseurl'], $dest_path );
37
		$avatar['skip'] = true;
38
	} else {
39
		// Retrieves a WP_Image_Editor instance and loads a file into it.

40
		$image = wp_get_image_editor( $filename );
41
42
		if ( ! is_wp_error( $image ) ) {
43
			// Resizes current image.

44
			$image->resize( $size, $size, true );
45
46
			// Saves current image to file.

47
			$image->save( $dest_path );
48
49
			$avatar['url']  = str_replace( $upload_dir['basedir'], $upload_dir['baseurl'], $dest_path );
50
			$avatar['skip'] = false;
51
		}
52
	}
53
54
	// Calls the functions added to avatar_manager_avatar_resize action hook.

55
	do_action( 'avatar_manager_avatar_resize', $url, $size );
56
57
	return $avatar;
58
}

Resumen

  • La función avatar_manager_avatar_resize() genera una copia redimensionada de la imagen de avatar especificada.
  • La llamada wp_upload_dir() devuelve una matriz que contiene información sobre la ruta de acceso en el directorio de cargas actualmente configurado.
  • La función str_replace() sustituye todas las instancias de la cadena de búsqueda por la cadena de reemplazo.
  • La función pathinfo() devuelve información sobre una ruta de acceso al archivo.
  • La función wp_basename() es la versión i18n amigable de basename() que devuelve el componente final del nombre de una ruta de acceso.
  • La función file_exists() comprueba si existe un archivo o directorio.
  • El indicador skip se establece en true si el archivo de imagen de destino ya existe, de lo contrario se genera una nueva imagen.
  • La función wp_get_image_editor() devuelve una instancia WP_Image_Editor y carga un archivo en ella. Con eso podemos manipular la imagen llamando a métodos en ella.
  • La función is_wp_error() comprueba si la variable pasada es un error de WordPress.
  • Luego, cambiamos el tamaño y guardamos la imagen llamando a los métodos resize() y save() del objeto $image.
  • do_action() ejecuta un gancho creado por add_action(); esto permite que los temas y plugins se conecten a la acción avatar_manager_avatar_resize que se activa después de cambiar el tamaño de una imagen de avatar.

Paso 2. Eliminar una imagen de avatar

Antes de encargarnos de las actualizaciones de perfil, tenemos que definir una función más:

1
/**

2
 * Deletes an avatar image based on attachment ID.

3
 *

4
 * @uses get_post_meta() For retrieving attachment meta fields.

5
 * @uses wp_upload_dir() For retrieving path information on the currently

6
 * configured uploads directory.

7
 * @uses delete_post_meta() For deleting attachment meta fields.

8
 * @uses get_users() For retrieving an array of users.

9
 * @uses delete_user_meta() For deleting user meta fields.

10
 * @uses do_action() For calling the functions added to an action hook.

11
 *

12
 * @since Avatar Manager 1.0.0

13
 *

14
 * @param int $attachment_id An attachment ID

15
 */
16
function avatar_manager_delete_avatar( $attachment_id ) {
17
	// Retrieves attachment meta field based on attachment ID.

18
	$is_custom_avatar = get_post_meta( $attachment_id, '_avatar_manager_is_custom_avatar', true );
19
20
	if ( ! $is_custom_avatar )
21
		return;
22
23
	// Retrieves path information on the currently configured uploads directory.

24
	$upload_dir = wp_upload_dir();
25
26
	// Retrieves attachment meta field based on attachment ID.

27
	$custom_avatar = get_post_meta( $attachment_id, '_avatar_manager_custom_avatar', true );
28
29
	if ( is_array( $custom_avatar ) ) {
30
		foreach ( $custom_avatar as $file ) {
31
			if ( ! $file['skip'] ) {
32
				$file = str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $file['url'] );
33
				@unlink( $file );
34
			}
35
		}
36
	}
37
38
	// Deletes attachment meta fields based on attachment ID.

39
	delete_post_meta( $attachment_id, '_avatar_manager_custom_avatar' );
40
	delete_post_meta( $attachment_id, '_avatar_manager_custom_avatar_rating' );
41
	delete_post_meta( $attachment_id, '_avatar_manager_is_custom_avatar' );
42
43
	// An associative array with criteria to match.

44
	$args = array(
45
		'meta_key'   => 'avatar_manager_custom_avatar',
46
		'meta_value' => $attachment_id
47
	);
48
49
	// Retrieves an array of users matching the criteria given in $args.

50
	$users = get_users( $args );
51
52
	foreach ( $users as $user ) {
53
		// Deletes user meta fields based on user ID.

54
		delete_user_meta( $user->ID, 'avatar_manager_avatar_type' );
55
		delete_user_meta( $user->ID, 'avatar_manager_custom_avatar' );
56
	}
57
58
	// Calls the functions added to avatar_manager_delete_avatar action hook.

59
	do_action( 'avatar_manager_delete_avatar', $attachment_id );
60
}
61
62
add_action( 'delete_attachment', 'avatar_manager_delete_avatar' );

Resumen

  • Se invoca al enlace de acción delete_attachment cuando wp_delete_attachment() elimina un archivo adjunto.
  • get_post_meta() devuelve los valores de los campos personalizados con la clave especificada de la entrada especificado. En primer lugar, comprobamos si el archivo adjunto con el ID especificado es una imagen de avatar.
  • La llamada is_array() descubre si una variable es una matriz.
  • A continuación, usamos la función unlink() para eliminar la imagen del avatar, incluidas sus copias redimensionadas, pero omitiendo aquellas con la marca skip establecida en true.
  • La función delete_post_meta() elimina todos los campos personalizados con la clave especificada de la entrada especificada.
  • La función get_users() recupera una matriz de usuarios que coinciden con los criterios indicados en $args.
  • La función delete_user_meta() elimina los criterios de coincidencia de metadatos de un usuario.
  • Por último, ejecutamos el gancho de acción avatar_manager_delete_avatar.

Paso 3. Actualizar un perfil de usuario

Al actualizar un perfil de usuario, no solo necesitamos guardar las opciones modificadas por el usuario, sino también gestionar las cargas y las eliminaciones de avatares. Hagámoslo:

1
/**

2
 * Updates user profile based on user ID.

3
 *

4
 * @uses avatar_manager_get_options() For retrieving plugin options.

5
 * @uses sanitize_text_field() For sanitizing a string from user input or from

6
 * the database.

7
 * @uses update_user_meta() For updating user meta fields.

8
 * @uses get_user_meta() For retrieving user meta fields.

9
 * @uses update_post_meta() For updating attachment meta fields.

10
 * @uses wp_handle_upload() For handling PHP uploads in WordPress.

11
 * @uses wp_die() For killing WordPress execution and displaying HTML error

12
 * message.

13
 * @uses __() For retrieving the translated string from the translate().

14
 * @uses avatar_manager_delete_avatar() For deleting an avatar image.

15
 * @uses wp_insert_attachment() For inserting an attachment into the media

16
 * library.

17
 * @uses wp_generate_attachment_metadata() For generating metadata for an

18
 * attachment.

19
 * @uses wp_update_attachment_metadata() For updating metadata for an

20
 * attachment.

21
 * @uses avatar_manager_avatar_resize() For generating a resized copy of the

22
 * specified avatar image.

23
 * @uses avatar_manager_delete_avatar() For deleting an avatar image based on

24
 * attachment ID.

25
 * @uses get_edit_user_link() For getting the link to the users edit profile

26
 * page in the WordPress admin.

27
 * @uses add_query_arg() For retrieving a modified URL (with) query string.

28
 * @uses wp_redirect() For redirecting the user to a specified absolute URI.

29
 *

30
 * @since Avatar Manager 1.0.0

31
 *

32
 * @param int $user_id User to update.

33
 */
34
function avatar_manager_edit_user_profile_update( $user_id ) {
35
	// Retrieves plugin options.

36
	$options = avatar_manager_get_options();
37
38
	// Sanitizes the string from user input.

39
	$avatar_type = isset( $_POST['avatar_manager_avatar_type'] ) ? sanitize_text_field( $_POST['avatar_manager_avatar_type'] ) : 'gravatar';
40
41
	// Updates user meta field based on user ID.

42
	update_user_meta( $user_id, 'avatar_manager_avatar_type', $avatar_type );
43
44
	// Retrieves user meta field based on user ID.

45
	$custom_avatar = get_user_meta( $user_id, 'avatar_manager_custom_avatar', true );
46
47
	if ( ! empty( $custom_avatar ) ) {
48
		// Sanitizes the string from user input.

49
		$custom_avatar_rating = isset( $_POST['avatar_manager_custom_avatar_rating'] ) ? sanitize_text_field( $_POST['avatar_manager_custom_avatar_rating'] ) : 'G';
50
51
		// Updates attachment meta field based on attachment ID.

52
		update_post_meta( $custom_avatar, '_avatar_manager_custom_avatar_rating', $custom_avatar_rating );
53
	}
54
55
	...
56
}
57
58
add_action( 'edit_user_profile_update', 'avatar_manager_edit_user_profile_update' );
59
add_action( 'personal_options_update', 'avatar_manager_edit_user_profile_update' );

Resumen

  • Las acciones edit_user_profile_update y personal_options_update se utilizan generalmente para guardar campos personalizados que se han añadido a la página de perfil de WordPress.
  • La función sanitize_text_field() desinfecta una cadena a partir de la entrada del usuario o de la base de datos.
  • La función update_user_meta() actualiza el campo meta del usuario en función del ID de usuario, mientras que get_user_meta() recupera un único campo meta o todos los campos de metadatos del usuario para un usuario dado.
  • La función update_post_meta() actualiza el valor de una clave meta existente (campo personalizado) para la entrada especificada.

Gestionar las cargas de avatares

Para controlar las cargas de avatares, escribe el siguiente código:

1
if ( isset( $_POST['avatar-manager-upload-avatar'] ) && $_POST['avatar-manager-upload-avatar'] ) {
2
	if ( ! function_exists( 'wp_handle_upload' ) )
3
		require_once( ABSPATH . 'wp-admin/includes/file.php' );
4
5
	// An associative array with allowed MIME types.

6
	$mimes = array(
7
		'bmp'  => 'image/bmp',
8
		'gif'  => 'image/gif',
9
		'jpe'  => 'image/jpeg',
10
		'jpeg' => 'image/jpeg',
11
		'jpg'  => 'image/jpeg',
12
		'png'  => 'image/png',
13
		'tif'  => 'image/tiff',
14
		'tiff' => 'image/tiff'
15
	);
16
17
	// An associative array to override default variables.

18
	$overrides = array(
19
		'mimes'     => $mimes,
20
		'test_form' => false
21
	);
22
23
	// Handles PHP uploads in WordPress.

24
	$avatar = wp_handle_upload( $_FILES['avatar_manager_import'], $overrides );
25
26
	if ( isset( $avatar['error'] ) )
27
		// Kills WordPress execution and displays HTML error message.

28
		wp_die( $avatar['error'],  __( 'Image Upload Error', 'avatar-manager' ) );
29
30
	if ( ! empty( $custom_avatar ) )
31
		// Deletes users old avatar image.

32
		avatar_manager_delete_avatar( $custom_avatar );
33
34
	// An associative array about the attachment.

35
	$attachment = array(
36
		'guid'           => $avatar['url'],
37
		'post_content'   => $avatar['url'],
38
		'post_mime_type' => $avatar['type'],
39
		'post_title'     => basename( $avatar['file'] )
40
	);
41
42
	// Inserts the attachment into the media library.

43
	$attachment_id = wp_insert_attachment( $attachment, $avatar['file'] );
44
45
	// Generates metadata for the attachment.

46
	$attachment_metadata = wp_generate_attachment_metadata( $attachment_id, $avatar['file'] );
47
48
	// Updates metadata for the attachment.

49
	wp_update_attachment_metadata( $attachment_id, $attachment_metadata );
50
51
	$custom_avatar = array();
52
53
	// Generates a resized copy of the avatar image.

54
	$custom_avatar[ $options['default_size'] ] = avatar_manager_avatar_resize( $avatar['url'], $options['default_size'] );
55
56
	// Updates attachment meta fields based on attachment ID.

57
	update_post_meta( $attachment_id, '_avatar_manager_custom_avatar', $custom_avatar );
58
	update_post_meta( $attachment_id, '_avatar_manager_custom_avatar_rating', 'G' );
59
	update_post_meta( $attachment_id, '_avatar_manager_is_custom_avatar', true );
60
61
	// Updates user meta fields based on user ID.

62
	update_user_meta( $user_id, 'avatar_manager_avatar_type', 'custom' );
63
	update_user_meta( $user_id, 'avatar_manager_custom_avatar', $attachment_id );
64
}

Resumen

  • function_exists() devuelve true si se ha definido la función dada, la instrucción require_once() comprueba si el archivo especificado ya ha sido incluido y, si es así, no lo vuelve a incluir.
  • La función wp_handle_upload() maneja las cargas de PHP en WordPress, desinfectando nombres de archivos, comprobando extensiones para el tipo mime y moviendo el archivo al directorio apropiado dentro del directorio uploads.
  • Antes de añadir la nueva imagen de avatar, llamamos a la función avatar_manager_delete_avatar() para eliminar el antiguo avatar, si hay alguno establecido.
  • La función wp_insert_attachment() inserta un archivo adjunto en la biblioteca multimedia.
  • La función wp_generate_attachment_metadata() genera metadatos para un archivo adjunto de imagen; también crea una miniatura y otros tamaños intermedios del archivo adjunto de imagen en función de los tamaños definidos en la Pantalla de configuración de medios.
  • La función wp_update_attachment_metadata() actualiza los metadatos de un archivo adjunto.
  • A continuación, llamamos a la función avatar_manager_avatar_resize() para generar una copia de la imagen del avatar con el tamaño predeterminado.
  • Por último, actualizamos los metadatos para el archivo adjunto y para el usuario que se esté editando actualmente.

Eliminar una imagen de avatar

Ahora, es el momento de hacer que el plugin elimine realmente una imagen de avatar cuando le sea solicitado:

1
if ( isset( $_GET['avatar_manager_action'] ) && $_GET['avatar_manager_action'] ) {
2
	global $wp_http_referer;
3
4
	$action = $_GET['avatar_manager_action'];
5
6
	switch ( $action ) {
7
		case 'remove-avatar':
8
			// Deletes avatar image based on attachment ID.

9
			avatar_manager_delete_avatar( $_GET['avatar_manager_custom_avatar'] );
10
11
			break;
12
	}
13
14
	// Gets the link to the users edit profile page in the WordPress admin.

15
	$edit_user_link = get_edit_user_link( $user_id );
16
17
	// Retrieves a modified URL (with) query string.

18
	$redirect = add_query_arg( 'updated', true, $edit_user_link );
19
20
	if ( $wp_http_referer )
21
		// Retrieves a modified URL (with) query string.

22
		$redirect = add_query_arg( 'wp_http_referer', urlencode( $wp_http_referer ), $redirect );
23
24
	// Redirects the user to a specified absolute URI.

25
	wp_redirect( $redirect );
26
27
	exit;
28
}

Resumen

  • Si el valor de la acción solicitada es remove-avatar llamamos a avatar_manager_delete_avatar() para eliminar la imagen de avatar especificada.
  • La función get_edit_user_link() obtiene el enlace a la página de edición de perfil de los usuarios en el escritorio de WordPress.
  • La función urlencode() codifica una cadena que se utilizará en una parte de la consulta de una URL.
  • Al final de la función, llamamos a la función wp_redirect() para redirigir al usuario de nuevo al perfil de usuario actualizado.
  • La llamada exit termina la ejecución del script; es una construcción de lenguaje y se puede llamar sin paréntesis si no se pasa ningún status.

Paso 4. Recuperar una imagen de avatar personalizada

A continuación, vamos a escribir una función auxiliar para recuperar una imagen de avatar personalizada:

1
/**

2
 * Returns user custom avatar based on user ID.

3
 *

4
 * @uses get_option() For getting values for a named option.

5
 * @uses avatar_manager_get_options() For retrieving plugin options.

6
 * @uses get_userdata() For retrieving user data by user ID.

7
 * @uses is_ssl() For checking if SSL is being used.

8
 * @uses add_query_arg() For retrieving a modified URL (with) query string.

9
 * @uses esc_attr() For escaping HTML attributes.

10
 * @uses get_user_meta() For retrieving user meta fields.

11
 * @uses get_post_meta() For retrieving attachment meta fields.

12
 * @uses wp_get_attachment_image_src() For retrieving an array with the image

13
 * attributes "url", "width" and "height", of an image attachment file.

14
 * @uses avatar_manager_avatar_resize() For generating a resized copy of the

15
 * specified avatar image.

16
 * @uses update_post_meta() For updating attachment meta fields.

17
 * @uses apply_filters() For calling the functions added to a filter hook.

18
 *

19
 * @since Avatar Manager 1.0.0

20
 *

21
 * @param int $user_id User to update.

22
 * @param int $size Size of the avatar image

23
 * @param string $default URL to a default image to use if no avatar is

24
 * available.

25
 * @param string $alt Alternative text to use in image tag. Defaults to blank.

26
 * @return string <img> tag for the user's avatar.

27
 */
28
function avatar_manager_get_custom_avatar( $user_id, $size = '', $default = '', $alt = false ) {
29
	// Returns if showing avatars is not enabled.

30
	if ( ! get_option( 'show_avatars' ) )
31
		return false;
32
33
	// Retrieves plugin options.

34
	$options = avatar_manager_get_options();
35
36
	if ( empty( $size ) || ! is_numeric( $size ) ) {
37
		$size = $options['avatar-manager-default-size'];
38
	} else {
39
		$size = absint( $size );
40
41
		if ( $size < 1 )
42
			$size = 1;
43
		elseif ( $size > 512 )
44
			$size = 512;
45
	}
46
47
	// Retrieves user data by user ID.

48
	$user = get_userdata( $user_id );
49
50
	// Returns if no user data was retrieved.

51
	if ( empty( $user ) )
52
		return false;
53
54
	$email = $user->user_email;
55
56
	if ( empty( $default ) ) {
57
		// Retrieves values for the named option.

58
		$avatar_default = get_option( 'avatar_default' );
59
60
		if ( empty( $avatar_default ) )
61
			$default = 'mystery';
62
		else
63
			$default = $avatar_default;
64
	}
65
66
	$email_hash = md5( strtolower( trim( $email ) ) );
67
68
	if ( is_ssl() )
69
		$host = 'https://secure.gravatar.com';
70
	else
71
		$host = sprintf( 'http://%d.gravatar.com', ( hexdec( $email_hash[0] ) % 2 ) );
72
73
	if ( $default == 'mystery' )
74
		$default = $host . '/avatar/ad516503a11cd5ca435acc9bb6523536?s=' . $size;
75
	elseif ( $default == 'gravatar_default' )
76
		$default = '';
77
	elseif ( strpos( $default, 'http://' ) === 0 )
78
		// Retrieves a modified URL (with) query string.

79
		$default = add_query_arg( 's', $size, $default );
80
81
	if ( $alt === false )
82
		$alt = '';
83
	else
84
		// Escapes HTML attributes.

85
		$alt = esc_attr( $alt );
86
87
	// Retrieves values for the named option.

88
	$avatar_rating = get_option( 'avatar_rating' );
89
90
	// Retrieves user meta field based on user ID.

91
	$custom_avatar = get_user_meta( $user_id, 'avatar_manager_custom_avatar', true );
92
93
	// Returns if no attachment ID was retrieved.

94
	if ( empty( $custom_avatar ) )
95
		return false;
96
97
	// Retrieves attachment meta field based on attachment ID.

98
	$custom_avatar_rating = get_post_meta( $custom_avatar, '_avatar_manager_custom_avatar_rating', true );
99
100
	$ratings['G']  = 1;
101
	$ratings['PG'] = 2;
102
	$ratings['R']  = 3;
103
	$ratings['X']  = 4;
104
105
	if ( $ratings[ $custom_avatar_rating ] <= $ratings[ $avatar_rating ] ) {
106
		// Retrieves attachment meta field based on attachment ID.

107
		$avatar = get_post_meta( $custom_avatar, '_avatar_manager_custom_avatar', true );
108
109
		if ( empty( $avatar[ $size ] ) ) {
110
			// Retrieves an array with the image attributes "url", "width"

111
			// and "height", of the image attachment file.

112
			$url = wp_get_attachment_image_src( $custom_avatar, 'full' );
113
114
			// Generates a resized copy of the avatar image.

115
			$avatar[ $size ] = avatar_manager_avatar_resize( $url[0], $size );
116
117
			// Updates attachment meta field based on attachment ID.

118
			update_post_meta( $custom_avatar, '_avatar_manager_custom_avatar', $avatar );
119
		}
120
121
		$src    = $avatar[ $size ]['url'];
122
		$avatar = '<img alt="' . $alt . '" class="avatar avatar-' . $size . ' photo avatar-default" height="' . $size . '" src="' . $src . '" width="' . $size . '">';
123
	} else {
124
		$src  = $host . '/avatar/';
125
		$src .= $email_hash;
126
		$src .= '?s=' . $size;
127
		$src .= '&d=' . urlencode( $default );
128
		$src .= '&forcedefault=1';
129
130
		$avatar = '<img alt="' . $alt . '" class="avatar avatar-' . $size . ' photo avatar-default" height="' . $size . '" src="' . $src . '" width="' . $size . '">';
131
	}
132
133
	// Calls the functions added to avatar_manager_get_custom_avatar

134
	// filter hook.

135
	return apply_filters( 'avatar_manager_get_custom_avatar', $avatar, $user_id, $size, $default, $alt );
136
}

Resumen

  • La función avatar_manager_get_custom_avatar devuelve una imagen de avatar personalizada basada en el ID de usuario o false si no se ha habilitado la visualización de avatares. La función recupera las opciones del plugin, desinfecta el parámetro $size y dá salida a los atributos HTML de la variable $alt.
  • A continuación, recupera una imagen predeterminada para usarla en lugar de la imagen de avatar si la clasificación de este no coincide. Se genera una copia redimensionada de la imagen de avatar a petición si el tamaño solicitado no coincide con un archivo de imagen existente.
  • La función get_userdata() devuelve un objeto WP_User con la información relativa al usuario cuyo ID le ha sido pasado.
  • La función md5() devuelve el hash MD5 para la cadena proporcionada.
  • La función strtolower() devuelve la cadena proporcionada pero con todos los caracteres alfabéticos convertidos a minúsculas.
  • La llamada is_ssl() comprueba si se está utilizando SSL.
  • La función sprintf() devuelve una cadena con formato.
  • La función hexdec() devuelve el equivalente decimal del número hexadecimal especificado.
  • La llamada strpos() encuentra la posición numérica de la primera aparición de needle en la cadena haystack.
  • La función wp_get_attachment_image_src() devuelve una matriz con los atributos de imagen url, width y height de un archivo de datos adjuntos de imagen.
  • Por último, utilizamos la función apply_filters() para llamar a las funciones añadidas al enlace de filtro avatar_manager_get_custom_avatar.

Paso 5. Recuperar una imagen de avatar

Básicamente, la siguiente función es la función principal de nuestro plugin:

1
/**

2
 * Returns the avatar for a user who provided a user ID or email address.

3
 *

4
 * @uses get_option() For getting values for a named option.

5
 * @uses avatar_manager_get_options() For retrieving plugin options.

6
 * @uses get_userdata() For retrieving user data by user ID.

7
 * @uses avatar_manager_get_custom_avatar() For retrieving user custom avatar

8
 * based on user ID.

9
 * @uses apply_filters() For calling the functions added to a filter hook.

10
 *

11
 * @since Avatar Manager 1.0.0

12
 *

13
 * @param int|string|object $id_or_email A user ID, email address, or comment

14
 * object.

15
 * @param int $size Size of the avatar image

16
 * @param string $default URL to a default image to use if no avatar is

17
 * available.

18
 * @param string $alt Alternative text to use in image tag. Defaults to blank.

19
 * @return string <img> tag for the user's avatar.

20
 */
21
function avatar_manager_get_avatar( $avatar = '', $id_or_email, $size = '', $default = '', $alt = false ) {
22
	// Returns if showing avatars is not enabled.

23
	if ( ! get_option( 'show_avatars' ) )
24
		return false;
25
26
	// Retrieves plugin options.

27
	$options = avatar_manager_get_options();
28
29
	if ( empty( $size ) || ! is_numeric( $size ) ) {
30
		$size = $options['avatar-manager-default-size'];
31
	} else {
32
		$size = absint( $size );
33
34
		if ( $size < 1 )
35
			$size = 1;
36
		elseif ( $size > 512 )
37
			$size = 512;
38
	}
39
40
	$email = '';
41
42
	if ( is_numeric( $id_or_email ) ) {
43
		$id = (int) $id_or_email;
44
45
		// Retrieves user data by user ID.

46
		$user = get_userdata( $id );
47
48
		if ( $user )
49
			$email = $user->user_email;
50
	} elseif ( is_object( $id_or_email ) ) {
51
		if ( ! empty( $id_or_email->user_id ) ) {
52
			$id = (int) $id_or_email->user_id;
53
54
			// Retrieves user data by user ID.

55
			$user = get_userdata( $id );
56
57
			if ( $user )
58
				$email = $user->user_email;
59
		} elseif ( ! empty( $id_or_email->comment_author_email ) ) {
60
			$email = $id_or_email->comment_author_email;
61
		}
62
	} else {
63
		$email = $id_or_email;
64
65
		if ( $id = email_exists( $email ) )
66
			// Retrieves user data by user ID.

67
			$user = get_userdata( $id );
68
	}
69
70
	if ( isset( $user ) )
71
		$avatar_type = $user->avatar_manager_avatar_type;
72
	else
73
		return $avatar;
74
75
	if ( $avatar_type == 'custom' )
76
		// Retrieves user custom avatar based on user ID.

77
		$avatar = avatar_manager_get_custom_avatar( $user->ID, $size, $default, $alt );
78
79
	// Calls the functions added to avatar_manager_get_avatar filter hook.

80
	return apply_filters( 'avatar_manager_get_avatar', $avatar, $id_or_email, $size, $default, $alt );
81
}
82
83
add_filter( 'get_avatar', 'avatar_manager_get_avatar', 10, 5 );

Resumen

  • La función avatar_manager_get_avatar() devuelve el avatar de un usuario que proporcionó un ID de usuario o una dirección de correo electrónico, o false si no está habilitada la visualización de avatares.
  • Usamos el filtro get_avatar para cambiar la salida de la función get_avatar(). Nuestra función recupera las opciones del plugin, desinfecta el parámetro $size y encuentra el ID del usuario especificado.
  • A continuación, devuelve el resultado de la llamada a la función avatar_manager_get_custom_avatar(), o la salida no modificada de get_avatar() si el usuario no utiliza un avatar personalizado.
  • La llamada is_object() busca si una variable es un objeto.
  • La función email_exists() comprueba si una dirección de correo electrónico determinada ya ha sido registrada en un nombre de usuario y devuelve ese ID de usuario, o false si no existe ninguno.

Para comprobar el resultado, dirígete a la pantalla Usuarios -> Tu perfil.

The Avatar Manager plugin options under the User Your Profile ScreenThe Avatar Manager plugin options under the User Your Profile ScreenThe Avatar Manager plugin options under the User Your Profile Screen
Las opciones del plugin Avatar Manager en la pantalla de usuario Tu perfil

Busca una imagen y cárgala. Ahora, deberías poder elegir entre usar Gravatar o la imagen de avatar personalizada que acabas de subir.


Paso 6. Eliminar ganchos de filtro innecesarios

Si vas a la pantalla discusión de configuración, notarás que los avatares de la configuración de Avatar predeterminada se reemplazan por tu avatar personalizado. Para solucionar este problema, restauraremos los avatares predeterminados eliminando nuestra función personalizada cuando no sea necesario con la ayuda del gancho de filtro avatar_defaults. Para ello, añade el siguiente código:

1
/**

2
 * Prevents custom avatars from being applied to the Default Avatar setting.

3
 *

4
 * @uses remove_filter() For removing a function attached to a specified action

5
 * hook.

6
 *

7
 * @since Avatar Manager 1.0.0

8
 *

9
 * @param array $avatar_defaults An associative array with default avatars.

10
 * @return array An associative array with default avatars.

11
 */
12
function avatar_manager_avatar_defaults( $avatar_defaults ) {
13
	// Removes the avatar_manager_get_avatar function attached to get_avatar

14
	// action hook.

15
	remove_filter( 'get_avatar', 'avatar_manager_get_avatar' );
16
17
	return $avatar_defaults;
18
}
19
20
add_filter( 'avatar_defaults', 'avatar_manager_avatar_defaults', 10, 1 );

Para evitar que los avatares personalizados se apliquen a la configuración de Avatar predeterminado, llamamos a la función remove_filter(). Elimina una función asociada a un gancho de filtro especificado. Este método puede utilizarse para eliminar las funciones predeterminadas asociadas a un gancho de filtro concreto y posiblemente reemplazarlas con un sustituto.


Paso 7. Visualizar los estados personalizados de medios

La pantalla de la Biblioteca de medios te permite editar, ver y eliminar imágenes, vídeos, grabaciones y archivos cargados previamente en tu blog. Para identificar un archivo adjunto que se utiliza como imagen de avatar, vamos a mostrar un estado de medios personalizado:

1
/**

2
 * Displays media states for avatar images.

3
 *

4
 * @uses get_post_meta() For retrieving attachment meta fields.

5
 * @uses __() For retrieving the translated string from the translate().

6
 * @uses apply_filters() For calling the functions added to a filter hook.

7
 *

8
 * @since Avatar Manager 1.0.0

9
 *

10
 * @param array $media_states An associative array with media states.

11
 * @return array An associative array with media states.

12
 */
13
function avatar_manager_display_media_states( $media_states ) {
14
	global $post;
15
16
	// Retrieves attachment meta field based on attachment ID.

17
	$meta_avatar = get_post_meta( $post->ID, '_avatar_manager_is_custom_avatar', true );
18
19
	if ( ! empty( $meta_avatar ) )
20
		$media_states[] = __( 'Avatar Image', 'avatar-manager' );
21
22
	// Calls the functions added to avatar_manager_display_media_states filter

23
	// hook.

24
	return apply_filters( 'avatar_manager_display_media_states', $media_states );
25
}
26
27
add_filter( 'display_media_states', 'avatar_manager_display_media_states', 10, 1 );

El filtro display_media_states se utiliza para mostrar estados de medios personalizados para los elementos adjuntos que se hayan añadido a la Biblioteca de medios. Usamos la variable global $post para obtener el ID del archivo adjunto actual. Si el campo personalizado _avatar_manager_is_custom_avatar no está vacío, el archivo adjunto es una imagen de avatar, por lo que le añadimos un estado de medios personalizado.

Si no tienes ninguna imagen de avatar personalizada configurada, sube una y dirígete a la pantalla de la Biblioteca de medios.

The Avatar Manager plugin media states under the Media Library ScreenThe Avatar Manager plugin media states under the Media Library ScreenThe Avatar Manager plugin media states under the Media Library Screen
Los estados de medios del plugin Avatar Manager en la pantalla de la Biblioteca de medios

Ten en cuenta que cada archivo adjunto que se utiliza como una imagen de avatar personalizada tiene la cadena de imagen de avatar anexada junto a su nombre de archivo.


Paso 8. Añadir el desinstalador

Para manejar el proceso de desinstalación, un plugin debe crear un archivo llamado uninstall.php en el directorio base del plugin en lugar de usar register_uninstall_hook(). Si este archivo existe, será llamado durante el proceso de desinstalación omitiendo el gancho de desinstalación. Para ello, abre avatar-manager/uninstall.php y añade el siguiente código:

1
<?php
2
/**

3
 * @package Avatar_Manager

4
 * @subpackage Uninstaller

5
 */
6
7
// Exits if uninstall is not called from WordPress.

8
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) )
9
	exit;
10
11
if ( ! function_exists( 'avatar_manager_delete_avatar' ) )
12
	include_once( 'avatar-manager.php' );
13
14
// Deletes plugin options.

15
delete_option( 'avatar_manager' );
16
17
// An associative array with criteria to match.

18
$args = array(
19
	'meta_key' => 'avatar_manager_custom_avatar'
20
);
21
22
// Retrieves an array of users matching the criteria given in $args.

23
$users = get_users( $args );
24
25
foreach ( $users as $user ) {
26
	// Deletes avatar image based on attachment ID.

27
	avatar_manager_delete_avatar( $user->avatar_manager_custom_avatar );
28
}
29
?>

Cuando se utiliza uninstall.php el plugin siempre debe comprobar la constante WP_UNINSTALL_PLUGIN, antes de ejecutarse. La constante WP_UNINSTALL_PLUGIN es definida por WordPress en tiempo de ejecución durante una desinstalación del plugin y no estará presente si uninstall.php se solicita directamente. defined() comprueba si existe una determinada constante con nombre. La instrucción include_once incluye y evalúa el archivo especificado durante la ejecución del script; si el código de un archivo ya ha sido incluido, no se incluirá nuevamente. La función delete_option() elimina una opción con nombre de la tabla options de la base de datos.


Paso 9. Internacionalizar y traducir el plugin

Una vez hayas creado la programación para tu plugin, otra consideración es la internacionalización. La internacionalización, abreviada a menudo como i18n, es el proceso de configuración de software para que pueda ser localizado; localización, o l10n, es el proceso de traducción del texto mostrado por el software en diferentes idiomas. WordPress utiliza las bibliotecas y herramientas gettext para i18n.

Es muy recomendable que internacionalices tu plugin, para que los usuarios de diferentes países puedan localizarlo.

Cadenas traducibles

Para hacer una cadena traducible, solo tienes que ajustar la cadena original en una llamada a la función __(). Si el código debe hacerse eco de la cadena en el navegador, utiliza en su lugar la función _e(). Como habrás notado, ya lo hemos hecho en nuestro plugin.

Dominios de texto

Un dominio de texto es un identificador único, que se asegura de que WordPress pueda distinguir entre todas las traducciones cargadas. Usar el nombre base de tu plugin siempre es una buena opción. Puedes cargar las cadenas traducidas del plugin llamando a la función load_plugin_textdomain(), algo que ya hemos hecho en la primera parte de nuestro tutorial.

Archivos PO

Ahora, tenemos que crear un archivo .po para los traductores. Para ello, usaremos el software de traducción Poedit. Una vez lo hayas descargado, haz clic en Archivo > Nuevo catálogo... para configurar un nuevo catálogo. Debería abrirse una nueva ventana. Dirígete a la pestaña Información del proyecto e introduce Avatar Manager como nombre del proyecto.

Poedits Project info tab under the Settings windowPoedits Project info tab under the Settings windowPoedits Project info tab under the Settings window
Ficha Información del proyecto de Poedit en la ventana Configuración

En la pestaña Rutas, dejemos la ruta de acceso base como . que hace referencia al directorio en el que se encuentra el catálogo.

Poedits Paths tab under the Settings windowPoedits Paths tab under the Settings windowPoedits Paths tab under the Settings window
La ficha Rutas de Poedit situada bajo la ventana Configuración

A continuación, dirígete a la pestaña Palabras clave. Elimina todos los elementos que aparecen allí, y añade estas palabras clave: __, _e, _n y _x.

Poedits Keywords tab under the Settings windowPoedits Keywords tab under the Settings windowPoedits Keywords tab under the Settings window
Ficha Palabras clave de Poedit en la ventana Configuración

Pulsa OK y guarda el archivo como avatar-manager/languages/avatar-manager-default.po. Ahora, el archivo ya está listo para su traducción.

Poedits main windowPoedits main windowPoedits main window
Ventana principal de Poedit

Traduce todas las cadenas que quieras y, a continuación, guarda el archivo como avatar-manager/languages/avatar-manager-{locale}.po. Locale es el código de idioma y/o código de país que definiste en la constante WPLANG en el archivo wp-config.php.

Archivos MO

Un archivo .mo es un archivo binario que contiene todas las cadenas originales y sus traducciones en un formato adecuado para la rápida extracción de la traducción. La conversión se realiza automáticamente si va a Editar > Preferencias > Editor y marcas Compilar automáticamente el archivo MO al guardar.


Paso 10. Publicación y promoción de un plugin

Esta sección revisamos los pasos necesarios para tomar un plugin que hayas creado y conseguir distribuirlo ampliamente.

Envío al directorio de plugins de WordPress

La forma más rápida, sencilla y mejor de distribuir tu plugin es cargarlo en el Directorio de plugins de WordPress. Para obtener más detalles sobre cómo enviar tu plugin, consulta la página de Información para desarrolladores o dirígete directamente a la página de envío de plugins.

Promocionar y documentar tu plugin

Para enviar y promocionar tu plugin entre la Comunidad de WordPress, crea primero en tu sitio una página para el plugin con instrucciones completas y bien escritas. Incluye un enlace a esta página con explicaciones en la cabecera del plugin, para que las personas puedan buscar fácilmente actualizaciones, más información y ayuda.

Si decides enviar tu plugin al Directorio de plugins de WordPress, haz también que esta información sea lo más clara posible de forma que puedan categorizar y ayudar a otros a entender la utilidad de tu plugin. También tienes que crear un archivo readme.txt en un formato estándar, e incluirlo en tu plugin.


Conclusión

Con esto concluimos nuestro tutorial; ahora, tenemos un plugin completamente en funcionamiento y hemos aprendido algunos consejos y trucos prácticos sobre el desarrollo de plugins de WordPress. La idea detrás de este plugin comenzó como una característica solicitada en el núcleo de WordPress; Me encantaría oír tus opiniones al respecto. ¿Mejora el flujo de trabajo actual? ¿Te resultaría útil un enfoque similar pero para la gestión de imágenes de Gravatar directamente desde la pantalla de tu perfil?

Como extra, el plugin Avatar Manager también está disponible en el Directorio de plugins de WordPress y en GitHub. Compruébalo para mantenerte al día con las últimas actualizaciones. ¡Gracias por leerme!


Referencias

  • WordPress Coding Standards: Información general sobre los estándares de codificación para el desarrollo de WordPress.
  • Writing a Plugin: El mejor punto de partida para aprender sobre cómo desarrollar plugins de WordPress.
  • Plugin API: Descripción sobre cómo utilizar ganchos de acción y filtros en tu plugin de WordPress, y funciones principales que los plugins pueden invalidar.
  • Function Reference: Un artículo con muchas de las funciones principales de WordPress útiles para los desarrolladores de plugins y temas; enumera la mayoría de las funciones más importantes, excluyendo las etiquetas de plantilla.
  • I18n for WordPress Developers: Internacionalización, incluyendo una sección sobre cómo internacionalizar tu plugin.
  • Plugin Submission and Promotion: Una vez haya escrito tu plugin, aquí tienes algunas sugerencias para distribuirlo ampliamente.

Enlaces externos