워드프레스 역할 그룹과 권한으로 구성 요소 제어

연재고품격 고품질 워드프레스 무료 사진 저장소완결2

워드프레스도 회원 가입 기능이 있으며, 회원이 속한 그룹에 따라 권한이 구분되어 있다는 것을 모르는 사용자는 없습니다. 이번 장에서는 예제 구성 기준에 따른 역할 그룹의 권한을 조절하여 관리페이지 및 사이트의 구성 요소 출력 등을 제어합니다.

‘무료 이미지 저장소’ 주제의 예제 사이트는 지난 과정까지 대부분 구성이 끝났습니다. 만약 이 예제와 같은 사이트를 실제 운용할 때 회원 가입은 가능하지만, 콘텐츠(이미지 포스트) 등록을 운영자 혼자 한다면 이번 장의 내용은 필요하지 않습니다. 또, 회원 가입 기능을 사용하지 않는다면 현재 예제 기준으로 관리페이지에서 회원 가입 기능을 해제하고, 비회원도 댓글 작성이 가능하도록 설정하는 정도만 변경하면 됩니다. 예제에서 추가한 회원을 삭제할 때 관리자로 포스트 작성자를 이전하는 것도 필요합니다.

이번 장의 내용은 워드프레스의 역할 그룹과 권한(Role & Capabilities) 시스템에 기반을 둔 것입니다. 그러나, 사용 경험이 없거나 적을 때 워드프레스의 역할과 권한은 설명이나 일부 관련 함수를 제외한 코덱스 안내만으로 이해하기 어렵습니다.

따라서, 코드 추가 전 상태와 추가 후 결과를 확인하는 방법으로 진행합니다. 직접 가상의 예제를 반복 경험하여 학습하는 게 최선이며, 궁금한 내용은 워드프레스 관련 커뮤니티에 질문하여 여러 정보를 습득하기 바랍니다.

이번 장부터는 사이트 언어를 영어로 변경하여 진행하며, 역할과 권한에 따른 구성 요소 확인 편리를 위해 3개의 다른 브라우저 세션을 동시에 열어 둡니다. 다음 목록에 따릅니다.

  • 관리페이지 일반 설정 페이지에서 사이트 언어를 ‘English(United States)’로 변경 후 저장
  • 3개의 다른 브라우저에서 사이트에 존재하는 ‘관리자(Administrator)’, ‘기여자(Contributor)’, ‘구독자(Subscriber)’ 회원으로 각각 로그인
  • 기여자는 ‘PhotoMan’ 선택
  • 구독자는 ‘generalMember’
  • 관리자 제외 회원 암호는 변경하지 않았다면 모두 ‘1234’
  • 편집기로 inc/template-functions.php 파일 열기

각 브라우저의 화면을 말할 때 ‘관리자 관리페이지’, ‘기여자 관리페이지’, ‘구독자 관리페이지’ 및 ‘관리자 사이트’, ‘기여자 사이트’, ‘구독자 사이트’로 부릅니다.

다음의 역할 그룹 명칭은 미리 파악해야 하는데, 각 목록의 마지막 영어 소문자 명칭만 프로그래밍(slug)에 필요한 이름이며, 나머지는 한글 또는 영어 버전에서 표시하는, 구분하기 쉽게 번역한 이름에 불과합니다. 설명은 한글 역할 그룹 이름을 사용합니다.

  • 관리자, Administrator, administrator
  • 기여자, Contributor, contributor
  • 구독자, Subscriber, subscriber

또, 역할은 ‘Role’, 권한은 ‘Cap’ 또는 ‘Caps’로 표기하며, 한글 ‘권한’은 Cap이 ‘워드프레스 사이트에서 가능한 능력 정도’의 뜻을 말합니다.

예제 사이트의 Role & Caps

편집기의 연습장 파일에 기존 코드를 모두 지우고 다음 코드를 추가한 후 저장하고, 아무 사이트에서 연습장 페이지를 새로 고쳐 결과를 봅니다.

echo '<pre>' . print_r( get_role( 'subscriber' ), true ) . '</pre>';
echo '<pre>' . print_r( get_role( 'contributor' ), true ) . '</pre>';
echo '<pre>' . print_r( get_role( 'administrator' ), true ) . '</pre>';

관리자 Caps 제외 기여자와 구독자 Caps만 나열하면 다음과 같습니다. level_*로 표시되는 항목은 사용하지 않아 염두에 두지 않아도 되므로 뺐습니다.

// 구독자의 프로그래밍 이름과 Caps
(
    [name] => subscriber
    [capabilities] => Array
        (
            [read] => 1
        )

)
// 기여자의 프로그래밍 이름과 Caps
(
    [name] => contributor
    [capabilities] => Array
        (
            [edit_posts] => 1
            [read] => 1
            [delete_posts] => 1
        )
)

Cap read가 없으면 대시보드 접근이 불가합니다. 이 Cap은 워드프레스 기본 Role 및 특정 Role 생성할 때 기본으로 존재하거나 추가합니다. 구독자 관리페이지와 기여자 관리페이지에 각각 접근이 가능한 것은 위의 결과처럼 read Cap이 Role에 할당(assigned)되어 있기 때문입니다.

위에 나열하지 않은 관리자 포함 나머지 Caps도 둘러보세요. 보통 각 Cap 이름에서 Cap 권한을 유추할 수 있습니다. 연습장 파일의 코드를 계속 유지하여 과정에 따라 변하는 Caps를 확인합니다.

기여자(Contributor) Caps 제거

다음 그림은 기여자 관리페이지입니다.

Capability 할당 전 기여자 관리페이지

예제의 기여자는 attachment 포스트 타입의 콘텐츠 ‘이미지’를 등록할 수 있어야 하므로 ‘Media’ 메뉴가 필요하며, 위의 그림에 있는 다음 메뉴(Caps)는 권한을 제거하여 출력되지 않도록 해야 합니다.

  • Posts (타입 post 등록 및 편집)
  • 앨범 (타입 pic_album 등록 및 편집)
  • Tools (타입 post 관련 Caps 제거 후 사라짐)

사이트의 연습장 페이지에서 볼 수 있는 기여자 Caps에서 다음 2가지를 제거해야 합니다.

edit_posts
delete_posts

remove_cap

편집기에 열린 template-functions.php 파일 맨 아래에 다음 코드를 추가하고 저장합니다.

/**
 * Remove and Add Capabilities
 */
add_action( 'admin_init', 'role_remove_add_caps' );
function role_remove_add_caps() {
    /* contributor(기여자) */
    $contributor_role = get_role( 'contributor' );
        // 제거할 caps
        $contributor_remove_caps = array(
            'edit_posts',
            'delete_posts',
        );
        foreach ( $contributor_remove_caps as $crc ) {
            $contributor_role->remove_cap( $crc );
        }
        // 추가할 caps, contributor

}

7번 줄에서 기여자의 현재 Caps를 구하여 10, 11번 줄의 Caps를 remove_cap 함수로 제거한 것입니다. 이때 4번 줄 admin_init 훅을 사용하였는데, 이 훅은 관리페이지 영역에 접근 시 다른 훅보다 먼저 실행(triggered)되는 것으로 정의되어 있습니다. 그러나, 이어서 계속 안내하는 것처럼 연습장 페이지를 새로 고쳤을 때도 기여자 Caps가 제거됩니다. 이 훅은 관리페이지 영역만이 아니라 admin-ajax.php 및 admin-post.php에서도 실행된다는 코덱스의 추가 안내가 있습니다.

코드를 추가하고 저장하였다면 아무 사이트의 연습장 페이지를 두 번 새로 고쳐 달라진 기여자 Caps를 확인합니다. 그리고, 기여자 관리페이지를 새로 고쳐 다음 그림의 결과가 나오는지 확인합니다.

Capability 제거 후 기여자 관리페이지

add_cap

이번에는 ‘Media’ 메뉴를 관리페이지에 출력하기 위해 해당 Caps를 기여자 그룹에 추가합니다. Media 메뉴는 타입 attachment 콘텐츠를 등록하는 것이므로 다음 Caps를 추가해야 등록 및 편집할 수 있으며, 미디어 파일 ‘업로드’가 가능합니다.

upload_files
edit_attachments
delete_attachments

다음 코드를 위에서 추가한 코드 17번 줄에 추가하고 저장합니다.

$contributor_add_caps = array(
    'upload_files',
    'edit_attachments',
    'delete_attachments',
);
foreach ( $contributor_add_caps as $cac ) {
    $contributor_role->add_cap( $cac );
}

아무 사이트의 연습장 페이지를 두 번 새로 고쳐 추가된 기여자 Caps를 확인하고, 기여자 관리페이지를 새로 고친 후 다음 그림과 같은지 확인합니다. 그리고, Media 메뉴를 클릭하여 미디어 목록 페이지에 접근합니다.

최종 기여자 관리페이지

사이트 연습장 페이지를 두 번 고치는 것은 워드프레스 역할(Role)과 권한(Caps) 정보가 데이터베이스에 저장되기 때문입니다.

타입 attachment Caps

현재 기여자(PhotoMan) 관리페이지 미디어 목록은 해당 회원의 콘텐츠를 포함한 사이트 전체의 미디어가 나타납니다. 문제는 다음 그림처럼 제목에 편집 링크가 제거되어 나옵니다.

기여자 관리페이지의 미디어 목록의 모든 포스트

관리페이지에서 ‘Media’ 메뉴를 출력하고 파일을 업로드하는 Cap은 upload_files Cap 하나로 충분하며, 이 Cap은 워드프레스에 존재하는 Cap입니다. 그러나, 다음 2가지는 기본으로 존재하지 않습니다.

edit_attachments
delete_attachments

예제에서 ‘앨범’ 커스텀 포스트 타입을 정의할 때처럼 워드프레스 post, page, attachment 등의 기본 포스트 타입도 기본 정의가 있습니다. 기본 attachment 포스트 타입에 정의한 Caps를 다음 코드로 볼 수 있는데, 연습장 파일에 이전에 추가한 코드 다음에 추가하세요. 아래 4번 줄만 추가하면 됩니다.

echo '<pre>' . print_r(get_role('subscriber'), true) . '</pre>';
echo '<pre>' . print_r(get_role('contributor'), true) . '</pre>';
echo '<pre>' . print_r(get_role('administrator'), true) . '</pre>';
echo '<pre>' . print_r($wp_post_types['attachment']->cap, true) . '</pre>';
// 여기 사이에

4번 줄은 attachment 포스트 타입의 Caps를 확인하는 것인데, 다음의 결과를 사이트의 연습장 페이지에서 볼 수 있습니다.

[edit_post] => edit_post
[read_post] => read_post
[delete_post] => delete_post
[edit_posts] => edit_posts
[edit_others_posts] => edit_others_posts
[publish_posts] => publish_posts
[read_private_posts] => read_private_posts
[read] => read
[delete_posts] => delete_posts
[delete_private_posts] => delete_private_posts
[delete_published_posts] => delete_published_posts
[delete_others_posts] => delete_others_posts
[edit_private_posts] => edit_private_posts
[edit_published_posts] => edit_published_posts
[create_posts] => upload_files

위의 결과로, create_posts Cap을 제외하면 모든 Caps가 타입 post에 할당한 Caps와 같음을 가늠할 수 있습니다. 그런데 예제에서는 다음 2가지 Caps를 제거했으므로 편집 권한이 없어서 링크가 없는 제목이 나오는 것입니다.

edit_posts
delete_posts

방법은 다음처럼 attachment 포스트 타입의 위 2가지 Caps에 새로 추가한 Caps를 할당하는 것입니다. 단, 조건으로 기여자 그룹에만 적용하며, 이 코드에 의한 Caps 변경은 데이터베이스에 저장되지 않는 조건에 따라 일시적으로 할당합니다.

if ( ! current_user_can( 'manage_options' ) && current_user_can( 'contributor' ) ) {
    global $wp_post_types;
    $wp_post_types['attachment']->cap->edit_posts = 'edit_attachments';
    $wp_post_types['attachment']->cap->delete_posts = 'delete_attachments';
}

위의 코드를 template-functions.php 파일에 이전에 추가한 코드 다음에 추가하고 저장한 후 기여자 관리페이지 미디어 목록을 보면 링크가 있는 제목이 출력됩니다. Screen Options 페이지에 출력할 목록(Number of items per page)을 100개로 변경하여 PhotoMan 회원의 이미지 포스트 제목에는 링크가 있지만, PhotoWoman 회원의 포스트는 링크가 없는 제목이 출력되는 것도 확인하세요.

관리페이지에서 로그인 회원의 포스트만 출력

현재 기여자 관리페이지의 미디어 목록 화면에는 사이트의 모든 이미지 포스트가 출력됩니다. 로그인 회원의 포스트만 출력하도록 변경합니다.

목록형의 미디어

편집기에서 inc/main-query.php 파일을 열고, 76번 줄 다음에 새 줄을 만들어 다음 코드를 추가하고 저장합니다.

// 관리페이지에서, 관리 권한이 있는 회원 제외하고 회원 자신의 포스트만 출력
if( $query->is_admin ) {
    $screen = get_current_screen(); // 관리페이지 조건 태그(is_admin) 안에서 정의해야 합니다
    $current_screen = $screen->id;

    if ( !current_user_can( 'manage_options' ) && $current_screen != 'dashboard' ) {
        $cuid = get_current_user_id();
        $query->set( 'author',  $cuid );
    }
}

기여자 관리페이지의 미디어 목록 화면을 새로 고쳐 PhotoMan 회원의 이미지 포스트만 출력되는지 확인합니다.

위의 코드는 관리페이지에서 Dashboard(알림판) 화면이 아닐 때와 manage_options Cap이 없는 회원일 때를 조건으로 둔 것입니다.

그리드형 미디어

미디어 목록 화면은 다음 그림처럼 ‘목록’과 ‘그리드’ 2가지 출력 옵션이 있습니다. 지금까지 본 것은 목록형입니다. 그리드 아이콘을 클릭합니다.

목록형과 그리드형의 미디어 출력 선택

로그인 회원마다 출력 옵션을 선택할 수 있는데, 선택 시 데이터베이스에 다음으로 저장합니다.

  • 목록일 때 _usermeta 테이블 _wp_media_library_mode 필드에 ‘list’
  • 그리드일 때 _usermeta 테이블 _wp_media_library_mode 필드에 ‘grid’

앞의 코드는 그리드에서도 PhotoMan 회원의 이미지만 출력됩니다. 예제는 타입 post 등의 포스트 작성 시 미디어첨부로 미디어를 등록하지 않지만, 포스트 등록 시 미디어 팝업 화면에서도 로그인 회원의 미디어만 출력하려면 다음 코드로 제어할 수 있습니다. 예제에서는 사용하지 않습니다.

add_filter( 'ajax_query_attachments_args', 'show_current_user_attachments' );
function show_current_user_attachments( $query = array() ) {
    $user_id = get_current_user_id();
    if( $user_id && !current_user_can( 'manage_options' ) ) {
        $query['author'] = $user_id;
    }
    return $query;
}

그리드에서는 ajax 방식으로 데이터를 출력한다는 정도만 기억하면 됩니다.

그러나, 예제에서는 그리드 선택 옵션을 제거하여 콘텐츠 편집 방법을 줄입니다. 다음 코드를 편집기에 열린 template-functions.php 파일 맨 아래에 추가하고 저장합니다.

/* Grid Media 목록 사용 제한 */
add_action( 'admin_init', 'disable_ajax_grid_media_list' );
function disable_ajax_grid_media_list() {
    if ( !current_user_can( 'manage_options' ) ) {
        if ( isset( $_GET['mode'] ) && $_GET['mode'] !== 'list' ) {
            wp_redirect( admin_url( 'upload.php?mode=list' ) );
            exit;
        } else {
            $_GET['mode'] = 'list';
        }
    }
}

조건으로 manage_options Cap이 없는 회원이 그리드 페이지에 접근하면 목록형 페이지로 리디렉트하는 코드입니다.

admin-style.css

코드로 그리드 페이지 접근 문제는 처리했지만, 아이콘은 그대로 남았습니다. CSS 코드로 감추는데 그전에 한 가지 확인합니다. 기여자 관리페이지의 이미지 포스트 중 아무거나 클릭하여 편집 화면에 접근하면 다음 그림처럼 편집 버튼이 있습니다.

이미지 편집 화면의 편집 버튼

버튼 클릭 시 나타나는 화면 안내는 생략하며, 이 버튼도 그리드 아이콘과 함께 CSS 코드로 감춥니다. 테마 루트 assets/css/admin-style.css 파일을 편집기로 열면 맨 아래 다음처럼 비활성화한 코드가 있습니다.

/* attachment list, edit page
.wp-filter .view-switch .view-grid {
    display: none;
}
.post-type-attachment .wp_attachment_image input[type=button] {
    display: none;
}
*/

다음처럼 변경하고 저장하세요. 그리고, 기여자 관리페이지를 Ctrl + F5 키로 새로 고친 후 그리드 아이콘과 편집 아이콘(Edit Image)을 확인하세요. 예제는 admin-style.css 파일을 관리자 그룹에서는 로드하지 않으므로 관리자 관리페이지에는 적용되지 않습니다. 테마의 functions.php 파일을 확인해보세요.

/* attachment list, edit page */
.wp-filter .view-switch .view-grid {
    display: none;
}
.post-type-attachment .wp_attachment_image input[type=button] {
    display: none;
}
CSS 코드로 버튼을 감춰도 크롬 브라우저 등의 특정 기능으로 CSS 코드를 다시 변경하여 버튼을 출력해 이미지 편집 화면에 접근할 수 있습니다. 예제의 기준에서 관리페이지의 모든 요소를 프로그래밍으로 완전하게 제어하려면 번거롭고 많은 작업이 필요하여 비효율적입니다. 실제 관련 사이트를 불특정 회원이 미디어를 등록할 수 있도록 운영한다면 프런트(사이트)에서 회원이 미디어를 등록할 수 있도록 구성하는 것이 좋고, 예제처럼 일부 인증 회원만 미디어를 등록한다면 지금의 구성도 괜찮습니다.

미디어 편집 화면 메타박스 제거

다음 그림처럼 미디어 편집 화면의 Screen Options 메타박스를 추가 선택합니다.

Screen Options 메타박스 선택

편집 화면 아래에 다음 그림처럼 추가한 메타박스가 나옵니다.

이미지 편집 화면의 메타박스

위의 메타박스를 manage_options Cap이 없는 회원일 때 출력하지 않도록 처리합니다. 편집기에 열린 template-functions.php 파일 맨 아래에 다음 코드를 추가하고 저장합니다. 그리고, 기여자 관리페이지의 편집 화면을 새로 고쳐 결과를 확인합니다. 마찬가지로 관리자 관리페이지의 미디어 편집 화면에도 접근하여 다른 결과를 확인하세요.

/* attachment 편집 화면 메타박스 제거 */
add_action( 'admin_menu' , 'remove_attachment_screen_metabox' );
function remove_attachment_screen_metabox() {
    if ( !current_user_can( 'manage_options' ) ) {
        remove_meta_box( 'commentstatusdiv', 'attachment', 'normal' ); // comments status
        remove_meta_box( 'commentsdiv', 'attachment', 'normal' ); // comments list
        remove_meta_box( 'slugdiv', 'attachment', 'normal' ); // slug
        remove_meta_box( 'titlediv', 'attachment', 'normal' ); // removes slug
    }
}

위의 코드는 Screen Options 선택 항목도 제거합니다.

어드민바 메뉴 제거 및 추가

다음 그림은 기여자 사이트에서 본 어드민바로 워드프레스 로고와 로그인 사용자 영역에 마우스를 올렸을 때 나타나는 메뉴를 동시에 출력한 것입니다.

기본 워드프레스 어드민바

워드프레스 로고 및 하위 메뉴를 제거하고, 오른쪽 로그인 사용자 하위 메뉴에 ‘내가 올린 사진’ 메뉴를 추가하여 등록자 아카이브 페이지로 링크합니다. 이미지 포스트 등록은 예제에서 관리자와 기여자 그룹만 가능하므로 조건을 둡니다. 다음 코드를 template-functions.php 파일에 추가하고 저장합니다.

/* Admin Bar */
add_action( 'admin_bar_menu', 'remove_custom_bar', 999 );
function remove_custom_bar( $wp_admin_bar ) {
    $wp_admin_bar->remove_node( 'wp-logo' );
    //$wp_admin_bar->remove_node( 'site-name' );
        //$wp_admin_bar->remove_node( 'dashboard' );
        $wp_admin_bar->remove_node( 'themes' );
        $wp_admin_bar->remove_node( 'widgets' );
        $wp_admin_bar->remove_node( 'menus' );
    $wp_admin_bar->remove_node( 'customize' );
    //$wp_admin_bar->remove_node( 'new-content' );
        //$wp_admin_bar -> remove_node ( 'new-post' );
        $wp_admin_bar->remove_node ( 'new-page' );
        $wp_admin_bar->remove_node ( 'new-user' );
        $wp_admin_bar->remove_node ( 'new-link' );
        //$wp_admin_bar -> remove_node ( 'new-media' );
    $wp_admin_bar->remove_node( 'search' );
    //$wp_admin_bar->remove_node( 'user-actions' );
        $wp_admin_bar -> remove_node ( 'logout' );
        //로그아웃 링크 재설정
        $args = array(
            'parent' => 'user-actions',
            'id' => 'logout',
            'title' => '로그아웃',
            'href' => wp_logout_url( $_SERVER['REQUEST_URI'] ),
        );
        $wp_admin_bar->add_node( $args );
        
    /* Admin Bar 메뉴 추가 */
    if ( current_user_can( 'upload_files' ) ) { // 예제에서 administrator, contributor
        $args = array(
            'parent' => 'user-actions', // 비활성화하면 최상위 메뉴.
            'id' => 'author_pic', // 구분하기 쉽게 직접 정하면 되고, wp-admin-bar-author_pic 형태로 출력.
            'title' => '내가 올린 사진',
            'href' => esc_url( get_author_posts_url( get_current_user_id() ) ),
        );
        $wp_admin_bar->add_node( $args );
    }
}

위의 코드에서 비활성화한 것은 참고의 뜻으로 남겨둔 것이며, 어드민바에 존재하는 메뉴를 변경할 때와 추가할 때 상위 노드, parentid 인수 확인 및 정의 등에 초점을 두면 쉽게 원하는 어드민바 메뉴를 구성할 수 있습니다.

30번 줄의 upload_files Cap 조건은 예제에서 관리자와 기여자 그룹에 해당합니다. 구독자, 기여자, 관리자 사이트를 각각 새로 고쳐 변경 어드민바를 확인하세요.

Taxonomy Capability

다음 그림은 기여자 관리페이지 이미지 포스트 편집 화면의 커스텀 분류 메타박스로, Screen Options Layout 1열 선택한 후 결과입니다.

기여자 그룹에 커스텀 분류 Caps 할당 전

위의 그림처럼 이미지 포스트 편집 화면의 각 분류 메타박스는 추가, 선택할 수 없도록 비활성화되어 있습니다. 지난 과정에서 이미지를 한꺼번에 등록할 때 각 포스트에 연결한 분류 term은 제대로 선택되어 있습니다.

다시, 관리자 관리페이지에서 아무 이미지 포스트 편집 화면에 접근하여 분류 메타박스를 확인해보세요. 추가, 선택 등이 가능할 것입니다. 관리자 관리페이지의 계층 구조 메타박스(미디어분류, 2차분류)를 기억하세요.

커스텀 분류의 Caps

예제에서 이미지 포스트 등록 주 그룹은 ‘기여자’이며, 기여자는 다음처럼 4개의 분류에 관하여 각각 다른 권한이 있어야 합니다.

  • 미디어분류(mediacat) : 존재하는 분류에 선택만 가능
  • 2차분류(photocat) : 존재하는 분류에 선택만 가능
  • 미디어태그(phototag) : 존재하는 분류 선택, 추가, 선택 제거 가능
  • 카메라(cameracat) : 선택 및 추가 불가

반면, 관리자 그룹은 모든 분류에 관하여 모든 권한이 있어야 합니다. 바로 처리해봅니다.

사이트 루트 wp-content/mu-plugins/pics-tax-cpt.php 파일을 편집기로 열어 18, 32, 46번 줄을 활성화합니다.

pics-tax-cpt.php 파일 18, 32, 46번 줄을 다음 3번 줄처럼 활성화
//'capabilities' => $capabilities,
'capabilities' => $capabilities,

편집기의 pics-tax-cpt.php 파일 10번 줄 다음에 다음 코드를 추가하고 저장합니다.

$capabilities = array(
    'manage_terms' => 'manage_picstaxs',
    'edit_terms' => 'manage_picstaxs',
    'delete_terms' => 'manage_picstaxs',
    'assign_terms' => 'upload_files'
);

기여자 관리페이지 아무 이미지 포스트 편집 화면에 접근하여 분류 메타박스를 확인하면, 카메라 분류 메타박스를 제외한 분류 메타박스가 활성화되며, 앞에서 나열한 각 분류의 권한처럼 추가, 선택 등의 권한이 제한된 상태로 출력될 것입니다.

다시, 관리자 관리페이지의 아무 이미지 포스트 편집 화면에 접근하면 코드 추가 전과 다르게 ‘추가’ 기능(텍스트 링크)이 나오지 않을 것입니다. 또, 관리자 관리페이지 Media 하위 메뉴에 카메라를 제외한 분류 메뉴는 나오지 않습니다. 확인해보세요.

관리자 Role에 추가한 Caps 할당

관리자 그룹은 사이트 모든 구성 요소에 관한 모든 권한이 있어야 하므로 다음 코드를 template-functions.php 파일에 추가하고 저장합니다. 이때 추가 위치에 주의합니다.

// attachment 포스트 타입 Caps를 새로 할당
    if ( ! current_user_can( 'manage_options' ) && current_user_can( 'contributor' ) ) {
        global $wp_post_types;
        $wp_post_types['attachment']->cap->edit_posts = 'edit_attachments';
        $wp_post_types['attachment']->cap->delete_posts = 'delete_attachments';
    }

// 위의 코드를 찾아 다음에 아래 코드를 추가

/* 추가할 caps, administrator */
$admin_role = get_role( 'administrator' );
    $administrator_add_caps = array(
        'manage_picstaxs',
    );
    foreach ( $administrator_add_caps as $aac ) {
        $admin_role->add_cap( $aac );
    }

관리자 관리페이지 편집 화면을 새로 고쳐 분류 메타박스의 변화를 확인하고, Media 하위 메뉴에 4가지 분류 메뉴가 나타나는지 확인합니다. 아무 사이트의 연습장 페이지를 새로 고쳐 관리자 Caps에 manage_picstaxs Cap이 추가되었는지 확인합니다.

마지막으로 기여자 관리페이지의 편집 화면 모든 분류 메타박스의 제한적 상태를 확인하고, Media 하위 메뉴가 나타나지 않는지 확인합니다.

분류의 Cpas

편집기의 pics-tax-cpt.php 파일에 추가한 분류 Caps는 다음과 같은데, 분류 term에 대한 관리, 편집, 삭제, 사용의 권한을 manage_picstax 이름의 Cap에 할당한 것입니다.

'manage_terms' => 'manage_picstaxs',
'edit_terms' => 'manage_picstaxs',
'delete_terms' => 'manage_picstaxs',
'assign_terms' => 'upload_files'

위의 Caps 할당 전 관리자 관리페이지에서는 모든 분류에 대한 권한이 있었는데, 다음의 기본 Caps 때문입니다.

'manage_terms' => 'manage_categories'
'edit_terms' => 'manage_categories'
'delete_terms' => 'manage_categories'
'assign_terms' => 'edit_posts'

다시, 위의 Caps 중 4번째인 다음 1번 줄 Cap은 앞에서 기여자 그룹에서는 제거하였으므로 관리자 그룹에서만 모든 분류에 대한 권한이 있었습니다. 따라서 분류에 관한 새로운 Caps 추가 전에는 관리자 그룹에서만 Media 하위 메뉴와 편집 화면에서 분류 메타박스의 term 추가가 가능했던 것입니다.

'assign_terms' => 'edit_posts'
'assign_terms' => 'upload_files'

위의 2번 줄 Cap은 예제 기준으로 기여자와 관리자 그룹의 공통 Cap입니다. 이 Cap을 할당한 assign_terms 인수는 분류의 선택 권한의 ‘사용’에 관한 것입니다.

기여자와 관리자 그룹의 공통 upload_files Cap에 할당하여 기여자와 관리자 모두 특정 분류를 ‘사용(선택)’할 수 있게 하였으며, 관리자는 다음 코드처럼 Cap을 데이터베이스에 저장하여 모든 권한을 할당한 것입니다.

$admin_role = get_role( 'administrator' );
    $administrator_add_caps = array(
        'manage_picstaxs',
    );
    foreach ( $administrator_add_caps as $aac ) {
        $admin_role->add_cap( $aac );
    }

만약 위의 manage_picstaxs Cap을 기여자에게도 추가한다면 카메라 분류를 제외한 3가지 분류에 대한 모든 권한을 기여자 그룹도 가지게 됩니다.

카메라 분류는 원본 이미지에서 구하는 것이므로 기여자 그룹에는 권한을 할당하지 않았고, 관리자 그룹에만 할당하였습니다.

Capability Type

이번 장에서 다루지 않았지만, 지난 과정의 pic_album 커스텀 포스트 타입 정의 시 다음은 생략하였는데, 정의하지 않을 때 기본 설정이기 때문입니다.

// 커스텀 포스트 타입의 기본 Capability Type
'capability_type' => 'post'

다음은 이번 장에서 나온 몇 가지 Caps입니다.

edit_posts
edit_attachments
manage_picstaxs
manage_options

이 Caps 모두 다음 패턴을 가지고 있습니다.

// 워드프레스 Caps 공통 패턴
{권한}_{capability_type(s)}

Capability Type ‘post’

워드프레스 기본 포스트 타입의 ‘post’와 Capability Type(이하 Caps 타입)의 ‘post’는 완전히 다른 것입니다. Caps 타입은 구분자 또는 식별자로 Caps Set(Set of Capabilities) 대표 이름을 뜻합니다. 포스트 타입 ‘post’에 사용할 Caps 타입 이름을 ‘post’로 정하여 쉽게 구분하기 위한 것으로 생각하면 됩니다. 새로운 Caps 타입을 정의할 때 보편적으로 사용합니다.

복수형 Cap 이름

이번 장에서 사용한 Caps를 보면 각 Cap 이름 끝에 ‘s’가 붙습니다. 다음 2번 줄처럼 Caps 타입을 정의하면 각 Cap에 ‘s’가 붙고, 3번 줄처럼 정의하면 productx를 사용합니다. ‘x’가 붙는 게 아니라 설정한 productx 그대로 사용한다는 뜻입니다. 단수(singular), 복수(plural)의 보편적 뜻으로 생각하고, 복수를 정의하지 않으면 ‘s’가 자동으로 각 Cap 이름 뒤에 붙는다는 것 기억하면 됩니다.

// 커스텀 포스트 타입 product 설정 시 가정
'capability_type' => 'product' // product(s)
'capability_type' => array( 'product', 'productx' );

분류의 Caps 타입

잠깐 살펴본 것은 포스트 타입 정의할 때 Caps 타입에 관한 것인데, 분류(taxonomy)를 정의할 때는 Caps 타입 이름을 정의하지 않습니다. 각 Cap에 복수형으로 바로 정의하면 됩니다. 예제에서 사용한 다음 분류에 관한 Cap을 참고하세요.

manage_picstaxs
manage_{picstax(s)}

위의 Cap 기준으로 보면 Caps 타입 이름은 ‘picstax’인데, 예제에서 사용하는 커스텀 분류 중 카메라 분류를 제외한 모든 분류는 기여자 그룹에 같은 Caps를 할당하므로 분류마다 다른 Caps 타입 이름을 지정할 필요가 없기에 필자가 마음대로 정한 것입니다. 결국, 포스트 타입 또는 분류 이름과 Caps 타입 이름은 쉽게 구분하기 위해 같은 또는 비슷한 이름을 정하는 것뿐 시스템적 관련이 없습니다.

이번 장의 워드프레스 Role & Capabilities 시스템에 관한 이해에 어려움이 있더라도 넘기는 게 좋습니다. 나중에 직접 기준을 정한 사이트 구성에서 여러 상황으로 하나씩 확인하는 단계를 거치는 반복 학습이 필요합니다.

관리자 관리페이지에서 사이트 언어(Site Language)를 ‘한국어’로 변경하고 저장합니다. 그리고, 다음 링크에서 이번 장에서 변경한 파일을 받아 압축을 푼 후 사이트 루트에 덮어쓰세요.

변경 파일 중 커스텀 분류와 커스텀 포스트 타입을 정의한 pics-tax-cpt.php 파일은 커스텀 분류의 label을 추가 정의하여 제공합니다. 파일을 열어 다음 코드와 비슷한 label 설정이 카메라 분류를 제외한 3개의 분류에 정의되어 있습니다. 예제 결과에 시스템적 영향이 없는 것이며, 관리페이지의 일부 출력 텍스트가 변경됩니다.

'all_items' => '모든 미디어분류',
'edit_item' => '미디어분류 수정',
'view_item' => '미디어분류별 목록',
'update_item' => '미디어분류명 수정',
'add_new_item' => '미디어분류 추가',
'new_item_name' => '새로운 미디어분류',
'parent_item' => '상위 미디어분류',
'parent_item_colon' => '상위 미디어분류',
'search_items' => '미디어분류 찾기',
'popular_items' => '콘텐츠가 많은 미디어분류',
'choose_from_most_used' => '콘텐츠가 많은 미디어분류',
'not_found' => '등록된 미디어분류가 없습니다.',

커스텀 포스트 타입과 분류에 관한 설정 변경 시 관련이 없어도 퍼머링크 정보를 업데이트하는 것이 좋습니다. 관리자 관리페이지 퍼머링크 설정 페이지에 접근하여 업데이트(Save Changes) 버튼을 클릭하세요.

예제 목차

0. 고품격 고품질 워드프레스 무료 사진 저장소

1. 예제 구성 환경과 파일

2. XAMPP, 워드프레스, 테마, 플러그인 설치와 설정

3. 테마 Pics Press

4. page 포스트 타입과 페이지 템플릿, 메뉴 구성

5. 워드프레스 핵심 용어 짚기

6. 워드프레스 포스트 타입 attachment

7. 워드프레스 이미지 사이즈

8. 워드프레스 이미지 사이즈 추가 및 변경

9. 워드프레스 이미지 파일 제어

10. 타입 attachment 템플릿과 image.php

11. 워드프레스 이미지 메타 데이터

12. GPS 데이터를 워드프레스 메타 데이터로 저장

13. 이미지 메타 데이터를 포스트 메타 데이터에 추가

14. Attachment 타입을 위한 워드프레스 커스텀 분류 등록

15. 이미지 메타 데이터를 워드프레스 분류와 필드 데이터에 저장

16. 이미지를 편집할 때 포스트 데이터와 메타 데이터 업데이트

17. 워드프레스 미디어 파일 업로드

18. 워드프레스 싱글 이미지 포스트 페이지

19. 워드프레스 아바타와 Author Archives

20. 워드프레스 이미지 사이즈별 데이터 출력

21. 워드프레스 폼 요소로 원하는 이미지 사이즈 다운로드

22. 워드프레스 텍스트 단락 및 줄 바꿈, wpautop

23. 워드프레스 사진의 EXIF 데이터 출력

24. 구글 지도에 표시하는 사진 촬영 위치

25. 워드프레스 attachment 포스트 타입의 아카이브

26. 워드프레스 함수로 자바스크립트 변수 데이터 생성

27. 워드프레스 커스텀 검색 – 쿼리 변수

28. 워드프레스 커스텀 검색 – 검색 폼과 쿼리 데이터

29. 워드프레스 커스텀 포스트 타입 ‘pic_album’

30. 커스텀 포스트 타입의 싱글 페이지

31. 워드프레스 WP_Query

32. 커스텀 쿼리, 페이지 템플릿, 포스트 아카이브

33. 분류 기준의 관련 포스트 커스텀 쿼리

34. wpdb 클래스로 구글 지도에 마커와 섬네일 표시

35. 워드프레스 분류 데이터 쿼리 클래스, WP_Term_Query

36. 워드프레스 템플릿 태그

37. 워드프레스 옵션 페이지, 옵션 필드

38. 워드프레스 사이트 프런트 페이지

39. 사이트 메뉴 및 포스트 페이지 링크

40. 워드프레스 Transient API

41. 워드프레스 분류의 term 데이터를 캐시 데이터로 생성

» 워드프레스 역할 그룹과 권한으로 구성 요소 제어

43. 간단한 워드프레스 코멘트 폼 수정

44. 워드프레스 대시보드 위젯 추가

45. 워드프레스 REST API 간략 이해

46. 워드프레스 REST API 응답에 커스텀 필드 추가

47. 워드프레스 REST API 커스텀 라우트 및 엔드포인트

48. 워드프레스 REST API 커스텀 엔드포인트로 구글 클러스터 지도 마커와 인포 윈도 표시

49. 워드프레스 REST API, Underscore.js 자바스크립트 템플릿, 포스트 Ajax Load More

50. 워드프레스 REST API, Underscore.js 자바스크립트 템플릿, 코멘트 Ajax Load More

51. 워드프레스 REST API 인증과 제한 및 제어