Configuración de cookies personalizadas en WordPress
Estoy intentando establecer cookies para redirigir a los usuarios que regresan a una página específica dentro de mi sitio WordPress.
Me gustaría recibir consejos sobre estos 2 puntos:
- ¿En qué archivos PHP de WordPress se deberían verificar las cookies antes de cargar cualquier contenido para manejar una redirección? ¿Hay algún archivo que sea más adecuado que otros para esto?
- ¿Cómo establezco correctamente una cookie en WordPress?
setcookie('nombre_cookie', 'valor_cookie', time()+4000);
no parece estar guardando ninguna cookie en mi sistema.
1 - Puedes verificar las cookies y hacer tu redirección utilizando hooks que se llaman antes de cualquier salida como el hook 'init':
<?php
// Engancha la función "redirect()" a la acción "init"
add_action('init', 'redirect');
// redirect() puede redirigir al usuario dependiendo de las cookies que tenga
function redirect(){
/* CÓDIGO */
}
?>
2 - La mejor manera de establecer cookies sería usando el hook 'init' así:
<?php
add_action('init', 'my_setcookie');
// my_setcookie() establece la cookie en el dominio y directorio donde está instalado WP
function my_setcookie(){
$path = parse_url(get_option('siteurl'), PHP_URL_PATH);
$host = parse_url(get_option('siteurl'), PHP_URL_HOST);
$expiry = strtotime('+1 month');
setcookie('my_cookie_name_1', 'my_cookie_value_1', $expiry, $path, $host);
/* más cookies */
setcookie('my_cookie_name_2', 'my_cookie_value_2', $expiry, $path, $host);
}
?>
Esto es más consistente, si tienes un blog en www.example.com/blog, la(s) cookie(s) no estarán disponibles en
- www.example.com
- www.example.com/store
- example.com
- www2.example.com
- ...
Actualización
también deberías poder usar las constantes COOKIE_PATH y COOKIEDOMAIN en lugar de determinarlas tú mismo, lo cual acabo de notar en la respuesta de Andre R Kohl – drzaus

¿Cómo puedes poner múltiples variables, por ejemplo Firstname, LastName, Random1, Random2 en lugar de solo la variable 'my_cookie_1'?

Oh, no sabía que las cookies solo contienen una variable por cookie. ¿Hay alguna manera de configurar múltiples cookies sin necesidad de tener el código de tiempo y URL anterior para que resulte en menos código? ¿Se podrían poner en una variable?

también deberías poder usar las COOKIEPATH
y COOKIEDOMAIN
constantes en lugar de tener que deducirlas tú mismo, lo cual acabo de notar en la respuesta de Andre R Kohl

corrección: COOKIE_DOMAIN

Ah, me di cuenta de que necesitaba enlazar esto al init()
.
SOLUCIÓN: Creé una función en functions.php que establece y verifica la cookie. Para que funcione correctamente, después de definir la función, fuera de la función llama esto:
add_action('init', 'nombre-de-la-función');

Esta forma funcionó:
add_action( 'init', 'funcion-para-establecer-cookie' );
function funcion-para-establecer-cookie(){
//usa una condición aquí, en qué página quieres establecer la cookie
//elige una página donde quieras que se establezca la cookie
$pageurl = get_option('siteurl').'/pagina-para-establecer-cookie';
// usa una función para obtener la URL de la página actual y usa una condición
//para compararla con la página deseada donde quieres establecer la cookie
if ( $pageurl === current_page_url() ) {
setcookie( 'nombre_cookie', 'valor_cookie', $tiempoExpiracion, $rutaCookie, $siteurl );
}
}

Querrás eliminar tu cookie antes de que se escriba cualquier contenido en la página (antes de que se envíen las cabeceras).
Para establecer la cookie, incluye la ruta, el dominio, y también recomiendo configurar los últimos 2 parámetros como true ($secure
y $httponly
). También necesitarás proporcionar los mismos parámetros a setcookie()
cuando elimines, excepto por $expiry
(que debe ser negativo) y $value
(que debe estar vacío '').
Si estás pasando JSON a través de la cookie, parece que necesitas hacer base64_encode
también, o no se decodificará correctamente.
Todo esto debería hacerse en una clase para que puedas acceder al valor de la cookie más adelante en tu código. La clase puede añadirse a un plugin o a functions.php.
Aquí hay un ejemplo donde usamos una cookie para almacenar una respuesta de acción y luego mostrársela al usuario después de redirigirlo:
class my_custom_class {
const MY_COOKIE_NAME_JSON = 'my_cookie_name_json';
const COOKIE_LIFETIME = 3600;
private $cookie_value;
function __construct() {
// asegúrate de eliminar la cookie antes de que se envíen las cabeceras
add_action('init', [$this, 'process_cookie_json'], 10);
// usa alertas de bootstrap para formatear el mensaje de retorno
add_filter('the_content', [$this, 'filter_the_content_in_the_main_loop'], 1);
}
static function some_action_that_sets_the_cookie($message, $response_type = 'success') {
$responses = [];
if (isset($_COOKIE[self::MY_COOKIE_NAME_JSON]))
$responses = json_decode(base64_decode($_COOKIE[self::MY_COOKIE_NAME_JSON]));
$responses[$response_type][] = $message;
self::set_cookie_json($responses);
}
static function set_cookie_json(array $cookie_value) {
setcookie(self::MY_COOKIE_NAME_JSON, base64_encode(json_encode($cookie_value)), time() + self::COOKIE_LIFETIME, "/", $_SERVER['HTTP_HOST'], true, true);
}
function process_cookie_json() {
if (!isset($_COOKIE[self::MY_COOKIE_NAME_JSON]))
return false;
$this->cookie_value = json_decode(base64_decode($_COOKIE[self::MY_COOKIE_NAME_JSON]), true);
setcookie(self::MY_COOKIE_NAME_JSON, '', -1, "/", $_SERVER['HTTP_HOST'], true, true);
unset($_COOKIE[self::MY_COOKIE_NAME_JSON]);
}
function filter_the_content_in_the_main_loop($content) {
if (!$this->cookie_value || !is_array($this->cookie_value))
return $content;
$alerts = [];
foreach ($this->cookie_value as $response_type => $messages)
$alerts[] = '<div class="alert alert-' . $response_type . '" role="alert">' . implode(PHP_EOL, $messages) . '</div>';
return implode(null, $alerts) . $content;
}
}
$my_custom_class = my_custom_class;
Luego puedes establecer la cookie mediante:
my_custom_class::some_action_that_sets_the_cookie('el mensaje');
