메뉴 항목에 액세스 조건을 추가하려면 어떻게합니까?


17

메뉴 항목의 표시 여부를 결정하는 기존 조건 위에 새로운 조건을 추가하려면 어떻게해야합니까? 이러한 조건은 권한 설정으로 제한되지 않아야합니다.

예를 들어 유스 케이스 (이 질문에 대한 이유는 아닙니다) : 사용자가 하나의 노드 만 만들 수있는 콘텐츠 유형이 있다고 가정하십시오. 해당 유형의 콘텐츠를 추가하기위한 메뉴 항목이 있습니다. 그러나 사용자가 이미 해당 콘텐츠 유형의 노드를 만든 경우 메뉴 항목을 숨기고 싶습니다. 첫 번째 생각은 쿼리를 실행하여 현재 사용자가 만든 특정 콘텐츠 유형의 노드가 있는지 확인하는 것입니다. 존재하는 경우 메뉴 항목을 숨 깁니다.

이 유형의 기능은 hook_menu_alter()필요한 논리를 추가 해야한다고 생각합니다 . 그러나 사용자에게 해당 유형의 콘텐츠를 만들 수있는 권한이 있는지 확인하는 것과 같이 기존 확인을 우회하지 않고 그렇게하는 방법을 잘 모르겠습니다. 내 논리 안에 그 논리를 포함시켜야합니까? 아니면 기존 액세스 로직을 덮어 쓰지 않고 추가 할 수 있습니까?


편집 : 일부 사람들은 "사용자를 콘텐츠 유형의 한 노드를 만들도록 제한하는 방법"에 대답하는 데 집중하는 것 같습니다. 그것은 여기서 질문이 아닙니다. 문제는 메뉴 항목에 사용자 정의 액세스 조건을 추가하는 방법입니다.

답변:


11

당신이해야 할 일은 hook_menu_alter ()를 통해 콜백을 추가 한 다음 콜백 내에서 논리를 수행하고 원래 콜백을 통해 데이터를 반환하는 것입니다.

다른 hook_menu_alter () 변경 사항을 덮어 쓰지 않으려면 access 인수를 통해 이전 콜백을 콜백으로 전달해야합니다.

이것은 모두 이론적이지만 코드는 다음과 같아야합니다.

MYMODULE_menu_alter(&$items) {
  $items['menu']['access arguments'] = array_merge(array($items['menu']['access callback']), $item['menu']['access arguments']);
  $items['menu']['access callback'] = 'MYMODULE_access_callback';
}

MYMODULE_access_callback() {
  $args = func_get_args();

  // Do Stuff.
  if ($something == FALSE) {
    return FALSE;
  }

  $function = array_shift($args);
  return call_user_func_array($function, $args);
}

새로운 액세스 콜백 기능을 할당하면 원래 콜백을 덮어 씁니까?
Chaulky

예, 메뉴 항목 당 하나의 액세스 콜백 만 가질 수 있으므로 원래 콜백으로 다시 전달해야합니다. 나는 권한이 많은 모듈 중 하나 인 이와 같은 것을 수행하는 모듈을 보았지만 어느 모듈을 기억할 수 없습니다.
Decipher

$ args에서 array_shift는 무엇을합니까?
Chaulky

우리는 예전의 '액세스 콜백'을 만든 '액세스 인수'에서 첫 번째 인수를 가져옵니다. 따라서 이전 콜백이 'MYMODULE2_access_callback'인 경우 이것이 array_shift가 반환하는 것입니다. 또한 콜백이 예상하는 인수 만 전달할 수 있도록 배열에서이를 제거합니다.
Decipher

1

위의 의견에 따라 D7의 솔루션은 다음을 사용합니다.

/**
 * Implements hook_node_access().
 */
function mymodule_node_access($node, $op, $account) {
  $type = is_string($node) ? $node : $node->type;

  if ($op == 'create' && $type == 'mynodetype' && db_query("SELECT 1 FROM {node} WHERE type = :type AND uid = :uid", array(':type' => $type, ':uid' => $account->uid))->fetchField()) {
    // If the user has already created a node of a specific type, they cannot
    // create any more.
    return NODE_ACCESS_DENY;
  }

  // Otherwise do not affect any node access.
  return NODE_ACCESS_IGNORE;
}

1
메뉴 항목과 관련이없는 것 같습니다. 아직 D7에 익숙하지는 않지만 노드 생성에만 해당되는 것 같습니다. 질문은 일반적으로 메뉴 항목에 중점을 둡니다.
Chaulky

오, 알겠습니다 ... 이것은 노드 제한 모듈을 가리키는 귀하의 답변에 제안 된 D7 솔루션에 대한 자세한 내용을 묻는 내 의견에 대한 답변입니다. 여전히 약간의 주제이지만 감사합니다.
Chaulky

mynodetype 링크 작성의 가시성은 node_access () 함수에 의해 제어되므로 Drupal 7에서이 후크를 호출합니다.
Dave Reid

1

체인 메뉴 액세스 API 모듈을 찾고 있습니다.

체인 메뉴 액세스 API를 사용하면 모듈이 자체 메뉴 액세스 콜백 기능을 다른 모듈의 메뉴 라우터 항목에 연결할 수 있습니다.

Drupal Stack Exchange에는 사용 방법에 대한 예가 하나 이상 있습니다.


-1

한 가지 옵션은 컨텐츠 유형에 대한 컨텐츠 작성 권한이있는 새 역할을 작성하는 것입니다. 사용자가 해당 유형의 노드를 만든 후에는 해당 역할을 제거하면 더 이상 만들 수 없습니다.


-1

아마도 노드 제한을 시도해야합니다 모듈을 .

프로젝트 페이지에서 :

노드 제한 모듈을 통해 관리자는 역할 또는 사용자가 만들 수있는 특정 유형의 노드 수를 제한 할 수 있습니다. 예를 들어, 사이트에 "광고"노드를 만들 수있는 "광고주"역할이있는 경우 노드 제한 관리자는 해당 역할의 모든 사용자를 특정 수의 노드로 제한 할 수 있습니다. 또한 사용자별로 사용자를 제한 할 수도 있습니다.


하나의 노드로 제한하는 것은 사용자 정의 액세스 콜백 메소드를 추가하기위한 사용 사례의 예일뿐입니다. 또한 노드 제한은 메뉴 항목을 제거하지 않고 사용자가 해당 컨텐츠 유형의 다른 노드를 추가하지 못하게합니다.
Chaulky

이제 모듈 설명을 다시 살펴 보았습니다. 이것이 Drupal 7에 있었다면 hook_node_access ($ node, 'create', $ account)를 사용하여 create node type 링크 자체의 가시성에 영향을 줄 수 있기 때문에 실제로 쉽습니다.
Dave Reid

그 흥미 롭군요. 곧 D7로 옮길 계획입니다. 더 자세하게 작성하고 답변을 게시 하시겠습니까?
Chaulky

답변의 D7 버전이 게시되었습니다.
Dave Reid
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.