アップロードしたメディアライブラリアイテムのみを表示するようにユーザーを制限しますか?


46

ユーザーが写真をアップロードできるようにしたいのです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);

1
自分の問題に対する答えを見つけた場合は、質問自体ではなく、それを以下の答えとして追加することをお勧めします。これはシステムに沿った方が優れており、回答をアップ投票できます。これにより、このサイトでの評判が向上します。
ヤンファブリ


私は本当に「自分の投稿メディアのみを表示する」プラグインを2番目にする必要があります。jqueryまたはphp / html / cssソリューションを探した後、私にとっては完璧に機能しました。
ワッフル14年

回答:


37

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

削除ページの上限を条件として使用したため、管理者と編集者にはメディアの完全なリストが表示されます。

1つの小さな副作用があります。フックは表示されません。メディアリストの上に表示される添付ファイルのカウント(特定のユーザーではなくメディアアイテムの総数が表示されます-i'dただし、これは小さな問題だと考えてください)。

私はそれをすべて同じように投稿したいと思ったが、役に立つかもしれない..;)


購読者レベルのユーザーへのファイルのアップロードを許可しました。コードを使用しようとしましたが、機能していませんでした。
シシル

1
「機能していない」というのはあまり意味がありません。
t31os

同じ観察を確認できます。私にとって「機能していない」とは、「貢献者」の役割がjpgをアップロードするときにすべてのメディアアイテムを表示できることを意味します。ただし、メニューからメディアライブラリに移動すると、空になります。(私の「寄稿者」の役割には、ファイルをアップロードする追加の機能がすでにあり、それは機能しています。
Sparky 14

したがって、アップロードウィンドウの[メディアライブラリ]タブに表示されるページに合わせてコードを調整する必要があります。私は今これを研究しています。
スパーキー14

私が正しく思い出すと(そして間違いが起こる)、メディア数を修正するためにフックが配置されていなかったのと同様に、この回答を書いた時点で適切なフックがありませんでした。ただし、執筆時点からWordPressの新しいバージョンが3つありますので、解決策が可能になります。
t31os 14

32

WP 3.7の時点でajax_query_attachments_argsは、ドキュメントに記載されているように、フィルターを介したはるかに優れた方法があります

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

19

投稿とメディアの両方に対応する完全なソリューションを次に示します(このコードは特に著者向けですが、ユーザーロールに応じて変更できます)。これにより、コアファイルをハッキングすることなく投稿/メディアカウントも修正されます。

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

すばらしいスニペットですが、メディアライブラリーにアイテムがない場合、エラーを吐き出します。警告:array_sum()はパラメーター1が配列、nullが想定され、警告:array_keys()はパラメーター1が配列、nullが想定
chrismccoy

fix_media_counts()関数で$ _num_postsを配列として定義する必要があります。$_num_posts = array();
ポール

4
この回答のコードは機能しますが、Advanced Custom Fieldsプラグインによって作成されたカスタムフィールドも削除します。
スパーキー14

1
関連性が
高い

5

これは受け入れられた答えの変更されたバージョンです。受け入れられた回答は、左側の[メディア]メニュー項目のみを対象としているため、ユーザーは写真を投稿にアップロードするときに、モーダルボックス内のメディアライブラリ全体を表示できます。このわずかに変更されたコードは、その状況を修正します。対象ユーザーには、投稿内にポップアップ表示されるモーダルボックスの[メディアライブラリ]タブから自分のメディアアイテムのみが表示されます。

これは、承認された回答からのコードで、編集する行をマークするコメントが付いています...

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

ここでは読みやすくするために改行とスペースのみが挿入されています

:受け入れられた回答と同様に、投稿とメディアカウンターは間違っています。ただし、このページの他のいくつかの回答には、これに対する解決策があります。私はそれらをテストしなかったという理由だけでそれらを組み込みませんでした。


2

完全な作業コード。唯一の問題は、[投稿の追加]ページでメディアライブラリの画像のカウントが間違っていることです。

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
ユーザーレベルは使用しないでください。これらは主に下位互換性のためにWordPressにあり(WP 2.0以前)、現代のWordPressのユーザー機能を決定するための信頼性がありません(互換性が不要になるとコアから消える可能性が高いためです) )。実際の機能を使用してユーザー権限を決定します。
t31os

を含んmedia-upload.phpでいるにもかかわらず、コードはPost Editページによって生成されたアップロードモーダルから機能していません。すべてのライブラリアイテムを引き続き表示できます。
スパーキー14

2

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

それは私のために働いています!


1

私はかなり大雑把だが実行可能なソリューションで問題を解決しました。

1)WP Hide Dashboardプラグインをインストールしたため、ユーザーにはプロファイル編集フォームへのリンクのみが表示されます。

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」に移動できます(存在することがわかっている場合)。彼らはファイルを見る以外には何もできず、99%の人もそれを知りませんが、それでも最適ではありません。次に、アップロード後に管理者をプロファイルページにリダイレクトします。これらは、ユーザーロールをチェックし、サブスクライバーのみをリダイレクトすることにより、かなり単純な修正を行うことができます。

コアファイルにアクセスせずにMediaページに接続するアイデアをお持ちの方がいれば幸いです。ありがとう!


2
ありadmin_init、すべての管理者のリクエストで実行されますフックが。ユーザーがupload.phpをリクエストし、そのリクエストをブロックする(例:)か、wp_die('Access Denied')フックごとに有効な場所にリダイレクトするのを防ぎたい場合。
-hakre

1
<?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として保存し、zipで圧縮し、プラグインとしてWPにアップロードしてアクティブ化します。これで完了です。


1

これを行う1つの方法は、Role Scoperプラグインを使用することです。これは、非常に具体的なロールと機能の管理にも最適です。実際には、メディアライブラリ内の画像へのアクセスを各ユーザーがアップロードした画像のみにロックできます。私は現在取り組んでいるプロジェクトにそれを使用してきましたが、それはうまく機能しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.