2011-07-29 3 views
3

모든 사용자에게 'message'유형의 노드에 대한 액세스를 조건부로 차단해야합니다. 사용자가 이러한 메시지 노드를 볼 수있는 유일한 방법은 양식을 성공적으로 제출하는 것입니다.Drupal 7 노드 접근을 조건부로 차단하는 hook_node_access

I는 다음과 같이 시작했습니다 :

function form_submit($form, &$form_state) { 
    // some logic here 
    $form_state['redirect'] = 'node/255'; 
} 

그렇게 노드 255이다 : 그러나

function mymodule_node_access($node, $op, $account) { 
    if ($op == 'view' && $node->type == 'message') { 
     return NODE_ACCESS_DENY; 
    } 
    } 

, 나는 형태의 성공적인 제출에 따라 이러한 유형의 개별 노드에보기 액세스를 허용 할 'message'를 입력하고이 특정 노드와이 사용자에 대한 NODE_ACCESS_DENY를 '들어 올리려는 경우'(대부분의 경우 익명 사용자가됩니다)

다른 제안 사항 이 일을 성취하는 방법?

답변

4

당신이 할 수있는 유일한 방법은 폼 제출 핸들러에서 hook_node_access()으로 확인되는 값을 설정하는 것입니다. 당신은 Drupal 변수 나 데이터베이스 테이블에 저장된 값을 사용할 수 있습니다. 양식에 액세스 한 사용자의 사용자 ID와 해당 양식이 제출 된 모든 노드의 노드 ID를 저장해야합니다. 당신은 드루팔 변수를 사용하는 가정 할

, 당신은 하나 다음과 유사한 코드를 사용할 수

function mymodule_form_submit($form, &$form_state) { 
    global $user; 
    $message_nid = 255; 
    $values = variable_get('access_nid', array()); 

    if (isset($values[$user->uid])) { 
    if (!isset($values[$user->uid][$message_nid])) { 
     $values[$user->uid][$message_nid] = $message_nid; 
    } 
    } 
    else { 
    $values[$user->uid] = array($message_nid => $message_nid); 
    } 

    variable_set('access_nid', $values); 
    $form_state['redirect'] = 'node/' . $message_nid; 
} 

function mymodule_node_access($node, $op, $account) { 
    $result = NODE_ACCESS_IGNORE; 

    if ($op == 'view' && $node->type == 'message') { 
    $values = variable_get('access_nid', array()); 
    if (!empty($values[$account->uid]) { 
     if (isset($values[$account->uid][$node->nid])) { 
     unset($values[$account->uid][$node->nid]); 
     $result = NODE_ACCESS_ALLOW; 
     } 
     else { 
     $result = NODE_ACCESS_DENY; 
     } 
    } 
    else { 
     $result = NODE_ACCESS_DENY; 
    } 
    } 
    variable_set('access_nid', $values); 

    return $result; 
} 

이 코드는 사용자가 한 번만 노드에 액세스 할 수 있다는주의 사항; 사용자가 두 번째 동일한 노드에 액세스하려고하면 "액세스 거부"오류가 발생합니다. 즉, 바람직하지 않은 경우, 다음과 같이 다음 두 번째 함수는 재 기입되어야한다

function mymodule_node_access($node, $op, $account) { 
    if ($op == 'view' && $node->type == 'message') { 
    $values = variable_get('access_nid', array()); 
    if (!empty($values[$account->uid]) { 
     if (isset($values[$account->uid][$node->nid])) { 
     return NODE_ACCESS_ALLOW; 
     } 

     return NODE_ACCESS_DENY; 
     } 
    } 
    else { 
     $result = NODE_ACCESS_DENY; 
    } 
    } 

    return NODE_ACCESS_IGNORE; 
} 

제가

간단한 코드를 작성하는 드루팔 변수를 사용; 이 경우에는 Drupal 변수를 사용하여 해당 컨텐츠 유형의 노드를 작성할 수있는 사용자가 적다면 수행해야합니다. 노드를 만들 수있는 사용자가 많으면 데이터베이스 테이블을 사용하는 것이 좋습니다.
또한 Drupal 변수를 사용할 때 Drupal은 데이터베이스 테이블을 사용하고 있습니다. 차이점은 해당 데이터베이스 테이블의 내용이 항상 메모리에로드된다는 것입니다. 많은 데이터를 저장해야하는 경우 Drupal 변수를 사용하지 않아야합니다. 나는 익명의 사용자들과 주로 일하고 있어요으로

+0

덕분에, 처음으로 내가 드루팔에서 변수를 사용했습니다. 나는 작업 솔루션 (아래에 게시 됨)을 가지고 있습니다. 가장 우아한 솔루션이지만 작동하는지 확실하지 않습니다! – pragnatek

+0

@pragnatek 답변을 업데이트했습니다. – kiamlaluno

+0

도움을 주셔서 감사합니다 - 나는 처음으로 node_access와 varaibles를 사용하려고 많은 것을 배우고 있습니다. 나는 더 가까이 가고있다! – pragnatek

2

수정 된 솔루션은 $ _SESSION을 사용 : 포인터에 대한

function mymodule_form_submit($form, &$form_state) { 
    $message_nid = 255; 
    if (!isset($_SESSION['node_access'])) { 
    $_SESSION['node_access'] = array(); 
    } 
    if (!isset($_SESSION['node_access']['nid'])) { 
    $_SESSION['node_access']['nid'] = $message_nid; 
    } 
    $form_state['redirect'] = 'node/' . $message_nid; 
} 

function mymodule_node_access($node, $op, $account) { 
    $node_access = NODE_ACCESS_IGNORE; 
    if ($op == 'view' && $node->type == 'message') { 
    if (isset($_SESSION['node_access'] && !empty($_SESSION['node_access'])) { 
     if ($node->nid == $_SESSION['node_access']['nid']) { 
     unset($_SESSION['node_access']['nid']); 
     $node_access = NODE_ACCESS_ALLOW ; 
     } else { 
     unset($_SESSION['node_access']['nid']); 
     $node_access = NODE_ACCESS_DENY; 
     } 
    } else { 
     $node_access = NODE_ACCESS_DENY; 
    } 
    } 
    return $node_access; 
}