web-dev-qa-db-ja.com

他のすべてのユーザー投稿ではなく、*一部*他のユーザー投稿にアクセスできるユーザーを作成できますか?

私はしばらくの間マルチユーザーWPサイトで基本的なユーザー権利の機能を使用してきました、そしてそれは素晴らしくうまくいきました。みんなの投稿へこれは、 wp-front プラグインによって支援されており、これを使用するとユーザーロールを簡単に定義できます。

しかし、私は今、同じ社外の会社で複数の作者が必要で、他の個人の仕事を監督する会社でも編集者が必要なシナリオがあります。

この新しいリモート編集者の役割は、自分の投稿と同じ会社の他の編集者によって作成された投稿を表示できるようにする必要があるため、新しくて問題があります。しかし、彼らは全員の投稿を見ることができてはいけません。

これは、wp-frontや他のプラグインでも、あるいは単にプラグインの外で手作りの解決策でも可能ですか?

理想的には、解決策はユーザーのコレクションを何らかの種類のグループに追加することで機能しますが、そうする必要はありません。

2
AdamJones

これが私のアプローチです。これはあなたが説明した基本的なニーズをカバーしていますが、より堅牢なソリューションに容易に拡張することができるということを心に留めておいてください。従うべきいくつかのステップ(すべてのコードはあなたのfunctions.phpに行きます):

1.会社名をユーザーメタとして保存する

私たちがする必要がある最初のことはユーザーに会社名を割り当てることです - 私はそれを達成するためにユーザーメタと行きます。管理しやすいようにメタボックスを編集してユーザー画面を編集することもできます。そのためのコードはここには含まれていませんが、そのアイデアを得たと確信しています。

テストのためにはupdate_user_meta( $user_id, 'company', 'Tyrell Corporation' );codex )でユーザーにmetaを追加することができます。

そのため、この例ではTyrell Corporationcompanyユーザーメタキーとして設定し、まったく同じメタを持つエディターを持つ著者がたくさんいると仮定します。

2.著者のユーザーメタに基づいて、会社メタを投稿に追加します。

物事をより簡単にそしてより安くするために、私は会社が割り当てられたどんな著者によっても保存されたすべての記事で会社名への参照を保持したいと思います。投稿を後で編集する権利)。それをするために、私はsave_posthook を使っています。

function save_company_meta( $post_id, $post, $update ) {
    // get author's company meta
    $company = get_user_meta( $post->post_author, 'company', true );

    if ( ! empty( $author_id ) ) {
        // add meta data to the post
        update_post_meta( $post_id, 'company', true );
    }
}

add_action( 'save_post', 'save_company_meta', 10, 3 );

現在、ユーザーが自分の下書きを保存するたびに、このユーザーに割り当てられている会社名がpost metaにコピーされます。

3.マップエディタのedit_post機能

最後に、 map editorの 'edit_post'機能を単純に使えます。投稿のcompanyメタデータがエディタのcompanyユーザメタと異なる場合は、この特定の投稿を編集する機能をその特定のエディタから外します。以下のコードには追加の条件がいくつかあります。たとえば、投稿にcompanyメタがまったく含まれていない場合やpost投稿タイプではない場合は、制限を適用しません。あなたはそれをあなたのニーズに合わせることができます:

function restrict_access_to_company_posts( $caps, $cap, $user_id, $args ) {

    /*
    We're messing with capabilities only if 'edit_post' 
    is currently checked and the current user has editor role
    but is not the administrator
    */

    if ( ! in_array( $cap, [ 'edit_post' ], true ) ) {
        return $caps;
    }

    if ( ! user_can( $user_id, 'editor' ) || user_can( $user_id, 'administrator' ) ) {
        return $caps;
    }

    /*
    $args[0] holds post ID. $args var is a bit enigmatic, it contains
    different stuff depending on the context and there's almost 
    no documentation on that, you've got to trust me on this one :)
    Anyways, if no post ID is set, we bail out and return default capabilities
    */
    if ( empty( $args[0] ) ) {
        return $caps;
    }

    /*
    You can also make sure that you're restricting access 
    to posts only and not pages or other post types
    */
    if ( 'post' !== get_post_type( $args[0] ) ) {
        return $caps;
    }

    $post_company   = get_post_meta( $args[0], 'company', true );
    $editor_company = get_user_meta( $user_id, 'company', true );

    /*
    if no meta data is set or editor is assigned 
    to the same company as the post, we allow normal editing
    */
    if ( empty( $post_company ) || $post_company === $editor_company ) {
        return $caps;
    }

    // finally, in all other cases, we restrict access to this post
    $caps = [ 'do_not_allow' ];

    return $caps;
}

これは管理UIから投稿を完全に隠すことはできません、あなたはまだリストにそれらを見ることができますが、エディタは投稿の編集画面に入ってそれを変更することもドラフトも見ることができません。フロントエンドの管理バーで)投稿が公開されても、編集者はまだ投稿のコンテンツを編集できません。

4.(オプション)管理者リストから投稿を完全に削除する

それでも上記の方法では不十分な場合は、pre_get_postscodex )にフックして管理者リストから投稿を完全に隠すこともできます。

function query_company_posts_only( $query ) {

    if ( ! is_admin() || empty( get_current_user_id() ) ) {
        return $query;
    }

    $editor_company = get_user_meta( get_current_user_id(), 'company', true );

    if ( empty( $editor_company ) ) {
        return $query;
    }

    $query->set( 'meta_key', 'company' );
    $query->set( 'meta_value', $editor_company );
}

add_action( 'pre_get_posts', 'query_company_posts_only', 10, 1 );

それがトリックをすることを願って、ちょうどそれで遊んで、あちこちでいくつかの改良を加えてください。

4
Levi Dulstein