6

Can I list all files uploaded by users in Network sites? In Multisite each user can manage their files with their own blog but the Super admin can't monitor all the uploaded files...how can i do that?

1
  • Nice idea and great code in response, kudos to @all! I imagined a Media network menu to show all network media list, with pagination and stuff. If a plugin already exists or someone goes further with the idea, please report ;)
    – brasofilo
    Commented Apr 21, 2013 at 15:14

2 Answers 2

9

You have to run through each blog and fetch the recent attachments with:

$args    = array (
    'post_type'   => 'attachment',
    'numberposts' => 30
);
$attachments = get_posts( $args );

Dashboard widgets are registered on wp_network_dashboard_setup in multi-site and wp_dashboard_setup in single-site.

Make sure to add the following line to the plugin header to get the plugin network enabled:

 * Network:     true 

Then you can get a table like this:

enter image description here

(from my local dev site, yes, it looks a little bit strange)

Sample plugin, very raw!

<?php # -*- coding: utf-8 -*-
/**
 * Plugin Name: List recent uploads in a network
 * Version:     2013.04.21
 * Network:     true
 */

if ( is_multisite() )
    add_action(
        'wp_network_dashboard_setup',
        array ( 'T5_Recent_Uploads_Dashboard_Widget', 'register' )
    );
else
    add_action(
        'wp_dashboard_setup',
        array ( 'T5_Recent_Uploads_Dashboard_Widget', 'register' )
    );

class T5_Recent_Uploads_Dashboard_Widget
{
    protected static $instance = NULL;

    protected $max_items = 30;

    public static function register()
    {
        self::$instance = new self;

        wp_add_dashboard_widget(
            __CLASS__,
            'Recent Uploads',
            array ( self::$instance, 'render' )
        );
    }

    public function render()
    {
        $uploads = $this->get_recent_uploads();

        if ( empty ( $uploads ) )
            return print '<p>No new uploads</p>';

        printf( '<p>%d new uploads.</p>', count( $uploads ) );

        print $this->get_attachment_table( $uploads );

        // inspect content here
        //print '<pre>$uploads = ' . htmlspecialchars( var_export( $uploads, TRUE ), ENT_QUOTES, 'utf-8', FALSE ) . '</pre>';
    }

    protected function get_recent_uploads()
    {
        if ( ! is_multisite() )
            return $this->get_attachments();

        $uploads      = array();
        $current_blog = get_current_blog_id();
        $blogs        = $this->get_blog_ids();

        foreach ( $blogs as $blog )
        {
            switch_to_blog( $blog->blog_id );
            $attachments = $this->get_attachments();

            foreach ( $attachments as $attachment )
                $uploads[] = $this->prepare_attachment( $attachment, $blog );
        }

        // restore current blog
        switch_to_blog( $current_blog );

        return array_slice( $uploads, 0, $this->max_items );
    }

    protected function prepare_attachment( $attachment, $blog )
    {
        $attachment->blog_id   = $blog->blog_id;
        $attachment->blog_name = get_bloginfo( 'name' );
        $attachment->edit      = get_edit_post_link( $attachment->ID );

        return $attachment;
    }

    protected function get_blog_ids()
    {
        global $wpdb;

        $query = $wpdb->prepare(
            "SELECT blog_id
                FROM $wpdb->blogs
                WHERE site_id    = %d
                AND public   = '1'
                AND archived = '0'
                AND mature   = '0'
                AND spam     = '0'
                AND deleted  = '0'
                ORDER BY blog_id",
            $wpdb->siteid
        );

        return $wpdb->get_results( $query );
    }

    protected function get_attachment_table( $attachments )
    {
        $table = '<table class="widefat">' . $this->get_table_header() . '<tbody>';

        foreach ( $attachments as $attachment )
            $table .= $this->get_row( $attachment );

        return "$table</tbody></table>";
    }

    protected function get_attachments()
    {
        $args    = array (
            'post_type'   => 'attachment',
            'numberposts' => $this->max_items
        );

        return get_posts( $args );
    }

    protected function get_table_header()
    {
        $columns = array ( 'Attachment', 'User', 'Date' );

        if ( is_multisite() )
            $columns[] = 'Site';

        $header  = '<tr><th>' . join( '</th><th>', $columns ) . '</th></tr>';
        return "<thead>$header</thead><tfoot>$header</tfoot>";

    }

    protected function get_row( $attachment )
    {
        $cells   = array ();
        $cells[] = $this->get_attachment_title( $attachment );
        $cells[] = $this->get_user_link( $attachment );
        $cells[] = mysql2date( 'Y.m.d', $attachment->post_date );

        if ( is_multisite() )
            $cells[] = $attachment->blog_name;

        return '<tr><td>' . join( '</td><td>', $cells ) . '</td></tr>';
    }

    protected function get_attachment_title( $attachment )
    {
        $title = $attachment->post_title;

        if ( empty ( $title ) )
            $title = basename( $attachment->guid );

        return "<a href='$attachment->edit'>$title</a>";
    }

    protected function get_user_link( $attachment )
    {
        $name = get_the_author_meta( 'nickname', $attachment->post_author );
        $url = network_admin_url( 'user-edit.php?user_id=' . $attachment->post_author );

        return "<a href='$url'>$name</a>";
    }
}
4
  • thank you! work fine ! the list is permanent? there will be pages to shorten the list if very long? thank you! Commented Apr 21, 2013 at 14:53
  • 3
    @Ghinnersmee I made a small update: The list will be at max 30 items long, but you can edit $max_items to change that.
    – fuxia
    Commented Apr 21, 2013 at 14:55
  • 1
    Maybe a small change for use transient caching and it is so much fine and simple solution.
    – bueltge
    Commented Apr 21, 2013 at 16:53
  • 1
    @Ghinnersmee You could switch and use the WP_List_Table. Then you get pagination for free... more work as well :)
    – kaiser
    Commented Apr 21, 2013 at 17:58
1

WordPress 3.7 introduced wp_get_sites() which will return an array of sites in a WordPress Multisite network. This can replace get_blog_ids().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.