1 |
85ad3d82
|
Assos Assos
|
<?php
|
2 |
|
|
|
3 |
|
|
/**
|
4 |
|
|
* @file
|
5 |
|
|
* This is the main script for the Field Permissions module. It merely contains
|
6 |
|
|
* the implementation of hooks invoked by Drupal core and CCK.
|
7 |
|
|
* All common functions are externalized into several scripts that are included
|
8 |
|
|
* on demand to save memory consumption during normal site operation.
|
9 |
|
|
*/
|
10 |
|
|
|
11 |
|
|
/**
|
12 |
|
|
* Indicates that a field does not have any access control.
|
13 |
|
|
*/
|
14 |
|
|
define('FIELD_PERMISSIONS_PUBLIC', 0);
|
15 |
|
|
|
16 |
|
|
/**
|
17 |
|
|
* Indicates that a field is private.
|
18 |
|
|
*
|
19 |
|
|
* Private fields are never displayed, and are only editable by the author (and
|
20 |
|
|
* by site administrators with the 'access private fields' permission).
|
21 |
|
|
*/
|
22 |
|
|
define('FIELD_PERMISSIONS_PRIVATE', 1);
|
23 |
|
|
|
24 |
|
|
/**
|
25 |
|
|
* Indicates that a field has custom permissions.
|
26 |
|
|
*/
|
27 |
|
|
define('FIELD_PERMISSIONS_CUSTOM', 2);
|
28 |
|
|
|
29 |
|
|
/**
|
30 |
|
|
* Implements hook_help().
|
31 |
|
|
*/
|
32 |
|
|
function field_permissions_help($path, $arg) {
|
33 |
|
|
switch ($path) {
|
34 |
|
|
// Main module help for the Field Permissions module.
|
35 |
|
|
case 'admin/help#field_permissions':
|
36 |
|
|
return '<p>' . t('Set field-level permissions to edit or view CCK fields in any node, edit field during node creation, and edit or view permissions for nodes owned by the current user.') . '</p>';
|
37 |
|
|
|
38 |
|
|
// Help for the Field Permissions overview page.
|
39 |
|
|
case 'admin/reports/fields/permissions':
|
40 |
|
|
return '<p>' . t('Report and troubleshoot field permissions.') . '</p>';
|
41 |
|
|
}
|
42 |
|
|
}
|
43 |
|
|
|
44 |
|
|
/**
|
45 |
|
|
* Implements hook_menu().
|
46 |
|
|
*/
|
47 |
|
|
function field_permissions_menu() {
|
48 |
|
|
$items['admin/reports/fields/list'] = array(
|
49 |
|
|
'title' => 'List',
|
50 |
|
|
'type' => MENU_DEFAULT_LOCAL_TASK,
|
51 |
|
|
'weight' => -10,
|
52 |
|
|
);
|
53 |
|
|
$items['admin/reports/fields/permissions'] = array(
|
54 |
|
|
'title' => 'Permissions',
|
55 |
|
|
'description' => 'Report and troubleshoot field permissions.',
|
56 |
|
|
'page callback' => 'field_permissions_overview',
|
57 |
|
|
'access arguments' => array('administer field permissions'),
|
58 |
|
|
'file' => 'field_permissions.admin.inc',
|
59 |
|
|
'type' => MENU_LOCAL_TASK,
|
60 |
|
|
'weight' => 0,
|
61 |
|
|
);
|
62 |
|
|
return $items;
|
63 |
|
|
}
|
64 |
|
|
|
65 |
|
|
/**
|
66 |
|
|
* Implementation of hook_permission().
|
67 |
|
|
*/
|
68 |
|
|
function field_permissions_permission() {
|
69 |
|
|
module_load_include('inc', 'field_permissions', 'field_permissions.admin');
|
70 |
|
|
return _field_permissions_permission();
|
71 |
|
|
}
|
72 |
|
|
|
73 |
|
|
/**
|
74 |
|
|
* Implements of hook_form_FORM_ID_alter().
|
75 |
|
|
*/
|
76 |
|
|
function field_permissions_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) {
|
77 |
|
|
// Injects the Field Permissions settings on the Edit field tab.
|
78 |
|
|
form_load_include($form_state, 'inc', 'field_permissions', 'field_permissions.admin');
|
79 |
|
|
return _field_permissions_field_settings_form_alter($form, $form_state, $form_id);
|
80 |
|
|
}
|
81 |
|
|
|
82 |
|
|
/**
|
83 |
|
|
* Implementation of hook_field_access().
|
84 |
|
|
*
|
85 |
|
|
* @param $op
|
86 |
|
|
* The operation to be performed. Possible values:
|
87 |
|
|
* - 'edit'
|
88 |
|
|
* - 'view'
|
89 |
|
|
* @param $field
|
90 |
|
|
* The field on which the operation is to be performed.
|
91 |
|
|
* @param $entity_type
|
92 |
|
|
* The type of entity; e.g. 'node' or 'user'.
|
93 |
|
|
* @param $entity
|
94 |
|
|
* The entity on which the operation is to be performed.
|
95 |
|
|
* @param $account
|
96 |
|
|
* The account to check.
|
97 |
|
|
*
|
98 |
|
|
* @return
|
99 |
|
|
* FALSE if the operation is not allowed.
|
100 |
|
|
* Note when field_access() is invoked, access is granted unless one
|
101 |
|
|
* implementation of hook_field_access() explicitly returns FALSE.
|
102 |
|
|
*
|
103 |
|
|
* @see field_access()
|
104 |
|
|
*/
|
105 |
|
|
function field_permissions_field_access($op, $field, $entity_type, $entity, $account) {
|
106 |
|
|
// Ignore the request if permissions have not been enabled for this field.
|
107 |
|
|
if (!isset($field['field_permissions']['type']) || $field['field_permissions']['type'] == FIELD_PERMISSIONS_PUBLIC) {
|
108 |
|
|
return;
|
109 |
|
|
}
|
110 |
|
|
// If the field is private, then only the author (and administrators with the
|
111 |
|
|
// 'access private fields' permissions) can view and edit it.
|
112 |
|
|
elseif ($field['field_permissions']['type'] == FIELD_PERMISSIONS_PRIVATE) {
|
113 |
|
|
if (isset($entity)) {
|
114 |
|
|
return _field_permissions_entity_is_owned_by_account($entity, $account) || user_access('access private fields', $account);
|
115 |
|
|
}
|
116 |
|
|
// If the entity does not exist, we must check if there is access to any
|
117 |
|
|
// entity; see comments in field_permissions_empty_entity_access(). In this
|
118 |
|
|
// case that will always be true, since private fields are always editable
|
119 |
|
|
// by their authors and in theory any user account can be the author of
|
120 |
|
|
// some entity on the site.
|
121 |
|
|
else {
|
122 |
|
|
return TRUE;
|
123 |
|
|
}
|
124 |
|
|
}
|
125 |
|
|
// Otherwise, check access by permission.
|
126 |
|
|
elseif ($field['field_permissions']['type'] == FIELD_PERMISSIONS_CUSTOM) {
|
127 |
|
|
if (!isset($entity)) {
|
128 |
|
|
return field_permissions_empty_entity_access($op, $field['field_name'], $account);
|
129 |
|
|
}
|
130 |
|
|
elseif ($op == 'view') {
|
131 |
|
|
return _field_permissions_field_view_access($field['field_name'], $entity_type, $entity, $account);
|
132 |
|
|
}
|
133 |
|
|
elseif ($op == 'edit') {
|
134 |
|
|
return _field_permissions_field_edit_access($field['field_name'], $entity_type, $entity, $account);
|
135 |
|
|
}
|
136 |
|
|
}
|
137 |
|
|
}
|
138 |
|
|
|
139 |
|
|
/**
|
140 |
|
|
* Determines custom field permissions access when the entity is unknown.
|
141 |
|
|
*
|
142 |
|
|
* When a module calls field_access() without providing an entity (which the
|
143 |
|
|
* API allows it to do), it is doing so in order to check generic access to the
|
144 |
|
|
* field. Therefore, we should only deny access if we know that there is no
|
145 |
|
|
* entity anywhere on the site for which the user has access to the provided
|
146 |
|
|
* field.
|
147 |
|
|
*
|
148 |
|
|
* For example, Views calls field_access('view') without providing the entity,
|
149 |
|
|
* in order to determine if the field can be included in the query itself. So
|
150 |
|
|
* we only want to return FALSE if we know that there are no entities for which
|
151 |
|
|
* access will be granted. Later on, Views will invoke field_access('view')
|
152 |
|
|
* again, indirectly, when rendering the fields using field_view_field(), and
|
153 |
|
|
* at that point the entity will be passed along so we can do our normal checks
|
154 |
|
|
* on it.
|
155 |
|
|
*
|
156 |
|
|
* As another example, the FileField Sources module uses field_access('edit')
|
157 |
|
|
* as a menu access callback for the IMCE file browser and does not pass along
|
158 |
|
|
* the entity. So we must return TRUE here if there is any entity for which the
|
159 |
|
|
* user is allowed to edit the field (otherwise the user would not have access
|
160 |
|
|
* to the IMCE file browser interface when editing the fields they do have
|
161 |
|
|
* permission to edit).
|
162 |
|
|
*
|
163 |
|
|
* @param $op
|
164 |
|
|
* The operation to be performed ('view' or 'edit').
|
165 |
|
|
* @param $field_name
|
166 |
|
|
* The name of the field whose access is being checked.
|
167 |
|
|
* @param $account
|
168 |
|
|
* The user account whose access is being checked.
|
169 |
|
|
*
|
170 |
|
|
* @return
|
171 |
|
|
* TRUE if access should be allowed, or FALSE if it shouln't.
|
172 |
|
|
*/
|
173 |
|
|
function field_permissions_empty_entity_access($op, $field_name, $account) {
|
174 |
|
|
$all_permissions['view'] = array(
|
175 |
|
|
'view ' . $field_name,
|
176 |
|
|
'view own ' . $field_name,
|
177 |
|
|
);
|
178 |
|
|
$all_permissions['edit'] = array(
|
179 |
|
|
'create ' . $field_name,
|
180 |
|
|
'edit ' . $field_name,
|
181 |
|
|
'edit own ' . $field_name,
|
182 |
|
|
);
|
183 |
|
|
|
184 |
|
|
// If there's any scenario where the user might have permission to perform
|
185 |
|
|
// the operation on the field, return TRUE.
|
186 |
|
|
if (isset($all_permissions[$op])) {
|
187 |
|
|
foreach ($all_permissions[$op] as $permission) {
|
188 |
|
|
if (user_access($permission, $account)) {
|
189 |
|
|
return TRUE;
|
190 |
|
|
}
|
191 |
|
|
}
|
192 |
|
|
}
|
193 |
|
|
|
194 |
|
|
return FALSE;
|
195 |
|
|
}
|
196 |
|
|
|
197 |
|
|
/**
|
198 |
|
|
* Implementation of hook_field_access('view').
|
199 |
|
|
*/
|
200 |
|
|
function _field_permissions_field_view_access($field_name, $entity_type, $entity, $account) {
|
201 |
|
|
// Check if user has access to view this field in any entity.
|
202 |
|
|
if (user_access('view ' . $field_name, $account)) {
|
203 |
|
|
return TRUE;
|
204 |
|
|
}
|
205 |
|
|
|
206 |
|
|
// If the user has permission to view entities that they own, return TRUE if
|
207 |
|
|
// they own this entity or FALSE if they don't.
|
208 |
|
|
if (user_access('view own ' . $field_name, $account)) {
|
209 |
|
|
return _field_permissions_entity_is_owned_by_account($entity, $account);
|
210 |
|
|
}
|
211 |
|
|
|
212 |
|
|
return FALSE;
|
213 |
|
|
}
|
214 |
|
|
|
215 |
|
|
/**
|
216 |
|
|
* Implementation of hook_field_access('edit').
|
217 |
|
|
*/
|
218 |
|
|
function _field_permissions_field_edit_access($field_name, $entity_type, $entity, $account) {
|
219 |
|
|
// If this is a new entity, check if the user has access to edit the field on
|
220 |
|
|
// entity creation.
|
221 |
|
|
if (isset($entity->is_new)) {
|
222 |
|
|
// Some entities provide an "is_new" property. If that is present, respect
|
223 |
|
|
// whatever it's set to.
|
224 |
|
|
$is_new = $entity->is_new;
|
225 |
|
|
}
|
226 |
|
|
else {
|
227 |
|
|
// Otherwise, try to find out if the entity is new by checking its ID. Note
|
228 |
|
|
// that checking empty() rather than !isset() is important here, to deal
|
229 |
|
|
// with the case of entities that store "0" as their ID while the final
|
230 |
|
|
// entity is in the process of being created (user accounts are a good
|
231 |
|
|
// example of this).
|
232 |
|
|
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
|
233 |
|
|
$is_new = empty($id);
|
234 |
|
|
}
|
235 |
|
|
if ($is_new) {
|
236 |
|
|
return user_access('create ' . $field_name, $account);
|
237 |
|
|
}
|
238 |
|
|
|
239 |
|
|
// Check if user has access to edit this field in any entity.
|
240 |
|
|
if (user_access('edit ' . $field_name, $account)) {
|
241 |
|
|
return TRUE;
|
242 |
|
|
}
|
243 |
|
|
|
244 |
|
|
// If the user has permission to edit entities that they own, return TRUE if
|
245 |
|
|
// they own this entity or FALSE if they don't.
|
246 |
|
|
if (user_access('edit own ' . $field_name, $account)) {
|
247 |
|
|
return _field_permissions_entity_is_owned_by_account($entity, $account);
|
248 |
|
|
}
|
249 |
|
|
|
250 |
|
|
return FALSE;
|
251 |
|
|
}
|
252 |
|
|
|
253 |
|
|
/**
|
254 |
|
|
* Returns TRUE if an entity is owned by a user account, FALSE otherwise.
|
255 |
|
|
*/
|
256 |
|
|
function _field_permissions_entity_is_owned_by_account($entity, $account) {
|
257 |
|
|
// Try to get the uid of the entity owner from the entity itself. If it's not
|
258 |
|
|
// set (for example, if the entity type does not store a uid or does not have
|
259 |
|
|
// a concept of "ownership"), we need to assume that the provided user
|
260 |
|
|
// account does not own it.
|
261 |
|
|
return isset($entity->uid) && $entity->uid == $account->uid;
|
262 |
|
|
} |