it-swarm-ko.tech

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

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

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

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


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

16
Chaulky

당신이해야 할 일은 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);
}
11
Decipher

Chain Menu Access API 모듈을 찾고 있습니다.

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

사용 방법에 대한 적어도 한 예 on Drupal 스택 교환)이 있습니다.

1
crantok

위의 의견에 따라 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
Dave Reid