webentwicklung-frage-antwort-db.com.de

Einschränken, dass Benutzer nur Medienbibliothekselemente anzeigen, die sie hochgeladen haben?

Ich möchte, dass Benutzer Fotos mit add_cap('upload_files') hochladen können, aber auf ihrer Profilseite werden in der Medienbibliothek alle hochgeladenen Bilder angezeigt. Wie kann ich das filtern, damit sie nur die Bilder sehen sie hochgeladen?

Hier ist meine Lösung für den Moment ... Ich führe eine einfache WP-Abfrage durch und dann eine Schleife auf der Seite "Profil" des Benutzers

$querystr = " SELECT wposts.post_date,wposts.post_content,wposts.post_title, guid 
FROM $wpdb->posts wposts
WHERE wposts.post_author = $author 
AND wposts.post_type = 'attachment' 
ORDER BY wposts.post_date DESC";

$pageposts = $wpdb->get_results($querystr, OBJECT);
45
TerryMatula

Sie können die Medienliste jederzeit mit einem pre_get_posts-Filter filtern, der zuerst die Seite und die Funktionen des Benutzers bestimmt und den author-Parameter festlegt, wenn bestimmte Bedingungen erfüllt sind.

Beispiel

add_action('pre_get_posts','users_own_attachments');
function users_own_attachments( $wp_query_obj ) {

    global $current_user, $pagenow;

    $is_attachment_request = ($wp_query_obj->get('post_type')=='attachment');

    if( !$is_attachment_request )
        return;

    if( !is_a( $current_user, 'WP_User') )
        return;

    if( !in_array( $pagenow, array( 'upload.php', 'admin-ajax.php' ) ) )
        return;

    if( !current_user_can('delete_pages') )
        $wp_query_obj->set('author', $current_user->ID );

    return;
}

Ich habe das Löschen von Seiten als Bedingung verwendet, damit Administratoren und Redakteure immer noch die vollständige Medienliste sehen.

Es gibt einen kleinen Nebeneffekt, für den ich keine Haken sehen kann, und zwar mit der Anzahl der Anhänge über der Medienliste (die immer noch die Gesamtzahl der Medienelemente anzeigt, nicht die des angegebenen Benutzers - ich würde halte dies jedoch für ein kleines Problem).

Dachte, ich würde es trotzdem posten, könnte nützlich sein ..;)

37
t31os

Ab WP 3.7 gibt es einen viel besseren Weg über den ajax_query_attachments_args-Filter, wie in der Dokumentation beschrieben:

add_filter( 'ajax_query_attachments_args', 'show_current_user_attachments' );

function show_current_user_attachments( $query ) {
    $user_id = get_current_user_id();
    if ( $user_id ) {
        $query['author'] = $user_id;
    }
    return $query;
}
30
David

Hier finden Sie eine vollständige Lösung für Posts und Medien (dieser Code richtet sich speziell an Autoren, Sie können ihn jedoch für jede Benutzerrolle ändern). Dies behebt auch die Anzahl der Posts/Medien, ohne die Kerndateien zu hacken.

// Show only posts and media related to logged in author
add_action('pre_get_posts', 'query_set_only_author' );
function query_set_only_author( $wp_query ) {
    global $current_user;
    if( is_admin() && !current_user_can('edit_others_posts') ) {
        $wp_query->set( 'author', $current_user->ID );
        add_filter('views_edit-post', 'fix_post_counts');
        add_filter('views_upload', 'fix_media_counts');
    }
}

// Fix post counts
function fix_post_counts($views) {
    global $current_user, $wp_query;
    unset($views['mine']);
    $types = array(
        array( 'status' =>  NULL ),
        array( 'status' => 'publish' ),
        array( 'status' => 'draft' ),
        array( 'status' => 'pending' ),
        array( 'status' => 'trash' )
    );
    foreach( $types as $type ) {
        $query = array(
            'author'      => $current_user->ID,
            'post_type'   => 'post',
            'post_status' => $type['status']
        );
        $result = new WP_Query($query);
        if( $type['status'] == NULL ):
            $class = ($wp_query->query_vars['post_status'] == NULL) ? ' class="current"' : '';
            $views['all'] = sprintf(
            '<a href="%1$s"%2$s>%4$s <span class="count">(%3$d)</span></a>',
            admin_url('edit.php?post_type=post'),
            $class,
            $result->found_posts,
            __('All')
        );
        elseif( $type['status'] == 'publish' ):
            $class = ($wp_query->query_vars['post_status'] == 'publish') ? ' class="current"' : '';
            $views['publish'] = sprintf(
            '<a href="%1$s"%2$s>%4$s <span class="count">(%3$d)</span></a>',
            admin_url('edit.php?post_type=post'),
            $class,
            $result->found_posts,
            __('Publish')
        );
        elseif( $type['status'] == 'draft' ):
            $class = ($wp_query->query_vars['post_status'] == 'draft') ? ' class="current"' : '';
            $views['draft'] = sprintf(
            '<a href="%1$s"%2$s>%4$s <span class="count">(%3$d)</span></a>',
            admin_url('edit.php?post_type=post'),
            $class,
            $result->found_posts,
            __('Draft')
        );
        elseif( $type['status'] == 'pending' ):
            $class = ($wp_query->query_vars['post_status'] == 'pending') ? ' class="current"' : '';
            $views['pending'] = sprintf(
            '<a href="%1$s"%2$s>%4$s <span class="count">(%3$d)</span></a>',
            admin_url('edit.php?post_type=post'),
            $class,
            $result->found_posts,
            __('Pending')
        );
        elseif( $type['status'] == 'trash' ):
            $class = ($wp_query->query_vars['post_status'] == 'trash') ? ' class="current"' : '';
            $views['trash'] = sprintf(
            '<a href="%1$s"%2$s>%4$s <span class="count">(%3$d)</span></a>',
            admin_url('edit.php?post_type=post'),
            $class,
            $result->found_posts,
            __('Trash')
        );
        endif;
    }
    return $views;
}

// Fix media counts
function fix_media_counts($views) {
    global $wpdb, $current_user, $post_mime_types, $avail_post_mime_types;
    $views = array();
    $count = $wpdb->get_results( "
        SELECT post_mime_type, COUNT( * ) AS num_posts 
        FROM $wpdb->posts 
        WHERE post_type = 'attachment' 
        AND post_author = $current_user->ID 
        AND post_status != 'trash' 
        GROUP BY post_mime_type
    ", ARRAY_A );
    foreach( $count as $row )
        $_num_posts[$row['post_mime_type']] = $row['num_posts'];
    $_total_posts = array_sum($_num_posts);
    $detached = isset( $_REQUEST['detached'] ) || isset( $_REQUEST['find_detached'] );
    if ( !isset( $total_orphans ) )
        $total_orphans = $wpdb->get_var("
            SELECT COUNT( * ) 
            FROM $wpdb->posts 
            WHERE post_type = 'attachment'
            AND post_author = $current_user->ID 
            AND post_status != 'trash' 
            AND post_parent < 1
        ");
    $matches = wp_match_mime_types(array_keys($post_mime_types), array_keys($_num_posts));
    foreach ( $matches as $type => $reals )
        foreach ( $reals as $real )
            $num_posts[$type] = ( isset( $num_posts[$type] ) ) ? $num_posts[$type] + $_num_posts[$real] : $_num_posts[$real];
    $class = ( empty($_GET['post_mime_type']) && !$detached && !isset($_GET['status']) ) ? ' class="current"' : '';
    $views['all'] = "<a href='upload.php'$class>" . sprintf( __('All <span class="count">(%s)</span>', 'uploaded files' ), number_format_i18n( $_total_posts )) . '</a>';
    foreach ( $post_mime_types as $mime_type => $label ) {
        $class = '';
        if ( !wp_match_mime_types($mime_type, $avail_post_mime_types) )
            continue;
        if ( !empty($_GET['post_mime_type']) && wp_match_mime_types($mime_type, $_GET['post_mime_type']) )
            $class = ' class="current"';
        if ( !empty( $num_posts[$mime_type] ) )
            $views[$mime_type] = "<a href='upload.php?post_mime_type=$mime_type'$class>" . sprintf( translate_nooped_plural( $label[2], $num_posts[$mime_type] ), $num_posts[$mime_type] ) . '</a>';
    }
    $views['detached'] = '<a href="upload.php?detached=1"' . ( $detached ? ' class="current"' : '' ) . '>' . sprintf( __( 'Unattached <span class="count">(%s)</span>', 'detached files' ), $total_orphans ) . '</a>';
    return $views;
}
19
Paul

Dies ist eine modifizierte Version von der akzeptierten Antwort . Da die akzeptierte Antwort nur auf das Menüelement Medien auf der linken Seite zielt, können Benutzer beim Hochladen eines Fotos in einen Beitrag weiterhin die gesamte Medienbibliothek im modalen Feld sehen. Dieser leicht geänderte Code behebt diese Situation. Die Zielbenutzer sehen nur ihre eigenen Medienelemente auf der Registerkarte Medienbibliothek des Modalfelds, das in einem Beitrag angezeigt wird.

Dies ist der Code aus der akzeptierten Antwort mit einem Kommentar, der die zu bearbeitende Zeile markiert ...

add_action('pre_get_posts','users_own_attachments');
function users_own_attachments( $wp_query_obj ) {

    global $current_user, $pagenow;

    if( !is_a( $current_user, 'WP_User') )
        return;

    if( 'upload.php' != $pagenow ) // <-- let's work on this line
        return;

    if( !current_user_can('delete_pages') )
        $wp_query_obj->set('author', $current_user->id );

    return;
}

Wenn Benutzer ihre eigenen Medien nur über das Menü Medien UND die Registerkarte Medienbibliothek des Upload-Modals anzeigen möchten, ersetzen Sie die angezeigte Zeile durch ...

if( (   'upload.php' != $pagenow ) &&
    ( ( 'admin-ajax.php' != $pagenow ) || ( $_REQUEST['action'] != 'query-attachments' ) ) )

(Zeilenumbrüche und Abstände werden hier nur zur besseren Lesbarkeit eingefügt)

Das Folgende ist dasselbe wie oben, beschränkt sie jedoch auch darauf, ihre eigenen Beiträge über den Menüpunkt Beiträge zu sehen.

if( (   'edit.php' != $pagenow ) &&
    (   'upload.php' != $pagenow ) &&
    ( ( 'admin-ajax.php' != $pagenow ) || ( $_REQUEST['action'] != 'query-attachments' ) ) )

(Zeilenumbrüche und Abstände werden hier nur zur besseren Lesbarkeit eingefügt)

Notizen: Wie in der akzeptierten Antwort sind die Posts und Medienzähler falsch. In einigen anderen Antworten auf dieser Seite gibt es jedoch Lösungen dafür. Ich habe es nicht getan integriere diese einfach, weil ich sie nicht getestet habe.

5
Sparky

t31os hat da oben eine großartige Lösung. Das einzige, was ist, dass die Anzahl aller Beiträge noch angezeigt wird.

Ich habe einen Weg gefunden, um zu verhindern, dass die Anzahl der Zahlen mit jQuery angezeigt wird.

Fügen Sie dies einfach Ihrer Funktionsdatei hinzu.

    function jquery_remove_counts()
{
    ?>
    <script type="text/javascript">
    jQuery(function(){
        jQuery("ul.subsubsub").find("span.count").remove();
    });
    </script>
    <?php
}
add_action('admin_head', 'jquery_remove_counts');

Es funktioniert für mich!

2
user15182

Vollständiger Arbeitscode. Das einzige Problem ist, dass die Anzahl der Bilder in der Medienbibliothek auf der Seite "Beitrag hinzufügen" falsch ist.

function my_files_only( $wp_query ) {
if ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/upload.php' ) !== false ) {
    if ( !current_user_can( 'level_5' ) ) {
        global $current_user;
        $wp_query->set( 'author', $current_user->id );
    }
}
else if ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/media-upload.php' ) !== false ) {
    if ( !current_user_can( 'level_5' ) ) {
        global $current_user;
        $wp_query->set( 'author', $current_user->id );
    }
}
}
add_filter('parse_query', 'my_files_only' );
2
Nitin

Eine Möglichkeit, dies zu tun, ist die Verwendung des Role Scoper-Plugins , das sich auch hervorragend zum Verwalten sehr spezifischer Rollen und Funktionen eignet. Sie können den Zugriff auf Bilder in der Medienbibliothek nur für die von jedem Benutzer hochgeladenen Bilder sperren. Ich habe es für ein Projekt verwendet, an dem ich gerade arbeite, und es funktioniert gut.

1
Rick Curran

Ich habe mein Problem mit einer ziemlich groben, aber praktikablen Lösung gelöst.

1) Ich habe das WP Hide Dashboard-Plugin installiert, sodass dem Benutzer nur ein Link zu seinem Profilbearbeitungsformular angezeigt wird.

2) In die author.php-Vorlagendatei habe ich den oben verwendeten Code eingefügt.

3) Dann habe ich für angemeldete Benutzer einen direkten Link zur Upload-Seite "wp-admin/media-new.php" angezeigt

4) Das nächste Problem, das mir aufgefallen ist, war, dass sie nach dem Hochladen des Fotos zu upload.php weitergeleitet wurden und alle anderen Bilder sehen konnten. Ich habe keinen Haken in der Seite media-new.php gefunden, also habe ich mich in die zentrale Datei "media-upload.php" gehackt und sie auf ihre Profilseite weitergeleitet:

    global $current_user;
    get_currentuserinfo();
    $userredirect =  get_bloginfo('home') . "/author/" .$current_user->user_nicename;

Dann wp_redirect( admin_url($location) ); durch wp_redirect($userredirect); ersetzt

Ein paar Probleme. Erstens kann der angemeldete Benutzer immer noch zu "upload.php" gehen, wenn er weiß, dass es existiert. Sie können nichts anderes tun, als die Akten anzuschauen, und 99% der Leute wissen nicht einmal davon, aber es ist immer noch nicht optimal. Zweitens wird der Administrator nach dem Hochladen auch zur Profilseite umgeleitet. Diese Probleme können relativ einfach behoben werden, indem Benutzerrollen überprüft und nur Abonnenten umgeleitet werden.

Wenn jemand Ideen hat, wie man sich in die Medienseite einbinden kann, ohne in die Kerndateien zu gehen, würde ich das begrüßen. Vielen Dank!

1
TerryMatula
<?php
/*
Plugin Name: Manage Your Media Only
Version: 0.1
*/

//Manage Your Media Only
function mymo_parse_query_useronly( $wp_query ) {
    if ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/upload.php' ) !== false ) {
        if ( !current_user_can( 'level_5' ) ) {
            global $current_user;
            $wp_query->set( 'author', $current_user->id );
        }
    }
}

add_filter('parse_query', 'mymo_parse_query_useronly' );
?>

Speichern Sie den obigen Code als manage_your_media_only.php, komprimieren Sie ihn, laden Sie ihn als Plugin in Ihr WP hoch und aktivieren Sie ihn, das ist alles.

1
Philip Borisov