web-dev-qa-db-fra.com

Obtenir tous les messages (de tout type), une pièce jointe est utilisée dans

Il n'est pas facile de compter le nombre de publications auxquelles une image est attachée - WordPress n'en tient simplement pas compte. Il ne fait que garder trace de la publication sur laquelle une pièce jointe a été téléchargée (et même pas nécessairement utilisée là-bas).

enter image description here

Brancher

Pour vous aider à démarrer le plus rapidement possible, voici le code du plugin:

<?php
/**
 * Plugin Name: Media Count
 * Description: Adds a column to the media admin list table to show the count of posts
 */

add_filter( 'manage_media_columns', function( $cols, $detached )
{
    $cols['count'] = 'Count';
    $cols['size']  = 'Size';
    return $cols;
}, 10, 2 );

add_action( 'manage_media_custom_column', function( $col, $id )
{
    switch ( $col )
    {
        case 'size' :
            $meta = wp_get_attachment_metadata( $id );
            // Image
            isset( $meta['width'] )
                AND print "{$meta['width']} &times; {$meta['height']}";
            // Audio
            isset( $meta['bitrate'] )
                AND print "{$meta['length_formatted']} min";
            break;
        case 'count' :
            $att  = get_post_custom( $id );
            $file = $att['_wp_attached_file'][0];
            // Do not take full path as different image sizes could
            // have different month, year folders due to theme and image size changes
            $file  = pathinfo( $file, PATHINFO_FILENAME );
            // @TODO Fill in the blanks
            break;
    }
}, 10, 2 );

Question:

Comment compter le nombre de messages auxquels une pièce jointe est utilisée - de la manière la plus efficace.

Plugin final

Le plugin complet peut êtretéléchargé en tant que Gist ici.

4
kaiser

Deuxième passage . Problèmes connus:

  • Nécessite la mise en cache (et le cache doit être nettoyé si possible)
  • Les types de message sont codés en dur
  • Quels sont les statuts de poste qui nous intéressent?

Voici la fonction:

/**
 * Given an attachment ID, searches for any post with that attachment used
 * as a featured image, or if it is present in the content of the post.
 * (Note above known issues).
*/
function get_image_count( $id ){
    global $wpdb;

    $att  = get_post_custom( $id );
    $file = $att['_wp_attached_file'][0];
    //Do not take full path as different image sizes could
    // have different month, year folders due to theme and image size changes
    $file = sprintf( "%s.%s",
        pathinfo( $file, PATHINFO_FILENAME ),
        pathinfo( $file, PATHINFO_EXTENSION )
    );

    $sql = "SELECT {$wpdb->posts}.ID 
        FROM {$wpdb->posts} 
        INNER JOIN {$wpdb->postmeta} 
        ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id) 
        WHERE {$wpdb->posts}.post_type IN ('post', 'page', 'event') 
        AND (({$wpdb->posts}.post_status = 'publish')) 
        AND ( ({$wpdb->postmeta}.meta_key = '_thumbnail_id' 
            AND CAST({$wpdb->postmeta}.meta_value AS CHAR) = '%d') 
            OR ( {$wpdb->posts}.post_content LIKE %s )
        ) 
        GROUP BY {$wpdb->posts}.ID";

    $prepared_sql = $wpdb->prepare( $sql, $id, "%src=\"%".$wpdb->esc_like( $file )."\"%" );

    $post_ids  = $wpdb->get_results( $prepared_sql );

    $count = count( $post_ids );

    return $count;
}
4
Stephen Harris

Juste comme un ajout, comme une amélioration pour tenir compte de différentes tailles d'image, je voudrais faire:

$file_name      = pathinfo( $file, PATHINFO_FILENAME );
$file_extension = '.' . pathinfo( $file, PATHINFO_EXTENSION );

Au lieu d'avoir une valeur combinée pour $file.

Et modifiez la préparation SQL pour:

$prepared_sql =
    $wpdb->prepare(
        $sql,
        $id,
        "%src=\"%"
            . like_escape( $file_name )
            . "%"
            . like_escape( $file_extension )
            . "\"%"
    );



Le deuxième ajout est un exemple qui utilise la fonctionnalité REGEXP/RLIKE de MySQL, mais il obtient également des images simplement liées dans une balise a. En outre, il est capable - contrairement au premier ajout, qui ne récupère que la taille complète téléchargée - de obtenir une image indépendante de la taille de l'image - où, par exemple, "the-image.jpg" serait en taille réelle et "the-image-150x150.jpg" une taille générée - utilisée:

$file_name      = pathinfo( $file, PATHINFO_FILENAME );
// beware different syntax
$file_extension = '[[...]]'.pathinfo( $file, PATHINFO_EXTENSION );

$sql = "SELECT {$wpdb->posts}.ID 
    FROM {$wpdb->posts} 
    INNER JOIN {$wpdb->postmeta} 
    ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id) 
    WHERE {$wpdb->posts}.post_type IN ('post', 'page', 'event') 
    AND (({$wpdb->posts}.post_status = 'publish')) 
    AND ( ({$wpdb->postmeta}.meta_key = '_thumbnail_id' 
        AND CAST({$wpdb->postmeta}.meta_value AS CHAR) = '%d') 
        OR ( {$wpdb->posts}.post_content REGEXP %s )
    ) 
    GROUP BY {$wpdb->posts}.ID";

$exp =
    '([[.<.]])' // tag start
        . '(img|a)' // define tag types
        . '.*' // other attributes void
        . '(src|href)' // define anchor(s) attribute
        . '=([[.".]]|[[.\'.]])' // quotes
        . '.*' // path/URL void
        . $file_name
        . '.*' // image size void
        . $file_extension
        . '([[.".]]|[[.\'.]])' // quotes
        . '.*' // other attributes void
        . '([[.>.]])' // tag end
    ;

$prepared_sql =
    $wpdb->prepare(
        $sql,
        $id,
        $exp
    );

$post_ids  = $wpdb->get_results( $prepared_sql );
2
Nicolai