Index: cck_field_privacy.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/cck_field_privacy/cck_field_privacy.module,v retrieving revision 1.3.2.2.2.10 diff -u -r1.3.2.2.2.10 cck_field_privacy.module --- cck_field_privacy.module 21 Mar 2009 20:46:15 -0000 1.3.2.2.2.10 +++ cck_field_privacy.module 10 May 2009 03:39:45 -0000 @@ -143,98 +143,172 @@ * Implementation of hook_form_alter(). */ function cck_field_privacy_form_alter(&$form, &$form_state, $form_id) { + global $user; - - $uid = (int) isset($form['#node']->uid)? $form['#node']->uid : $user->uid; // original author or current user (authoring new node) + $types = variable_get('cckfp_types', NULL); if (is_array($types)) { - if (!array_key_exists($form['#node']->type, $types) && !in_array($form['page']['#value']->options['content-type'], $types)) { - return; // abort - } + if (array_key_exists($form['#node']->type, $types) || in_array($form['page']['#value']->options['content-type'], $types)) { - // Get the stored fields - $fields = variable_get('cckfp_types', NULL); - $values = unserialize(variable_get('cckfp_values', array())); - - $cckfp_enabled_fields = array(); - - // Figure out what node type (via name) we are accessing. - $node_name = $form['type']['#value']; - if (array_key_exists($node_name, $fields)) { - if ($fields[$node_name] != '0') { - foreach ($values as $name => $value) { - if ($name == $node_name) { - foreach ($value as $field => $enabled) { - if (!$enabled) continue; - if (array_key_exists($field, $form)) { - if (isset($form[$field][0])) { - $form_field =& $form[$field][0]; - } - elseif (isset($form[$field]['keys'])) { - $form_field =& $form[$field]['keys']; - } - elseif (isset($form[$field]['key'])) { - $form_field =& $form[$field]['key']; + $fields = variable_get('cckfp_types', NULL); + $values = unserialize(variable_get('cckfp_values', array())); + $node_type = $form['type']['#value']; + + // workaround : exclude user_register to avoid fields being treated + // two times when the content profile registration module is used + + if (($form_id != "user_register") && is_array($values[$node_type])) { + + $privacyfields = array_filter($values[$node_type]); // get fields which need a padlock + + if (!empty($privacyfields)) { + + // get original author or current user (authoring new node) + $u = (int) isset($form['#node']->uid)? $form['#node']->uid : $user->uid; + + // get the widgets used for fields of this node type + $fieldtypes = content_fields(NULL, $node_type); // make use of results cached by _content_type_info, no db hit + $needpadlock = array(); + + foreach ($privacyfields as $field => $value) { + + // Get the current state of the field and set perms that will be used with jQ impromptu + $field_pref_sql = db_query("SELECT permission FROM {cckfp} WHERE uid = %d AND type_name = '%s' AND field_name = '%s'", $u, $node_type, $field); + $field_pref = (string) db_result($field_pref_sql); + if ($field_pref == "") { + $field_pref = variable_get('cckfp_'. $node_type .'_default', 'e'); // Set to the default state of the field + } + $privacyfields[$field] = $field_pref; + + switch ($fieldtypes[$field]['widget']['type']) { + + // treats special cases separately : + // $form['#field_info'][$field]['widget']['label'] used insted of ['#title'] + // some other CCK fields should be treated here + // TODO : do not work for date fields if end dates or repetitions are set + + case "email_textfield" : + case "date_select" : + case "date_combo" : + case "date_popup" : + case "date_text" : + if (isset($form['#field_info'][$field]['widget']['label'])) { + $form['#field_info'][$field]['widget']['label'] .= " ". t(Privacy) .""; } else { - $form_field =& $form[$field]; - } - // Get the current state of the field - $field_pref_sql = db_query("SELECT permission FROM {cckfp} WHERE uid = %d AND type_name = '%s' AND field_name = '%s'", $uid, $node_name, $field); - $field_pref = (string) db_result($field_pref_sql); - if ($field_pref == "") { - //Get the default state of the field - $type_default_name = 'cckfp_' . $node_name .'_default'; - $field_pref = variable_get($type_default_name, 'e'); - } - - // Let's add the field name to the array of fields - $cckfp_enabled_fields[$field] = $field_pref; - - // Add the padlock icon & link to the JQuery function - // @TODO: Add this via jQuery to degrade gracefully in browsers without JavaScript enabled. - // @TODO: Get the padlock to also appear on field group titles (fieldset legends), if selected. - if (isset($form_field['#title'])) { - $form_field['#title'] .= ""; - //email fields are special, they must be handled a bit differently. - if (in_array($form[$field][0]['#type'], array("email_textfield", "date_combo"))) { - $form['#field_info'][$field]['widget']['label'] .= ""; - } - } - else if (isset($form[$field]['#title'])) { - $form[$field]['#title'] .= ""; - } - else if (isset($form_field[0]['#title'])) { - $form_field[0]['#title'] .= ""; - } - else { - $form['#field_info'][$field]['widget']['label'] .= ""; + $needpadlock[$field] = TRUE; } - } + break; + // other special case goes here + + // normal cases that need will be treated recursively throught the form + // case "location_element" : // shown as fieldset with various sub fields + // case "link" : // code needs work + // case "optionwidgets_select" : + // case "userreference_autocomplete" : + // case "userreference_select" : + default : $needpadlock[$field] = TRUE; // field still need a padlock } } + + if (!empty($needpadlock)) { // look for fields left recursively throught the form + _cck_field_privacy_add_padlock($form, $needpadlock); + } + + // include javascript and css only if needed + jquery_impromptu_add(); + drupal_add_js(drupal_get_path('module', 'cck_field_privacy') .'/cck_field_privacy.js'); + drupal_add_js(array( + 'cck_field_privacy' => array( + 'action' => url('cck_field_privacy/ajax'), + 'uid' => $u, + 'content_type' => $node_type, + 'default_value' => $privacyfields, + ), + ), 'setting'); } } - - // include javascript and css - jquery_impromptu_add(); // css and js - drupal_add_js(drupal_get_path('module', 'cck_field_privacy') .'/cck_field_privacy.js'); - - // output per-page settings - drupal_add_js(array( - 'cck_field_privacy' => array( - 'action' => url('cck_field_privacy/ajax'), - 'uid' => $uid, - 'content_type' => $node_name, - 'default_value' => $cckfp_enabled_fields, - ), - ), 'setting'); } } return $form; } /** + * Recursively add a padlock where needed + */ +function _cck_field_privacy_add_padlock(&$elements, &$needpadlock) { + + // only treats keys that are not properties (i.e., does not begin with '#') + foreach (element_children($elements) as $field) { + if (isset($elements[$field]) && $elements[$field]) { + if (array_key_exists($field, $needpadlock)) { // form element is handled by cckfp + $lockimg = "". t(Privacy) .""; + if (isset($elements[$field][0]['#type'])) { // content sub field first + switch ($elements[$field][0]['#type']) { + case "link" : // link widget + // WARNING : possibly 2 text fields with the same label shown 2 times + // with different suffix 'Title' and 'URL' : only the 'first label id' will work + // should use the widget description or some theming on the widget output + $elements[$field][0]['#title'] = $lockimg ." ". $elements[$field][0]['#title']; + break; + + case "userreference_autocomplete" : + // ugly display if content_multiple_values is used + // padlock shoud be shown after $elements[$field]['#title'] but it does not react + $elements[$field][0]['#title'] .= " ". $lockimg; + break; + + default : // assume field is a standard CCK field and not fieldgroup + $elements[$field][0]['#title'] .= " ". $lockimg; + break; + } + } + elseif (isset($elements[$field]['#type'])) { + switch ($elements[$field]['#type']) { + case "tabpage" : + // fielgroup shown as tab by the cck fieldgroup tabs module + // label will be already a link that should be closed first + // but an

tag without link also use this label + // html validation error without modifiing tabs' template + $elements[$field]['#title'] .= $lockimg; + break; + + case "fieldset" : + if (isset($elements[$field]['#collapsible']) + && ($elements[$field]['#collapsible'] == 1)) { // collapsible fieldset + // using description because a padlock in the clickable legend tag will not work + $elements[$field]['#description'] = $lockimg ." ". $elements[$field]['#description']; + } + else { $elements[$field]['#title'] .= " ". $lockimg; } + break; + + case "userreference_select" : + case "optionwidgets_select" : + $elements[$field]['#title'] .= " ". $lockimg; + break; + + default : // TODO : field probably not properly handled + $elements[$field]['#title'] .= " ". $lockimg; + break; + } + } + else { + /* field type not properly handled */ + } + + $needpadlock[$field] = FALSE; + $needpadlock = array_filter($needpadlock); + } + + if (!empty($needpadlock)) { + // recursing through children elements if privacy fields left + _cck_field_privacy_add_padlock($elements[$field], $needpadlock); + } + } + } +} + +/** * MENU_CALLBACK for cck_field_privacy/ajax. * * @return String