Comprobar si el usuario está conectado usando jQuery
Quiero ejecutar código jQuery personalizado que muestre un diálogo de inicio de sesión al usuario si hace clic en un botón y no ha iniciado sesión. ¿Cómo podría hacer eso?

Revisa el atributo class
para body
: Si el tema está usando body_class()
, el body tendrá una clase llamada logged-in
para usuarios que han iniciado sesión. Ten en cuenta que la función también puede usarse en el elemento html
.
Ejemplo con jQuery:
if(jQuery('body').hasClass('logged-in')){
// Hacer algo
}
Ejemplo con JavaScript puro:
if (document.body.classList.contains('logged-in')) {
// hacer algo
}
También puedes usar is_user_logged_in()
como condición para encolar o imprimir el script.

Me gusta la idea de simplemente verificar el cuerpo para la clase logged-in
. Solo hay que asegurarse de que los temas usen body_class();
o get_body_class();
De lo contrario, no es una solución muy confiable. Aunque yo uso esas funciones en mis temas, así que es una buena solución para mí. Gracias por la idea simple.

Si deseas saber si el usuario está conectado en este momento, prueba esto. Las otras respuestas verifican si el usuario estaba conectado o no cuando la página se cargó, no en el momento en que se ejecuta el JavaScript. El usuario podría haber iniciado sesión en una pestaña separada, por ejemplo.
Coloca esto en tu JavaScript
var data = {
action: 'is_user_logged_in'
};
jQuery.post(ajaxurl, data, function(response) {
if(response == 'yes') {
// el usuario está conectado, haz lo que necesites aquí
} else {
// el usuario no está conectado, muestra el formulario de inicio de sesión aquí
}
});
Coloca esto en tu functions.php
function ajax_check_user_logged_in() {
echo is_user_logged_in()?'yes':'no';
die();
}
add_action('wp_ajax_is_user_logged_in', 'ajax_check_user_logged_in');
add_action('wp_ajax_nopriv_is_user_logged_in', 'ajax_check_user_logged_in');

WordPress lo establece como 'tusitio.com/wp-admin/admin-ajax.php'. Esa es la URL a la que se supone que deben enviarse todas las solicitudes AJAX

Coloqué el jQuery.post dentro del manejador de clics de jQuery pero esto no funciona. ¿Tienes alguna idea de cómo solucionarlo?

Codex menciona que en las versiones más recientes de WordPress esto ya está definido. Quizás puedas definir tu propia versión de ajaxurl con wp_localize_script

La URL siempre debe apuntar a "dominio.com/wp-admin/admin-ajax.php"

En caso de que alguien reciba el error "ajaxurl no está definido"... http://stackoverflow.com/questions/17710728/how-to-load-ajax-in-wordpress#17713643

Por favor, agrega body_class() al cuerpo HTML
<body <?php body_class(); ?>>
// tu código html
</body>
Esto agregará la clase logged-in
para usuarios logueados, luego puedes usar el siguiente código jQuery para ejecutar tu código personalizado solo para usuarios logueados.
if ($('body').hasClass('logged-in')) {
// ejecuta tu código jQuery.
}

No sé por qué este recibió votos negativos. El enfoque es totalmente válido. +1

No lo sé. Tengo la misma pregunta. La respuesta es válida, pero ¿por qué los votos negativos?

Hmm. Quizás porque usa jQuery en lugar de la forma correcta (usando un filtro y el callback). Algunas personas son alérgicas a jQuery.

Ten en cuenta que ninguno de los ejemplos anteriores es confiable si utilizas un plugin de caché de página, ya que el código en la etiqueta body será estático. Además, existe una forma sencilla de hacer esto (sin consultas adicionales a AJAX, lo cual no es óptimo).
Si deseas probar el estado de inicio de sesión del usuario con JavaScript, puedes usar este código para establecer una cookie cuando el usuario inicia sesión y eliminarla cuando cierra sesión. Añade esto, por ejemplo, al archivo functions.php de tu tema:
function login_function() {
setcookie('wp_user_logged_in', 1, time() + 31556926, '/');
$_COOKIE['wp_user_logged_in'] = 1;
}
add_action('wp_login', 'login_function');
function logout_function() {
unset($_COOKIE['wp_user_logged_in']);
setcookie('wp_user_logged_in', null, -1, '/');
}
add_action('wp_logout', 'logout_function');
Luego, es una simple prueba de la cookie en JavaScript.
if (document.cookie.indexOf('wp_user_logged_in') !== -1) {
//hacer algo cuando el usuario ha iniciado sesión
} else {
//hacer algo cuando el usuario ha cerrado sesión
}

Es realmente bastante simple, confiable y en el peor de los casos se ejecuta casi instantáneamente después de la carga de la página (si se carga el script en el pie de página sin bloqueo de renderizado), a diferencia de otras respuestas. Ajax es lento y depender de clases del cuerpo fallará con el caché. Es necesario agregar esta cookie al texto de la Política de Cookies. Gracias Janos.

Como seguimiento, existe un problema con la sincronización de las cookies predeterminadas de WordPress y la nueva cookie accesible por script, pero he recibido una respuesta excelente y simple sobre cómo solucionarlo: https://stackoverflow.com/questions/56208574/setting-script-accessible-cookie-expiry-based-on-wordpress-logged-in-cookie

Otro ejemplo, en caso de que quieras usarlo para llamadas AJAX.
// Simplificado... ten en cuenta que todos los nombres/variables/etc. en mi clase tienen nombres únicos.
// ...lo mismo aplica para el manejador del script.
class wpse69814_example
{
public $response;
public function __construct()
{
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'localize' ), 20 );
}
public function enqueue()
{
wp_enqueue_script(
'wpse69814_handler',
plugins_url( 'url/to/file.js', __FILE__ ),
array( 'jquery' ),
filemtime( plugins_dir_path( __FILE__ ).'/path/to/file.js' ),
true
);
}
public function localize()
{
wp_localize_script( 'wpse69814_handler, 'wpse69814_object', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'ajax_nonce' => wp_create_nonce( 'wpse69814_nonce' ),
'action' => 'wpse69814-handler-action',
'data' => array(
'is_user_logged_in' => is_user_logged_in(),
)
)
}
}

Dado que la CDN no se autentica con WordPress, is_user_logged_in
se almacenará en caché como falso en el DOM cuando se acceda al origen. El estado del usuario debería abstraerse a un hilo sin caché mediante XHR cuando se usa una CDN. El enfoque de @Mridul Aggarwal funciona pero con cabeceras de no-cache en la respuesta.

Gracias a esta publicación y otra más, encontré una solución a mi problema. Solo lo comparto por si a alguien le puede resultar útil.
Funciona en sitios WordPress actuales
Este código verifica si el usuario ha iniciado sesión o no usando jQuery. Si el usuario NO ha iniciado sesión, evita que el usuario haga clic derecho en el contenido y copie imágenes y texto.
$(document).ready(function(){
// si el usuario no ha iniciado sesión...
if (!document.querySelector('body.logged-in')){
//bloquear todo el contenido
disableSelection(document.body);
// deshabilitar clic en imágenes
$('img').bind('contextmenu', function(e){return false;});
console.log('hola');
}
// función para bloquear todo el contenido
function disableSelection(target){
$(function() {
$(this).bind("contextmenu", function(e) {
e.preventDefault();
});
});
if (typeof target.onselectstart!="undefined") //Para IE
target.onselectstart=function(){return false}
else if (typeof target.style.MozUserSelect!="undefined") //Para Firefox
target.style.MozUserSelect="none"
else //Para otros navegadores (como Opera)
target.onmousedown=function(){return false}
target.style.cursor = "default";
}
})

Estoy utilizando un método alternativo sin ajaxurl
y body class
. Simplemente no confío en la clase del cuerpo, que podría no existir en todos los temas.
En functions.php
deberías tener:
add_action( 'wp_body_open', 'custom_body_open' );
function custom_body_open() {
$logged_in = is_user_logged_in() ? 'yes' : 'no'; //Función de WP para verificar si el usuario está conectado o no
echo '<div style="display:none" class="user_is_logged_in" data-logged-in="' . $logged_in . '" ></div>';
}
Eso crea un div
invisible al inicio de la etiqueta body con:
- Nombre de clase "user_is_logged_in" - solo para referencia de jQuery.
- Estilo "display: none" - hace que el div sea invisible. En su lugar puedes usar CSS:
.user_is_logged_in { display: none }
- Valor "data-(logged-in)" como "yes" (conectado) o "no" (no conectado). Ese valor será consultado posteriormente con
jQuery
.
En jQuery consulto el valor de "data-logged-in" y luego actúo en consecuencia:
jQuery(document).ready(function($) {
var logged_in = $(".user_is_logged_in").data("logged-in") == 'yes' ? true : false;
if (logged_in) {
...
}
else {
...
}
}

Aquí está el script de WordPress que agregará una clase a la etiqueta Body dependiendo de si el usuario ha iniciado sesión o no
https://gist.github.com/raftaar1191/55fe297db0724e62883846b3ed31b543

Agradezco todas las respuestas, pero localizar scripts o verificar la clase CSS no sería, en mi opinión, la mejor práctica, ya que la verificación de clases CSS no es 100% confiable y la función de localización de scripts es, como su nombre indica, para localizar.
Después de WordPress 4.5, la mejor solución sería agregar un script en línea de la siguiente manera:
<?php
function detect_login() {
$isLoggedIn = is_user_logged_in();
wp_register_script( 'detect_login', '' );
wp_enqueue_script( 'detect_login');
wp_add_inline_script( 'detect_login', "var isLoggedIn = $isLoggedIn" );
}
add_action( 'wp_enqueue_scripts', 'detect_login' );
Y luego, obviamente, verificar el ámbito global que ahora está contaminado por nuestra variable global isLoggedIn de la siguiente manera: window.isLoggedIn

@JacobPeattie Sí, la razón por la que crearon wp_add_inline_script()
es para evitar que la gente use la función de localización de scripts para declarar variables globales. Como su nombre indica, esta es una mejor opción. ¿Por qué usar algo que inicialmente no estaba destinado para ese propósito si tenemos una buena alternativa?

No fue creado para eso. Se añadió para permitir agregar pequeños fragmentos de código ejecutable antes o después de un script, para soportar cosas como cargadores de fuentes. https://make.wordpress.org/core/2016/03/08/enhanced-script-loader-in-wordpress-4-5/

@JacobPeattie exactamente, ¿y para qué se agregó la cadena wp_localize_script()
? ¿Para contaminar el ámbito global con variables globales? ¿O para localizar como su nombre sugiere?

¿De qué estás hablando? wp_localize_script te obliga a poner espacios de nombres a tus variables dentro de un objeto. Tu propia respuesta está agregando una variable al ámbito global sin ningún tipo de espacio de nombres.

@JacobPeattie ehm, ¿dónde crees que almacenarás el objeto de wp_localize_script()
? pista: window
, de todos modos como estás tan apegado a wp_localize_script()
siéntete libre de mantener tu opinión sobre usarlo para declarar variables no relacionadas con la localización en lugar de usar la función vanilla hecha para eso, cada quien con lo suyo.
