是否限制用户只能查看他们上传的媒体库项目?

时间:2010-09-07 作者:TerryMatula

我希望用户能够使用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);

8 个回复
最合适的回答,由SO网友:t31os 整理而成

您始终可以使用pre_get_posts 过滤器,首先确定页面和用户的功能,并在满足某些条件时设置作者参数。。

示例

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;
}
我使用了删除页面上限作为条件,以便管理员和编辑仍能看到完整的媒体列表。

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

我想我还是会把它贴上去,也许会有用……)

SO网友:David

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

SO网友:Paul

这是一个针对帖子和媒体的完整解决方案(此代码专门针对作者,但您可以针对任何用户角色对其进行更改)。这还可以在不破坏核心文件的情况下修复帖子/媒体数量。

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

SO网友:Sparky

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

这是来自已接受答案的代码,带有注释,标记要编辑的行。。。

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: 正如公认的答案一样,帖子和媒体计数器将是错误的。然而,在本页的其他一些答案中,也有解决方案。我并没有将它们合并,只是因为我没有测试它们

SO网友:Nitin

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

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

SO网友:user15182

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\');
这对我有用!

SO网友:TerryMatula

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

1) 我安装了WP Hide Dashboard插件,因此用户只能看到他们的个人资料编辑表单的链接。

2) 作者。php模板文件,我插入了上面使用的代码。

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

4) 我注意到的下一个问题是,在他们上传照片后,它会重定向他们进行上传。php。。。他们可以看到所有其他的照片。我还没有找到一个新的媒体。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”存在,他们仍然可以访问它。除了查看文件,他们什么都做不了,99%的人甚至不知道,但这仍然不是最佳选择。其次,它还会在上传后将管理员重定向到配置文件页面。通过检查用户角色,并且只重定向订阅者,可以很简单地修复这些问题。

如果有人想不进入核心文件而直接进入媒体页面,我将不胜感激。谢谢

SO网友:Rick Curran

一种方法是使用Role Scoper plugin, 它对于管理非常特定的角色和功能也很有用。实际上,您可以仅将对媒体库中图像的访问锁定为每个用户上载的图像。我一直在将其用于我目前正在进行的一个项目,效果很好。

结束

相关推荐