CCK presents its output in two places in the $node object:
$node->content[fieldname][various keys]
and
$node->fieldname[index][various keys]

I'm using the latest CVS checkout (1.3.2.27 2007/08/27) and CCK_field_perms only succeeds in controlling access to the content located under $node->content.
The result is that if you use the raw cck output everything works fine, but if you want to theme the output using the "theme a full node" aproach, where you access the content using the $field_my_field[0]['view'] syntax (derived from $node->field_my_field[0]['view']) the content is still accessible.

It seems to me that anything added to the $node->$fieldname array is ignored later down the system.

A quick and dirty fix I made for myself in the cck_field_perms_nodeapi functions seens to work though:

unset $node->$disallowed_field;
//$node->$disallowed_field['#access'] = false;
$node->content[$disallowed_field]['#access'] = false;       

Unsetting the entire $node->fieldname member seems to work, but it does not feel like a clean and tidy way of dealing with the problem.

Sorry that I can not provide a patch file, I still haven't gotten my head around diff on my windows machine.

I hope someone have more insight on how to deal with this properly.

CommentFileSizeAuthor
#1 cck_theming.patch993 bytesVidarls
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Vidarls’s picture

Status: Active » Needs review
FileSize
993 bytes

Here is a patch with my fix, please review.

Andreas Kohlbecker’s picture

Your feeling was right. Since unsetting the entire $node->fieldname member should be avoided (http://drupal.org/node/138984) this strategy has been skipped: http://drupal.org/cvs?commit=67100

I stumbled into the same issue as you and I found out that there is one line of code which might work in some php setups, but which did not work at all with mine, causing the malfunction you've described. A patch for that bug and a little bit explanation is available from here: http://drupal.org/node/173322#comment-627089

Vidarls’s picture

Status: Needs review » Reviewed & tested by the community

I've investigated a bit further about my bug and also the bug Andreas refers to.
So far what I've found is rather depressing.

It seems to my that due to the nature of CCK, cck field permissions can never be successfully implemented as a regular Drupal module, it needs to be a part of core CCK. (is the lack of field permissions by design, or just not prioritized?)

Hiding content from being viewed can be done the way the CCK field permissions module functions today. But my above unset patch is needed in, unsetting a member during the 'view' phase of node loading probably won't break anything, and the member being unset does not have an '#access' property in the first place. ($node->content[field_name] on the other hand *does* have a functional '#access' property, but this array does not contain filtered output text)

The hard part begins when you need to control how the cck fields are submitted. Unsetting and / or hiding fields in the node form does not do the trick, as CCK processes the fields according to which fields are connected to which content types in the CCK tables, rather than which fields where actually submitted by the form.

To successfully manage permissions on a field basis some patching of one or all of the functions called in the following three functions is needed in addition to controlling what fields is presented in the form.:

/**
 * Submit form callback for node type fields.
 *
 * At submit time, the widget does whatever data massaging is necessary so that
 * the field has the content in the expected format and can commit the changes
 * to the database.
 */
function content_submit(&$node) {
  _content_widget_invoke('submit', $node);
  _content_widget_invoke('process form values', $node);
  _content_field_invoke('submit', $node);
  _content_field_invoke_default('submit', $node);
}

/**
 * Insert node type fields.
 */
function content_insert(&$node) {
  _content_field_invoke('insert', $node);
  _content_field_invoke_default('insert', $node);
}

/**
 * Update node type fields.
 */
function content_update(&$node) {
  _content_field_invoke('update', $node);
  _content_field_invoke_default('update', $node);
  cache_clear_all('content:'. $node->nid .':'. $node->vid, 'cache_content');
}

So that leaves me back at scratch with my project... *sigh*

Vidarls’s picture

double posting, someone please delete me

Vidarls’s picture

double posting

scottrigby’s picture

hi,
has this been resolved in later versions?
thanks in advance for the info!
Scott

Summit’s picture

Subscribing, greetings, Martijn

doc2@drupalfr.org’s picture

What piece of code should we use? The first patch? AND/OR the snippet in #3 ?

Thanks in advance.

virgo’s picture

Any progress ?