views:

81

answers:

5

I'm looking for a particular behaviour that grant permission to see one or more cck field based on date time creation of node.

In particular i need to:

Grant to role A: Full access to all CCK (old and new) Grant to role B: Access to all CCK but ONLY to ones present in node OLDER than 1 Year Anonymous user: No access to CCK field

How can i get this result?

A: 

It's easy, create node-{YOURTYPE}.tpl.php, theme it, and add conditions to show fields dependency from dates...

Nikit
I don't think this would work, as the CCK fields are not available separately in the node template, but are already rendered within the $content variable. But the general approach might work if one finds the proper CCK field template (or theme function), overriding this instead of the node template.
Henrik Opel
It's would work and it's one of way to hide fields (without using custom modules (hook_nodeapi)). Just remove $content - it's not good for theming. Use $node->field_FIELDNAME[0]['#value'], investigate "$node" via print_r() or dsm (devel module) functions.
Nikit
@Nikit: I see - sure, if you throw away the $content variable and output the nodes fields directly, you can do pretty much anything you want. But you would also circumvent major parts of Drupals theming system by throwing away any customizations other modules might have made to the content! I'd consider this to be quite hackish and would not recommend it, as it might simply break other functionality.
Henrik Opel
Henrik, i am not agree, theming is last thing that will work before sending to user, so it's most safety than removing fields via hook_nodeapi or other hooks.
Nikit
@Nikit: I do not say that it is not safe. But it breaks other functionality. One example: with CCK enabled, you can adjust the output order of fields in the backend UI (`admin/content/node-type/[yourNodeType]/fields`). The order defined there will be used in the $content variable. With your approach, that ordering will be completely ignored, since the node template will define its own order. Now thats Ok if it is your own site, since you know this. But if the site is used by others, they'll think that they can adjust the order in the UI, but will fail, since you will just ignore their setting.
Henrik Opel
That's why I call it 'hackish' - it works, and achieves what's needed in a straight and simple way (which is good), but doing so, it breaks other stuff (which is not so good). Again, if this site is completely in your control, this is not a big problem, as you will (hopefully) remember what you did and why some things in the UI do not work as expected. But if the site is to be used by others (and you just left for your next job), they will not know about your 'hack'. So you just 'stole' them a feature, and they'll need a new programmer to fix something that they could do on their own before.
Henrik Opel
I might need to add that I use the word 'hackish' in the sense of 'sloppy shortcut', 'quick and dirty fix' or the like. This does not necessarily imply that something is unsafe or 'evil' in itself, but more that it is risky, not thought through, and is likely to cause trouble in the future. (Did you ever have to do maintenance programming of an 'inherited' site? ;)
Henrik Opel
+1  A: 

I would implement hook_nodeapi() in a custom module, and on $op == 'view' check for the proper node type and the user role. Depending on the role, I'd remove the field entry in question from the `$node->content' array.

Note that the custom module needs to be invoked after CCK for this to work, as otherwise the CCK fields are not yet available in the `$node->content' array. So depending on its name, one might need to alter the custom modules weight to a value higher than that of CCK.

If the same logic needs to be applied for node edit forms as well, one would do the same on $op == 'prepare'.

Henrik Opel
+2  A: 

You want to control permissions on a field level so I would avoid using hook_nodeapi() Instead I would suggest you use hook_field_access (or use a combination of hook_nodeapi and hook_field_access()

example in pseudocode:

mymodule_hook_field_access($op, $field, $account = NULL, $node = NULL){

    if($field['field_name'] == 'field_xyz'){
        switch($op){
            case 'view':
                if($node->created was less than a year ago && $account role is A){
                   return FALSE;
                }

                if($node->created was less than a year ago && $account role is B){
                 return TRUE;
                }

                return FALSE;
                break;
            case 'edit':
                ...
                ...
        }    
    }

    return TRUE;
}

See to see the hook being called http://api.lullabot.com/content_access

hook_field_access() is available in Drupal 6 from the CCK module. In Drupal 7 it is in core.

Sid NoParrots
+1 - Didn't know about this hook - much easier than my hook_nodeapi suggestion!
Henrik Opel
+1  A: 

Thanks to all for suggestions!

The hook_field_access() is the solution i'm looking for.

I previously used the $node->field_FIELDNAME[0]['#value'] but I don't like to put in my theme (or in template.php) functions for user access. There was also the problem of theming, this solution didn't give my possibility for an easy and clean HTML output using Semantic CCK module!

Thanks again! Bye!

Ps. why my post is not after the last??!!

Dret
@Dret: Your post is not after the last because the order is based on votes here on stackoverflow. You can upvote (and downvote) questions as well as answers via the little arrows around the numbers to the left. So you should upvote NoParrots answer, as it was useful for you. As the questioner, you can also accept an answer as correct. This will put that answer to the top (regardless of votes), so that others can find it more easily. Upvotes and answer acceptance give some reputation points to the authors, so be liberal in voting - the voting system is the main reason why stackoverflow works!
Henrik Opel
+1 for follow up. (Though normally, you should not post the follow up as a separate answer, but simply accept the answer as the right one and add your remarks in a comment to that answer).
Henrik Opel
@Dret: Since you seemed to like my answer the most, why don't you mark it as "correct" :-). You can also give it an up vote too!
Sid NoParrots
A: 

mhmm... I tried with this code:

<?php
function cck1yprivacy_hook_field_access ($op, $field, $account = NULL, $node = NULL) {
global $user;
$roles = $user->roles;
$today = time();
$createdate = $node->created;
    if ($field['field_name'] == 'field_free') {
        switch($op){
            case 'view':
                if ((($today-$createdate) < 31536000) && (in_array('User',$roles))) {
                   return FALSE;
                }

                if(in_array('Member',$roles)) {
                 return TRUE;
                }

                return FALSE;
                break;
                  case 'edit':
                   if (in_array('Admin',$roles)) {
                 return TRUE;
                }
    }
    }

    return TRUE;
}
?>

But didn't works... can someone help me? Thanks! Bye!

Dret
@Dret: It seems like you have not registered a 'real' account on stackoverflow yet, hence posting as an 'unregistered user'. While this is OK in principle, using a registered account will give you access to more features which will help you getting answers here (e.g. voting, comments and much more). For example, in this case, you should post your problems as a comment to NoParrots answer, so that he will get notified about them (you should not expect answerers to constantly monitor the threads they answered to). You might also want to check the FAQ: http://stackoverflow.com/faq
Henrik Opel
Thanks! Did it...!
Dret
You should rename the function cck1yprivacy_field_access (remove the *hook* part of the function name 2. If things still don't work in such situations it is a great idea to use a debugger and put a breakpoint in the code and try it out... If debugger is too complicated then try the http://drupalcontrib.org/api/function/dsm function (you will need the devel module for that)
Sid NoParrots

related questions