field_permission_example.module in Examples for Developers 7
Same filename and directory in other branches
An example field using the Field Types API.
File
field_permission_example/field_permission_example.moduleView source
<?php
/**
* @file
* An example field using the Field Types API.
*/
/**
* @defgroup field_permission_example Example: Field Permissions
* @ingroup examples
* @{
* Example using permissions on a Field API field.
*
* This example is a relatively simple text field you can attach to
* any fieldable entity.
*
* In this module we demonstrate how to limit access to a field.
* Drupal's Field API gives you two operations to permit or restrict:
* view and edit. So you can then decide who gets to see fields,
* who can edit them, and who can manage them.
*
* Our field is called field_permission_example_fieldnote. It has a
* simple default widget of a text area, and a default formatter
* that applies a CSS style to make it look like a sticky note.
*
* In addition to demonstrating how to set up permissions-based
* access to a field, this module also demonstrates the absolute
* minimum required to implement a field, since it doesn't have
* any field settings. The tests also have a generalized
* field testing class, called FieldTestGeneric, which can be easily
* subclassed and reused for other fields.
*
* If you wish to use this code as skeleton code for a field without
* permissions, you can simply remove field_permission_exampe_permission()
* and field_permission_field_access(). Also field_permission_example_menu()
* and _field_permission_example_page() are vestigial to the Examples
* project.
*
* How does it work?
*
* You can install this module and go to path /examples/field_permission_example
* for an introduction on how to use this field. Or see the same content at
* _field_permission_example_page().
*
* OK, how does the code work?
*
* As with any permission system, we implement hook_permission() in
* order to define a few permissions. In our case, users will want
* to either view or edit fieldnote fields. And, similar to the way
* node permissions work, we'll also include a context of either
* their own content or any content. So that gives us 4 permissions
* which administrators can assign to various roles. See
* field_permission_example_permission() for the list.
*
* With our permissions defined in hook_permission(), we can now
* handle requests for access. Those come in through
* hook_field_access(), which we've implemented as
* field_permission_example_field_access(). This function determines
* whether the user has the ability to view or edit the field
* in question by calling user_access(). We also give special edit
* access to users with the 'bypass node access' and
* 'administer content types' permissions, defined by the node module.
*
* One tricky part is that our field won't always be attached to
* nodes. It could be attached to any type of entity. This means
* that there's no general way to figure out if the user 'owns'
* the entity or not. Since this is a simple example, we'll just
* check for 'any' access to unknown entity types. We'll also
* limit our known entity types to node and user, since those
* are easy to demonstrate.
*
* In a real application, we'd have use-case specific permissions
* which might be more complex than these. Or perhaps simpler.
*
* You can see a more complex field implementation in
* field_example.module.
*
* @see field_example
* @see field_example.module
* @see field_types
* @see field
*/
/**
* Implements hook_permission().
*
* We want to let site administrators figure out who should
* be able to view, edit, and administer our field.
*
* Field permission operations can only be view or edit, in the
* context of one's own content or that of others. Contrast
* with content types where we also have to worry about who can
* create or delete content.
*/
function field_permission_example_permission() {
// Note: This would be very easy to generate programmatically,
// but it's all typed out here for clarity.
// The key text is the machine name of the permission.
$perms['view own fieldnote'] = array(
'title' => 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("<p>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.</p><p>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.</p><p>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.</p><p>Definitely look through the code to see various implementation details.</p>");
return $page;
}
/**
* @} End of "defgroup field_permission_example".
*/
Functions
Name | Description |
---|---|
field_permission_example_field_access | Implements hook_field_access(). |
field_permission_example_field_formatter_info | Implements hook_field_formatter_info(). |
field_permission_example_field_formatter_view | Implements hook_field_formatter_view(). |
field_permission_example_field_info | Implements hook_field_info(). |
field_permission_example_field_is_empty | Implements hook_field_is_empty(). |
field_permission_example_field_widget_form | Implements hook_field_widget_form(). |
field_permission_example_field_widget_info | Implements hook_field_widget_info(). |
field_permission_example_menu | Implements hook_menu(). |
field_permission_example_permission | Implements hook_permission(). |
_field_permission_example_page | A simple page to explain to the developer what to do. |