web-dev-qa-db-fra.com

Désactivation des images de publication pour les utilisateurs non connectés

Existe-t-il un moyen intéressant de désactiver les personnages/images d'une certaine catégorie de publication jusqu'à ce qu'un utilisateur se connecte? Je souhaite que tout le contenu de la publication soit visible, à l'exception des images.

Je ne suis pas un programmeur et je n'ai trouvé aucun plugin utile.

2
Adam Robinsson

Vous pouvez utiliser PHP strip_tags et vous connecter à the_content filtrer en vérifiant si l’utilisateur est connecté .

ajoutez ceci à votre fichier functions.php

add_filter( 'the_content', 'wpse_remove_img' );
function wpse_remove_img( $content ){

  if( ! is_user_logged_in() ){

    // You need to specify which tag you want to keep here it's p, a, h2,span, div.
    // Adjust accordingly (you might want to add other or remove all)
    $content = strip_tags($content, '<p><a><h2><span><div>'); 


  }

  return $content;

}

MODIFIER

Si vous souhaitez remplacer l'image à la place, j'utiliserais PHP DOMDocument pour effectuer la recherche et le remplacer.

Notez que vous pouvez rencontrer certains problèmes d’encodage de texte ou d’avertissements pour certaines balises HTML5. Hakre explique en détail pourquoi cela peut arriver et Gordon l'explique bien, les deux sur StackExchange.

Dans ma solution ci-dessous, je m'en suis occupé en définissant le codage avant le chargement du $content. Et la désactivation temporaire des erreurs libxml afin que nous ne soyons pas gênés par des avertissements en utilisant libxml_use_internal_errors

encore une fois, cela va dans votre functions.php

add_filter( 'the_content', 'wpse_replace_img' );
function wpse_replace_img( $content ){

  if( ! is_user_logged_in() ){

    $dom = new DOMDocument();

    libxml_use_internal_errors(true); // deactivating errors
    // Load without added HTML and doctype, see https://stackoverflow.com/a/22490902/4643867
    $dom->loadHTML( '<?xml encoding="UTF-8">' . $content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD ); // adding encoding
    libxml_use_internal_errors(false); // reactivating errors

    $tags = $dom->getElementsByTagName( 'img' );

    foreach ($tags as $img) {
      $new_src_url = 'http://url/to/your/filler-image.jpg';
            $img->setAttribute( 'src', $new_src_url );
            $img->setAttribute( 'srcset', '' );

    }

    $content = $dom->saveHTML();

  }

  return $content;

}

MODIFIER

Ok, voici une édition qui prend en compte le fait d'encapsuler les balises <a> autour des images. Cette première solution remplacera le lien vers l'image par un #

add_filter( 'the_content', 'wpse_replace_img' );
function wpse_replace_img( $content ){

  if( ! is_user_logged_in() ){

    $dom = new DOMDocument();

    libxml_use_internal_errors(true);
    // Load without added HTML and doctype, see https://stackoverflow.com/a/22490902/4643867
    $dom->loadHTML( '<?xml encoding="UTF-8">' . $content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD ); // adding encoding
    libxml_use_internal_errors(false);

    $tags  = $dom->getElementsByTagName( 'img' );

    foreach ($tags as $img) {
      $new_src_url = 'http://url/to/your/filler-image.jpg';
      $img->setAttribute( 'src', $new_src_url );
      $img->setAttribute( 'srcset', '' );

      if( $img->parentNode->tagName == 'a' ){ // if the current image is wrapped by an <a> tag, replace href link with an #

        $img->parentNode->setAttribute( 'href', '#' );

      }

    }

    $content = $dom->saveHTML();

  }

  return $content;

}

Ensuite, vous pouvez également supprimer complètement la balise <a>. Avec l'aide de matb33 sur stackoverflow, j'ai réussi à trouver cette solution.

add_filter( 'the_content', 'wpse_replace_img' );
function wpse_replace_img( $content ){

  if( ! is_user_logged_in() ){

    $dom = new DOMDocument();

    libxml_use_internal_errors(true);
    // Load without added HTML and doctype, see https://stackoverflow.com/a/22490902/4643867
    $dom->loadHTML( '<?xml encoding="UTF-8">' . $content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD ); // adding encoding
    libxml_use_internal_errors(false);

    $tags  = $dom->getElementsByTagName( 'img' );
    $fragment = $dom->createDocumentFragment();  // Create our new document fragment to manipulate


    foreach ($tags as $img) {
      $new_src_url = 'http://url/to/your/filler-image.jpg';
      $img->setAttribute( 'src', $new_src_url );
      $img->setAttribute( 'srcset', '' );

      if( $img->parentNode->tagName == 'a' ){ // if the current image has an  <a> tag as a parent apply replace our <a> tag with our <img> tag

        $a = $img->parentNode;
        $fragment->appendChild( $img->parentNode->childNodes->item( 0 ) ) ; // store our image node into the fragment
        $a->parentNode->replaceChild( $fragment, $a ); // replace our <a> tag with our <img> tag

      }

    }

    $content = $dom->saveHTML();

  }

  return $content;

}

MODIFIER

Et voici comment appliquer uniquement à des catégories spécifiques

add_filter( 'the_content', 'wpse_replace_img' );
function wpse_replace_img( $content ){

  if( ! is_user_logged_in() ){

    $apply_restriction = false;
    $categories = get_the_category();
    $restricted_cat = array(
        'restricted_cat_slug' // Our restricted category slug, since it's an array you could provide more than one
    );


    // Performing our check, switch the flag if we find a match
    foreach( $categories as $cat ){
        foreach( $restricted_cat as $r_cat ){
            if( $cat->slug == $r_cat ){
                $apply_restriction = true;
            }
        }
    }

    // Bail out without applying any restriction if no category match is found
    if( ! $apply_restriction ){
        return $content;
    }

    $dom = new DOMDocument();

    libxml_use_internal_errors(true);
    // Load without added HTML and doctype, see https://stackoverflow.com/a/22490902/4643867
    $dom->loadHTML( '<?xml encoding="UTF-8">' . $content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD ); // adding encoding
    libxml_use_internal_errors(false);

    $tags  = $dom->getElementsByTagName( 'img' );
    $fragment = $dom->createDocumentFragment();  // Create our new document fragment to manipulate


    foreach ($tags as $img) {
      $new_src_url = 'http://url/to/your/filler-image.jpg';
      $img->setAttribute( 'src', $new_src_url );
      $img->setAttribute( 'srcset', '' );

      if( $img->parentNode->tagName == 'a' ){ // if the current image has an  <a> tag as a parent apply replace our <a> tag with our <img> tag

        $a = $img->parentNode;
        $fragment->appendChild( $img->parentNode->childNodes->item( 0 ) ) ; // store our image node into the fragment
        $a->parentNode->replaceChild( $fragment, $a ); // replace our <a> tag with our <img> tag

      }

    }

    $content = $dom->saveHTML();

  }

  return $content;

}
2
bynicolas

Voici une suggestion pour supprimer des images, avec légende , pour les visiteurs (non connectés):

add_filter( 'img_caption_shortcode', function( $output, $attr, $content )
{
    $width = isset( $attr['width'] ) ? $attr['width'] : '300';
    $align = isset( $attr['align'] ) ? $attr['align'] : '';
    $class = isset( $attr['class'] ) ? $attr['class'] : 'no-image';

    $class = sprintf( 'wp-caption %s %s', $align, $class );

    return is_user_logged_in() 
        ? $output 
        : sprintf( 
            '<div class="%s" width="%d">%s</div>',
            esc_attr( $class ),
            (int) $width,
            esc_html__( 'Please log in to view the image', 'mydomain' )
        );
}, 10, 3 );

c'est-à-dire que seules les images encapsulées dans le shortcode [caption] sont remplacées par un texte.

Le texte de la légende doit être non vide et la largeur non nulle.

J'espère que vous pourrez l'adapter à vos besoins.

Voici un exemple:

no-image

2
birgire