Dispelling Node Access Fears

Venturing into the node access realm of hooks and functionality for some reason always felt complex, so I have avoided it complete thus far, relying on various node or taxonomy access based modules (http://drupal.org/taxonomy/term/74), to handle any access issues I needed. This usually resulted in systems that were more complex or more burdensome to maintain than desired. Well, I was wrong, the node access system isn't complex, and it is powerfully efficient and optimized.

Recently, I needed to implement a system to allow editing access to a node (an organization node) by multiple users, but we wanted the original node author to dole out this access instead of sending requests to the administrators. But beyond that we needed them to be able to edit all the 'product' nodes that referenced the 'organization' node.

A couple modules were close to what I needed (http://drupal.org/project/nodeaccess_autoreference, http://drupal.org/project/nodeaccess_userreference, http://drupal.org/project/nodeaccess_nodereference) but they were a bit more featured loaded than I wanted, and I used this as an opportunity to learn about the node access hooks (check out the node access example for a general example.).

To tackle my issue, I started with a user reference CCK item on the organization node, so the node author can assign other members to the node, and also added a node reference item to the product nodes to reference an organization node.

Now that the links were in place, I had to implement the node access permissions. Even time a node is checked for 'edit' permissions the node grants hook is run, so my module needed to implement this hook.

function example_node_grants($account, $op) {
   //Keyed array with realm as key
   $grants['referenced'] = array($account->uid);
   return $grants;
}

From the API guide, I just needed to create an array with the key as the realm of access permissions (should not conflict with any other node access module you have, if any). I called the realm 'referenced' since I was using node and user references, and since it was user based, I just use the user ID as the item to look for.

In simple terms, this tells the node access system to look for an entry that links the user ID, with the requested node ID in the 'referenced' realm of entries.

But the check is useless unless we have already added grants to the system, so the node access record hook is needed.

Checking the API guide, I just needed to pass an array of arrays with the grants that needed to be saved.

function example_node_access_records($node) {
   if ($node->type == 'org') {
   //For each user referenced in the CCK item, add a grant entry.
   foreach($node->field_members as $u) {
     if (!empty($u['uid'])) {
       $r_user = user_load($u['uid']);
       $grants[] = array(
         'realm' => 'referenced',
         'gid' => $u['uid'],
         'grant_view' => TRUE,
         'grant_update' => TRUE,
         'grant_delete' => user_access('administer org', $r_user) ? 1 : 0,
         );
       }
     }
   }
   elseif ($node->type = 'product') {
     //For each 'org' node referenced, check for all user references to add grants.
     foreach($node->field_org_ref as $o) {
       if (!empty($o['nid'])) {
         $o_node = node_load($o['nid']);
       //For each user referenced in the CCK item, add a grant entry.
       foreach($o_node->field_members as $u) {
       if (!empty($u['uid'])) {
         $r_user = user_load($u['uid']);
         $grants[] = array(
         'realm' => 'referenced',
         'gid' => $u['uid'],
         'grant_view' => TRUE,
         'grant_update' => TRUE,
         'grant_delete' => user_access('administer org', $r_user) ? 1 : 0,
         );
         }
       }
       }
     }
   }

   return $grants;
}

When a node is saved, all the grants for that node are re-calculated. But I had an issue where I needed to also resave all the referenced 'product' nodes with new permissions each time the 'org' node was updated. So I needed to also make a nodeapi hook entry to save new grants for any referenced 'product' nodes.

function example_nodeapi(&$node, $op) {
if ($op == 'update' or $op == 'insert') {
//Update node access table with grants of the author and members of an org
if ($node->type == 'org') {
//Add grants for all products that reference this node.

$qry = db_query("SELECT DISTINCT(nid) FROM content_type_product WHERE field_org_ref_nid = %d",$node->nid);
while ($result = db_fetch_object($qry)) {
$grants = array();
foreach($node->field_members as $u) {
if (!empty($u['uid'])) {
$r_user = user_load($u['uid']);
$grants[] = array(
'realm' => 'referenced',
'gid' => $u['uid'],
'grant_view' => TRUE,
'grant_update' => TRUE,
'grant_delete' => user_access('administer org', $r_user) ? 1 : 0,
);
}
}
node_access_write_grants($result, $grants, 'referenced');
}
}
}
}

The node_access_write_grants function takes the same array entries like the node access records hook. It isn't needed to be called oin the node access records hook because the grants are written later through the hook loop, but in the nodeapi() implementation, we have to explicitly call the write grants function to make sure they are saved.

To round out the permissions carefully, I turned on the CCK permissions modules and protected both the user reference and node reference fields so that members with this new delegated power can't add or remove other people from the editing powers. Only the node author can do that.

Now that I have done it once, I won't be nearly as fearful regarding the node access system, and I have found how optimized this system is. Great job Drupal core developers.

Thanks for sharing

Thanks for sharing

Excellent resource and will

Excellent resource and will certainly apply it to my current projects (otimização de sites, desentupidora, acompanhantes, cartoes de visita, portas de aço, relogio de ponto and transportadora). I may have some difficulty to implement the codes, but if this is the case surely come back here for help.
Thank you and success!

These kind of post are always

These kind of post are always inspiring and I prefer to read quality content so Laser Hair Removal New York CityI happy to find many good point here in the post, writing is simply great, thank you for the post.thanks

v-pills in nasıl çalıştığını

v-pills in nasıl çalıştığını anlamak için önce ereksiyonun v-pills nasıl oluştuğuna bakalım; Organın sertleşmesi penis derinizin hemen altında bulunan Copora Cavernosa adı verilen bir dizi depocuk sayesinde olmaktadır. Bunlar sertleşebilen süngerimsi oluşumlardır. Bu depocukların her biri bir damar grubuna bağlıdır ve biri doldurma, diğeri de boşaltma görevini üstlenmiş iki vanaya sahiptir. Sertleşmenin, yani ereksiyonun gerçekleşmesi için beyin, hormonlar, sinir uçları ve kan damarları uyum içinde çalışabilmelidir.Penis Büyütücü Cinsel olarak uyarıldığınızda, bütün sistemler sağlıklı çalışıyorsa penis içindeki depocuklarda bulunan ve onları dolduran vana açılır, içine kan dolar ve onlar kan dolup genişledikçe penis de dikleşir ve sertleşir, yani ereksiyon gerçekleşir. vpills penis büyütücü içerdiği doğal afrodizyaklar ve şifalı bitkilerle kan damarlarını genişletip yoğun bir kan akışı sağlar ve penisinizi daha hacimli, daha sert, ereksiyonunuzu ise daha güçlü ve uzun süreli kılar.

Acai ile 1 ay gibi kısa

Acai ile 1 ay gibi kısa sürede fazla kilolarınızı verebilir, Acai herkesi kendinize hayran bırakabilirsiniz… Klinik olarak A.B.D ve AB ülkelerinde bir çok başarısıyla adından söz ettirmiştir. Acai Berry Ve hepsinden önemlisi olan asıl sorunumuz kilo vermemize rağmen verdiğimiz kiloları geri alma probleminin yaşanmaması Acai’yi tercih bitkisel zayıflama etme sebebinin başında yer almasını sağlamıştır.

I like this article. I find

I like this article. I find the information I need. I think I can find more useful information here, thanks
Brochure Printing

Thank you for sharing

Thank you for sharing information, hopefully bring many benefits
especially for the loyal readers of this blog.

Astaga.com Lifestyle on the Net

bisnis pulsa
Bisnis Online
Bisnis Internet
Bisnis Online
belajar bahasa inggris
How To Jump Higher

I definitely enjoying every

I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post.I will bookmark your blog and have my children check up here often.
web design new york
Thanks

I like the way you explain

I like the way you explain the things. Keep posting. Thanks..I will be one of your loyal reader if you maintain this kind of post.
Black CaviarThanks

It was December 1st, 2008. I

It was December 1st, 2008. I was sleeping soundly, the cool San Diego breeze blowing through the screen door when the ringing of my cell phone woke me up. I rubbed my eyes and shook my head to dissolve the remaining fragments of my dreamarmy surplus

Post very nicely written, and

Post very nicely written, and it contains useful facts. I am happy to find your distinguished way of writing the post. Now you make it easy for me to understand and implement. Thanks for sharing with us. Dermajuv

hands down, sir. i have to

hands down, sir. i have to say i couldn't agree more.
online psychology degree | new hollywood flick

Venturing into the node

Venturing into the node access realm of hooks and functionality for some reason always felt complex, so I have avoided it complete thus far, relying on various node or taxonomy access based modules (http://drupal.org/taxonomy/term/74), to handle any access issues I needed.

Equity Release

This is my first time i visit

This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good work.