t('View own fieldnote')); $perms['edit own fieldnote'] = array('title' => t('Edit own fieldnote')); $perms['view any fieldnote'] = array('title' => t('View any fieldnote')); $perms['edit any fieldnote'] = array('title' => t('Edit any fieldnote')); return $perms; } /** * Implements hook_field_access(). * * We want to make sure that fields aren't being seen or edited * by those who shouldn't. * * We have to build a permission string similar to those in * hook_permission() in order to ask Drupal whether the user * has that permission. Permission strings will end up being * like 'view any fieldnote' or 'edit own fieldnote'. * * The tricky thing here is that a field can be attached to any type * of entity, so it's not always trivial to figure out whether * $account 'owns' the entity. We'll support access restrictions for * user and node entity types, and be permissive with others, * since that's easy to demonstrate. * * @see field_permission_example_permissions() */ function field_permission_example_field_access($op, $field, $entity_type, $entity, $account) { // This hook will be invoked for every field type, so we have to // check that it's the one we're interested in. if ($field['type'] == 'field_permission_example_fieldnote') { // First we'll check if the user has the 'superuser' // permissions that node provides. This way administrators // will be able to administer the content types. if (user_access('bypass node access', $account)) { drupal_set_message(t('User can bypass node access.')); return TRUE; } if (user_access('administer content types', $account)) { drupal_set_message(t('User can administer content types.')); return TRUE; } // Now check for our own permissions. // $context will end up being either 'any' or 'own.' $context = 'any'; switch ($entity_type) { case 'user': case 'node': // While administering the field itself, $entity will be // NULL, so we have to check it. if ($entity) { if ($entity->uid == $account->uid) { $context = 'own'; } } } // Assemble a permission string, such as // 'view any fieldnote' $permission = $op . ' ' . $context . ' fieldnote'; // Finally, ask Drupal if this account has that permission. $access = user_access($permission, $account); $status = 'FALSE'; if ($access) { $status = 'TRUE'; } drupal_set_message($permission . ': ' . $status); return $access; } // We have no opinion on field types other than our own. return TRUE; } /** * Implements hook_field_info(). * * Provides the description of the field. */ function field_permission_example_field_info() { return array( // We name our field as the associative name of the array. 'field_permission_example_fieldnote' => array( 'label' => t('Fieldnote'), 'description' => t('Place a note-taking field on entities, with granular permissions.'), 'default_widget' => 'field_permission_example_widget', 'default_formatter' => 'field_permission_example_formatter', ), ); } /** * Implements hook_field_is_empty(). * * hook_field_is_empty() is where Drupal asks us if this field is empty. * Return TRUE if it does not contain data, FALSE if it does. This lets * the form API flag an error when required fields are empty. */ function field_permission_example_field_is_empty($item, $field) { return empty($item['notes']); } /** * Implements hook_field_formatter_info(). * * We need to tell Drupal about our excellent field formatter. * * It's some text in a div, styled to look like a sticky note. * * @see field_permission_example_field_formatter_view() */ function field_permission_example_field_formatter_info() { return array( // This formatter simply displays the text in a text field. 'field_permission_example_formatter' => array( 'label' => t('Simple text-based formatter'), 'field types' => array('field_permission_example_fieldnote'), ), ); } /** * Implements hook_field_formatter_view(). * * Here we output the field for general consumption. * * The field will have a sticky note appearance, thanks to some * simple CSS. * * Note that all of the permissions and access logic happens * in hook_field_access(), and none of it is here. */ function field_permission_example_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $element = array(); switch ($display['type']) { case 'field_permission_example_formatter': foreach ($items as $delta => $item) { $element[$delta] = array( // We wrap the fieldnote content up in a div tag. '#type' => 'html_tag', '#tag' => 'div', '#value' => check_plain($item['notes']), // Let's give the note a nice sticky-note CSS appearance. '#attributes' => array( 'class' => 'stickynote', ), // ..And this is the CSS for the stickynote. '#attached' => array( 'css' => array(drupal_get_path('module', 'field_permission_example') . '/field_permission_example.css'), ), ); } break; } return $element; } /** * Implements hook_field_widget_info(). * * We're implementing just one widget: A basic textarea. * * @see field_permission_example_field_widget_form() */ function field_permission_example_field_widget_info() { return array( 'field_permission_example_widget' => array( 'label' => t('Field note textarea'), 'field types' => array('field_permission_example_fieldnote'), ), ); } /** * Implements hook_field_widget_form(). * * Drupal wants us to create a form for our field. We'll use * something very basic like a default textarea. * * @see field_permission_example_field_widget_info() */ function field_permission_example_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { // Grab the existing value for the field. $value = isset($items[$delta]['notes']) ? $items[$delta]['notes'] : ''; // Grab a reference to the form element. $widget = $element; // Set up the delta for our return element. $widget['#delta'] = $delta; // Figure out which widget we need to generate. // In our case, there's only one type. switch ($instance['widget']['type']) { case 'field_permission_example_widget': $widget += array( '#type' => 'textarea', '#default_value' => $value, ); break; } $element['notes'] = $widget; return $element; } /** * Implements hook_menu(). * * Provides a simple user interface that gives the developer some clues. */ function field_permission_example_menu() { $items['examples/field_permission_example'] = array( 'title' => 'Field Permission Example', 'page callback' => '_field_permission_example_page', 'access callback' => TRUE, ); return $items; } /** * A simple page to explain to the developer what to do. * * @see field_permission_example.module */ function _field_permission_example_page() { $page = t("

The Field Permission Example module shows how you can restrict view and edit permissions within your field implementation. It adds a new field type called Fieldnote. Fieldnotes appear as simple text boxes on the create/edit form, and as sticky notes when viewed. By 'sticky note' we mean 'Post-It Note' but that's a trademarked term.

To see this field in action, add it to a content type or user profile. Go to the permissions page ("); $page .= l(t('admin/people/permissions'), 'admin/people/permissions'); $page .= t(") and look at the 'Field Permission Example' section. This allows you to change which roles can see and edit Fieldnote fields.

Creating different users with different capabilities will let you see these behaviors in action. Fieldnote helpfully displays a message telling you which permissions it is trying to resolve for the current field/user combination.

Definitely look through the code to see various implementation details.

"); return $page; } /** * @} End of "defgroup field_permission_example". */