it-swarm.cn

限制用户仅查看他们上传的媒体库项目?

我希望用户能够使用add_cap('upload_files')上传照片,但在其个人资料页面中,媒体库会显示已上传的每张图片。如何过滤,以便他们只能查看图像 他们 上传?

这是我目前的解决方案......我正在做一个简单的WP查询,然后在用户的“个人资料”页面上进行循环

$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

您始终可以使用pre_get_posts过滤器来过滤媒体列表,该过滤器首先确定页面和用户的功能,并在满足特定条件时设置author参数。

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;
}

我使用删除页面上限作为条件,因此管理员和编辑仍然可以看到完整的媒体列表。

有一个小的副作用,我看不到任何钩子,这是与媒体列表上方显示的附件计数(它仍将显示媒体项目的总数,而不是给定用户的总数 - 我是考虑这是一个小问题但是)。

以为我会发布所有相同的,可能是有用的..;)

37
t31os

从WP 3.7开始,通过ajax_query_attachments_args过滤器有一个更好的方法,如 documentation 中所提供的:

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

这是一个完整的帖子和媒体解决方案(此代码专门针对作者,但您可以为任何用户角色更改它)。这也可以修复帖子/媒体计数,而不会破坏核心文件。

// 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

这是 接受的答案 的修改版本。由于接受的答案仅针对左侧的“媒体”菜单项,因此用户在将照片上传到帖子时仍可以在模式框中看到整个媒体库。这个稍微修改过的代码修复了这种情况。目标用户只能在帖子中弹出的模式框的“媒体库”选项卡中看到自己的媒体项目。

这是接受答案的代码,注释标记要编辑的行...

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;
}

要让用户只能从上传模式的“媒体”菜单和“媒体库”选项卡中查看自己的媒体,请用此替换指示的行...

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

仅为了便于阅读而插入换行符和间距

以下内容与上述相同,但也限制他们从帖子菜单项中查看自己的帖子。

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

仅为了便于阅读而插入换行符和间距

Notes:在接受的答案中,帖子和媒体计数器将是错误的。但是,在此页面的其他一些答案中有解决方案。我没有合并那些只是因为我没有测试过它们。

5
Sparky

t31os在那里有一个很好的解决方案。唯一的问题是所有帖子的数量仍然显示出来。

我想出了一种方法来保持数字计数不会出现使用jQuery。

只需将其添加到您的函数文件中。

    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');

它对我有用!

2
user15182

完整的工作代码..唯一的问题是,在“添加帖子”页面上的媒体库中获取错误的图像数量。

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

一种方法是使用 Role Scoper插件 ,它非常适合管理非常具体的角色和功能。实际上,您可以将对媒体库中图像的访问权限仅锁定为每个用户上传的图像。我一直在将它用于我正在进行的项目,它运作良好。

1
Rick Curran

我用一个非常粗糙但可行的解决方案解决了我的问题。

1)我安装了WP隐藏仪表板插件,因此用户只能看到其配置文件编辑表单的链接。

2)在author.php模板文件中,我插入了上面使用的代码。

3)然后,对于登录用户,我显示了上传页面“wp-admin/media-new.php”的直接链接

4)我注意到的下一个问题是,在他们上传照片之后,它会将它们重定向到upload.php ......他们可以看到所有其他图片。我还没有找到media-new.php页面的钩子,所以我最终攻击了核心“media-upload.php”并将它们重定向到他们的个人资料页面:

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

然后用wp_redirect( admin_url($location) );替换wp_redirect($userredirect);

但是有几个问题。首先,登录用户仍然可以转到“upload.php”,如果他们知道它存在的话。他们不能做任何事情,除了LOOK的文件,99%的人甚至不知道它,但它仍然不是最佳的。其次,它还会在上传后将管理员重定向到个人资料页面。通过检查用户角色并仅重定向订阅服务器,可以进行相当简单的修复。

如果有人有关于挂钩到媒体页面的想法而不进入核心文件,我会很感激。谢谢!

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' );
?>

将上面的代码保存为manage_your_media_only.php,压缩它,作为插件上传到WP并激活它,就是这样。

1
Philip Borisov