• ResueltoModerador almendron

    (@almendron)


    He encontrado en el codex el siguiente código:

    /**
     * Hide email from Spam Bots using a shortcode.
     *
     * @param array  $atts    Shortcode attributes. Not used.
     * @param string $content The shortcode content. Should be an email address.
     * @return string The obfuscated email address. 
     */
    function wpdocs_hide_email_shortcode( $atts , $content = null ) {
        if ( ! is_email( $content ) ) {
            return;
        }
        return '<a href="mailto:' . esc_url( antispambot( $content ) ) . '">' . esc_html( antispambot( $content ) ) . '</a>';
    }
    add_shortcode( 'email', 'wpdocs_hide_email_shortcode' );

    Si lo aplico tal cual, aparece el enlace con una sintaxis errónea:

    <a href="mailto:http://xxx@xxxx.com">xxx@xxxx.com</a>

    Para que aparezca bien el enlace, es necesario cambiar y poner «esc_html» en lugar de «esc_url». De esta forma sale:

    <a href="mailto:xxx@xxxx.com">xxxg@xxxx.com</a>

    Las dudas que tengo son las siguientes:

    1) ¿Es un error del código usar «esc_url»?
    2) «Es necesario usar «esc_html»?

    Al margen de esta duda, me gustaría saber si hay alguna forma de ofuscar una dirección de correo cuando esta se introduce en el menú de un tema, es decir, yendo a Apariencia > Menús.

Viendo 13 respuestas - de la 1 a la 13 (de un total de 13)
  • Moderador kallookoo

    (@kallookoo)

    Hola @almendron

    1) Yo diria que si es un error del codigo, prueba asi esc_url( 'mailto:' . antispambot( $content ) )
    Tienes un codigo mas completo en este plugin; https://plugins.trac.wordpress.org/browser/antispambot/trunk/antispambot.php
    2) Si no funcionase lo de antes y por seguridad yo te lo recomiendo. Nunca esta de mas pasare un esc_* sino estamos seguros del contenido.

    Sobre el menu deberias utilizar algun filtro de los que aparece aqui; https://developer.wordpress.org/reference/classes/walker_nav_menu/start_el/
    Yo me decanto por el walker_nav_menu_start_el, si lo quieres modificar antes de mostrarlo en la web.
    Otra seria guardarlo directamente codificado en la DB utilizando el filtro wp_insert_post_data pero se complica un poco mas para implementarlo.
    Vamos que debes detectar el post_type para ejecutarlo o no, filtrar los elementos del menu para detectar si existe un mail sin codificar y asi pasarle la function para codificarlo.

    • Esta respuesta fue modificada hace 4 años, 8 meses por kallookoo.
    Moderador almendron

    (@almendron)

    Muchas gracias @kallookoo

    De momento, me apaño con el plugin que funciona perfectamente. Lo del menú lo miraré con más detenimiento y ya te diré algo.

    Moderador almendron

    (@almendron)

    Me surge una duda: de la misma forma que se usa add_filter( 'the_content', ...), ¿No hay ninguna forma de sustituir «the_content» por algo que haga que actúe el filtro en los menús?

    Moderador kallookoo

    (@kallookoo)

    No te entendi, en el the_content se pasan muchas funciones pero ninguna codifica los mails que yo recuerde.
    En el enlace que te puse en las lineas 202 y 225 veras dos filtros.
    Uno que se encarga de los attrs del enlace y el otro que se encarga del texto del enlace (aka title)
    Con esos dos deberias poder aplicar la function, salvo que en el de los attrs es un array asi que deberias primero identificar el $attr['href'].
    No pongo codigo que estoy con el movil, espero que igualmente lo entiendas.

    Moderador almendron

    (@almendron)

    Me explico mejor con un ejemplo:

    function security_remove_emails($content) {
        $pattern = '/([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4})/i';
        $fix = preg_replace_callback($pattern, "security_remove_emails_logic", $content);
        return $fix;
    }
    function security_remove_emails_logic($result) {
        return antispambot($result[1]);
    }
    add_filter( 'the_content', 'security_remove_emails', 20 ); //ocultar correo en posts
    add_filter( 'comment_text', 'security_remove_emails', 20 ); //ocultar correo en comentarios
    add_filter( 'widget_text', 'security_remove_emails', 20 ); //ocultar correo en widgets

    Como ves, el filtro se puede poner para que actúe en determinadas áreas (the_content, comment_text, ..). Lo que no encuentro es si hay algún opción para que actué en la zona de menús.

    Moderador almendron

    (@almendron)

    Y respecto al código, lo miro mañana. Tal vez funcione nav_menu_link_attributes

    Muchas gracias.

    Moderador kallookoo

    (@kallookoo)

    He actualizado tu codigo, pero no lo probe.

    
    function security_remove_emails( $data ) {
        if ( is_array( $data ) || is_object( $data ) ) {
            return map_deep( $data, 'security_remove_emails' );
        }
    
        if ( $data && is_string( $data ) ) {
            $_data = preg_replace_callback( 
               '/([0-9a-z._%+-]+@[a-z0-9.-]+\.[a-z]{2,})/i',
               function ( $r ) {
                   if ( ! empty( $r[1] ) ) {
                       return antispambot( $r[1] );
                   }
                   return $r;
               }, 
               $data
            ); 
            if ( is_string( $_data ) ) {
                return $_data;
            }
        }
        return $data;
    }
    add_filter( 'the_content', 'security_remove_emails', 20 );
    add_filter( 'comment_text', 'security_remove_emails', 20 );
    add_filter( 'widget_text', 'security_remove_emails', 20 );
    
    add_filter( 
        'nav_menu_link_attributes',
        function ( $atts, $item, $args, $depth ) {
            if ( isset( $atts['href'] ) ) {
                $atts['href'] = security_remove_emails( $atts['href'] );
            }
            return $atts;
        },
        10,
        4
    );
    
    add_filter(
        'nav_menu_item_title', 
        function( $title, $item, $args, $depth ) {
            return security_remove_emails( $title );
        },
        10, 
        4
    );
    

    He añadido tanto el href como el title.

    • Esta respuesta fue modificada hace 4 años, 8 meses por kallookoo.
    • Esta respuesta fue modificada hace 4 años, 8 meses por kallookoo.
    Moderador almendron

    (@almendron)

    En cuanto tenga un momento, lo pruebo y te digo algo.

    Moderador almendron

    (@almendron)

    Voy comprobando cosas.

    El código del codex, en su línea 12, debe poner, ta y como has indiciado, lo siguiente:

    return '<a href="' . esc_url( 'mailto:' . antispambot( $content ) ) . '">'. esc_html( antispambot( $content ) ) . '</a>';

    y así funciona bien.

    Moderador almendron

    (@almendron)

    Respecto al plugin:

    1) He puesto 'hex_encoding' => 1, para activar «hex encoding».

    2) Lo anterior hace que al usar la dirección de correo como texto del enlace también aparezca codificada. Para solucionarlo, basta cambiar

    return '<a href="'. $url . '">' . antispambot( $email, $hex_encoding ) . '</a>';

    por

    return '<a href="'. $url . '">' . antispambot( $email ) . '</a>';

    Moderador almendron

    (@almendron)

    En cuanto a los menús, es incluso más sencillo.

    Paso 1. Añadir un elemento al menú usando un enlace personalizado y en el campo «URL» se añade el correo con la siguiente sintaxis: mailto:elcorreoquequieres@correo.com

    Paso 2. La función. Basta con añadir «add_filter( ‘nav_menu_link_attributes’, ‘security_remove_emails’, 20 );» para que funcione perfectamente.

    function security_remove_emails( $data ) {
        if ( is_array( $data ) || is_object( $data ) ) {
            return map_deep( $data, 'security_remove_emails' );
        }
    
        if ( $data && is_string( $data ) ) {
            $_data = preg_replace_callback( 
               '/([0-9a-z._%+-]+@[a-z0-9.-]+\.[a-z]{2,})/i',
               function ( $r ) {
                   if ( ! empty( $r[1] ) ) {
                       return antispambot( $r[1] );
                   }
                   return $r;
               }, 
               $data
            ); 
            if ( is_string( $_data ) ) {
                return $_data;
            }
        }
        return $data;
    }
    add_filter( 'nav_menu_link_attributes', 'security_remove_emails', 20 );
    Moderador almendron

    (@almendron)

    Por último y ya acabo, la función anterior aplicada a los post no me gusta.

    Ofusca correctamente la dirección pero la muestra como texto plano. Me gusta más el funcionamiento del plugin.

    Moderador almendron

    (@almendron)

    Total, que al final resulta que había un plugin 🙂

    https://wordpress.org/plugins/menu-email-antispam/

Viendo 13 respuestas - de la 1 a la 13 (de un total de 13)
  • El debate ‘Ofuscar email’ está cerrado a nuevas respuestas.