updated core to 7.58 (right after the site was hacked)
This commit is contained in:
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @file
|
||||
* CSS for Field Example.
|
||||
*/
|
||||
.stickynote {
|
||||
background:#fefabc;
|
||||
padding:0.8em;
|
||||
font-family:cursive;
|
||||
font-size:1.1em;
|
||||
color: #000;
|
||||
width:15em;
|
||||
|
||||
-moz-transform: rotate(2deg);
|
||||
-webkit-transform: rotate(2deg);
|
||||
-o-transform: rotate(2deg);
|
||||
-ms-transform: rotate(2deg);
|
||||
transform: rotate(2deg);
|
||||
|
||||
box-shadow: 0px 4px 6px #333;
|
||||
-moz-box-shadow: 0px 4px 6px #333;
|
||||
-webkit-box-shadow: 0px 4px 6px #333;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
name = Field Permission Example
|
||||
description = A Field API Example: Fieldnote with Permissions
|
||||
package = Example modules
|
||||
core = 7.x
|
||||
files[] = tests/field_permission_example.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2017-01-10
|
||||
version = "7.x-1.x-dev"
|
||||
core = "7.x"
|
||||
project = "examples"
|
||||
datestamp = "1484076787"
|
||||
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Install function for the field_permission_example module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_field_schema().
|
||||
*
|
||||
* Defines the database schema of the field, using the format used by the
|
||||
* Schema API.
|
||||
*
|
||||
* We only want a simple text field, similar to the body of a node.
|
||||
*
|
||||
* Note that this field has only a normal text (which translates to
|
||||
* 16k of text in MySQL), and so therefore doesn't have an index.
|
||||
* More complex schema would probably have at least one indexed
|
||||
* column.
|
||||
*
|
||||
* @see http://drupal.org/node/146939
|
||||
* @see schemaapi
|
||||
* @see hook_field_schema()
|
||||
* @ingroup field_permission_example
|
||||
*/
|
||||
function field_permission_example_field_schema($field) {
|
||||
$columns = array(
|
||||
'notes' => array('type' => 'text', 'size' => 'normal', 'not null' => FALSE),
|
||||
);
|
||||
return array(
|
||||
'columns' => $columns,
|
||||
);
|
||||
}
|
@ -0,0 +1,329 @@
|
||||
<?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".
|
||||
*/
|
@ -0,0 +1,572 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Tests for Field Permission Example.
|
||||
*
|
||||
* @ingroup field_permission_example
|
||||
*/
|
||||
|
||||
/**
|
||||
* A generic field testing class.
|
||||
*
|
||||
* Subclass this one to test your specific field type
|
||||
* and get some basic unit testing for free.
|
||||
*
|
||||
* Since Simpletest only looks through one class definition
|
||||
* to find test functions, we define generic tests as
|
||||
* 'code_testWhatever' or 'form_testWhatever'. Subclasses
|
||||
* can then implement shim test methods that just call the
|
||||
* generic tests.
|
||||
*
|
||||
* 'code_' and 'form_' prefixes denote the type of test:
|
||||
* using code only, or through Drupal page forms.
|
||||
*
|
||||
* @ingroup field_permission_example
|
||||
*/
|
||||
class GenericFieldTest extends DrupalWebTestCase {
|
||||
|
||||
// Our tests will generate some random field instance
|
||||
// names. We store them here so many functions can act on them.
|
||||
protected $instanceNames;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Generic Field Test',
|
||||
'description' => 'Someone neglected to override GenericFieldTest::getInfo().',
|
||||
'group' => 'Examples',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supply the field types we wish to test.
|
||||
*
|
||||
* Return an array of field types to instantiate and test.
|
||||
*
|
||||
* @return array
|
||||
* The field types we wish to use.
|
||||
*/
|
||||
protected function getFieldTypes() {
|
||||
return array('these_are_not', 'valid_field_types', 'please_override');
|
||||
}
|
||||
|
||||
/**
|
||||
* The module to enable.
|
||||
*
|
||||
* @return string
|
||||
* Module machine name.
|
||||
*/
|
||||
protected function getModule() {
|
||||
return 'this-is-not-a-module-name-please-override';
|
||||
}
|
||||
|
||||
/**
|
||||
* Simpletest's setUp().
|
||||
*
|
||||
* We want to be able to subclass this class, so we jump
|
||||
* through a few hoops in order to get the modules from args
|
||||
* and add our own.
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->instanceNames = array();
|
||||
$modules = func_get_args();
|
||||
if (isset($modules[0]) && is_array($modules[0])) {
|
||||
$modules = $modules[0];
|
||||
}
|
||||
$modules[] = 'node';
|
||||
$modules[] = 'field_ui';
|
||||
parent::setUp($modules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that all required fields are specified in hook_field_info().
|
||||
*
|
||||
* The full list is label, description, settings, instance_settings,
|
||||
* default_widget, default_formatter, no_ui.
|
||||
*
|
||||
* Some are optional, and we won't check for those.
|
||||
*
|
||||
* In a sane world, this would be a unit test, rather than a
|
||||
* web test, but module_implements is unavailable to us
|
||||
* in unit tests.
|
||||
*
|
||||
* @see hook_field_info()
|
||||
*/
|
||||
public function runTestGenericFieldInfo() {
|
||||
$field_types = $this->getFieldTypes();
|
||||
$module = $this->getModule();
|
||||
$info_keys = array(
|
||||
'label',
|
||||
'description',
|
||||
'default_widget',
|
||||
'default_formatter',
|
||||
);
|
||||
// We don't want to use field_info_field_types()
|
||||
// because there is a hook_field_info_alter().
|
||||
// We're testing the module here, not the rest of
|
||||
// the system. So invoke hook_field_info() ourselves.
|
||||
$modules = module_implements('field_info');
|
||||
$this->assertTrue(in_array($module, $modules),
|
||||
'Module ' . $module . ' implements hook_field_info()');
|
||||
|
||||
foreach ($field_types as $field_type) {
|
||||
$field_info = module_invoke($module, 'field_info');
|
||||
$this->assertTrue(isset($field_info[$field_type]),
|
||||
'Module ' . $module . ' defines field type ' . $field_type);
|
||||
$field_info = $field_info[$field_type];
|
||||
foreach ($info_keys as $key) {
|
||||
$this->assertTrue(
|
||||
isset($field_info[$key]),
|
||||
$field_type . "'s " . $key . ' is set.'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all testable fields as instances to a content type.
|
||||
*
|
||||
* As a side-effect: Store the names of the instances created
|
||||
* in $this->$instance_names.
|
||||
*
|
||||
* @param object $node_type
|
||||
* A content type object. If none is provided, one will be generated.
|
||||
*
|
||||
* @return object
|
||||
* The content type object that has the fields attached.
|
||||
*/
|
||||
public function codeTestGenericAddAllFields($node_type = NULL) {
|
||||
$this->instanceNames = array();
|
||||
if (!$node_type) {
|
||||
$node_type = $this->drupalCreateContentType();
|
||||
}
|
||||
foreach ($this->getFieldTypes() as $field_type) {
|
||||
$instance_name = drupal_strtolower($this->randomName(32));
|
||||
$field = array(
|
||||
'field_name' => $instance_name,
|
||||
'type' => $field_type,
|
||||
);
|
||||
$field = field_create_field($field);
|
||||
$instance = array(
|
||||
'field_name' => $instance_name,
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $node_type->name,
|
||||
'label' => drupal_strtolower($this->randomName(20)),
|
||||
);
|
||||
// Finally create the instance.
|
||||
$instance = field_create_instance($instance);
|
||||
// Reset the caches...
|
||||
_field_info_collate_fields(TRUE);
|
||||
// Grab this instance.
|
||||
$verify_instance = field_info_instance('node', $instance_name, $node_type->name);
|
||||
$this->assertTrue($verify_instance, 'Instance object exists.');
|
||||
$this->assertTrue(
|
||||
$verify_instance != NULL,
|
||||
'field_info_instance() says ' . $instance_name . ' (' . $node_type->name . ') was created.'
|
||||
);
|
||||
$this->instanceNames[] = $instance_name;
|
||||
}
|
||||
return $node_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all fields in $this->field_names.
|
||||
*
|
||||
* @param mixed $node_type
|
||||
* A content type object. If none is specified,
|
||||
* the test fails.
|
||||
*/
|
||||
public function codeTestGenericRemoveAllFields($node_type = NULL) {
|
||||
if (!$node_type) {
|
||||
$this->fail('No node type.');
|
||||
}
|
||||
if (count($this->instanceNames) < 1) {
|
||||
$this->fail('There are no instances to remove.');
|
||||
return;
|
||||
}
|
||||
foreach ($this->instanceNames as $instance_name) {
|
||||
$instance = field_info_instance('node', $instance_name, $node_type->name);
|
||||
$this->assertTrue($instance, "Instance exists, now we'll delete it.");
|
||||
field_delete_field($instance_name);
|
||||
$instance = field_info_instance('node', $instance_name, $node_type->name);
|
||||
$this->assertFalse($instance, 'Instance was deleted.');
|
||||
}
|
||||
$this->instanceNames = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add and delete all field types through Form API.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function formTestGenericFieldNodeAddDeleteForm() {
|
||||
// Create and login user.
|
||||
$account = $this->drupalCreateUser(array(
|
||||
'administer content types',
|
||||
'administer fields',
|
||||
));
|
||||
$this->drupalLogin($account);
|
||||
|
||||
// Add a content type.
|
||||
$node_type = $this->drupalCreateContentType();
|
||||
|
||||
// Add all our testable fields.
|
||||
$field_names = $this->formAddAllFields($node_type);
|
||||
|
||||
// Now let's delete all the fields.
|
||||
foreach ($field_names as $field_name) {
|
||||
// This is the path for the 'delete' link on field admin page.
|
||||
$this->drupalGet('admin/structure/types/manage/' .
|
||||
$node_type->name . '/fields/field_' . $field_name . '/delete');
|
||||
// Click the 'delete' button.
|
||||
$this->drupalPost(NULL, array(), t('Delete'));
|
||||
$this->assertText(t('The field @field has been deleted from the @type content type.',
|
||||
array('@field' => $field_name, '@type' => $node_type->name)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all fields using Form API.
|
||||
*
|
||||
* @param mixed $node_type
|
||||
* A content type object. If none is specified,
|
||||
* the test fails.
|
||||
*/
|
||||
protected function formAddAllFields($node_type = NULL) {
|
||||
if (!$node_type) {
|
||||
$this->fail('No content type specified.');
|
||||
}
|
||||
// Get all our field types.
|
||||
$field_types = $this->getFieldTypes();
|
||||
// Keep a list of no_ui fields so we can tell the user.
|
||||
$unsafe_field_types = array();
|
||||
$field_names = array();
|
||||
|
||||
$manage_path = 'admin/structure/types/manage/' . $node_type->name . '/fields';
|
||||
foreach ($field_types as $field_type) {
|
||||
// Get the field info.
|
||||
$field_info = field_info_field_types($field_type);
|
||||
// Exclude no_ui field types.
|
||||
if (isset($field_info['no_ui']) && $field_info['no_ui']) {
|
||||
$unsafe_field_types[] = $field_type;
|
||||
}
|
||||
else {
|
||||
// Generate a name for our field.
|
||||
// 26 is max length for field name.
|
||||
$field_name = drupal_strtolower($this->randomName(26));
|
||||
$field_names[$field_type] = $field_name;
|
||||
// Create the field through Form API.
|
||||
$this->formCreateField($manage_path, $field_type, $field_name,
|
||||
$field_info['default_widget'], 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Tell the user which fields we couldn't test.
|
||||
if (!empty($unsafe_field_types)) {
|
||||
debug(
|
||||
'Unable to attach these no_ui fields: ' .
|
||||
implode(', ', $unsafe_field_types)
|
||||
);
|
||||
}
|
||||
|
||||
// Somehow clicking "save" isn't enough, and we have to
|
||||
// rebuild a few caches.
|
||||
node_types_rebuild();
|
||||
menu_rebuild();
|
||||
return $field_names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a field using the content type management form.
|
||||
*
|
||||
* @param mixed $manage_path
|
||||
* Path to our content type management form.
|
||||
* @param mixed $field_type
|
||||
* The type of field we're adding.
|
||||
* @param mixed $field_name
|
||||
* The name of the field instance we want.
|
||||
* @param mixed $widget_type
|
||||
* Which widget would we like?
|
||||
* @param mixed $cardinality
|
||||
* Cardinality for this field instance.
|
||||
*/
|
||||
protected function formCreateField($manage_path, $field_type, $field_name, $widget_type, $cardinality) {
|
||||
// $manage_path is the field edit form for our content type.
|
||||
$this->drupalGet($manage_path);
|
||||
$edit = array(
|
||||
'fields[_add_new_field][label]' => $field_name,
|
||||
'fields[_add_new_field][field_name]' => $field_name,
|
||||
'fields[_add_new_field][type]' => $field_type,
|
||||
'fields[_add_new_field][widget_type]' => $widget_type,
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Save'));
|
||||
|
||||
// Assume there are no settings for this,
|
||||
// so just press the button.
|
||||
$this->drupalPost(NULL, array(), t('Save field settings'));
|
||||
|
||||
$edit = array('field[cardinality]' => (string) $cardinality);
|
||||
$this->drupalPost(NULL, $edit, t('Save settings'));
|
||||
|
||||
debug(
|
||||
t('Saved settings for field !field_name with widget !widget_type and cardinality !cardinality',
|
||||
array(
|
||||
'!field_name' => $field_name,
|
||||
'!widget_type' => $widget_type,
|
||||
'!cardinality' => $cardinality,
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertText(t('Saved @name configuration.', array('@name' => $field_name)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a node with some field content.
|
||||
*
|
||||
* @return object
|
||||
* Node object for the created node.
|
||||
*/
|
||||
public function createFieldContentForUser(
|
||||
$account = NULL,
|
||||
$content = 'testable_content',
|
||||
$node_type = NULL,
|
||||
$instance_name = '',
|
||||
$column = NULL
|
||||
) {
|
||||
if (!$column) {
|
||||
$this->fail('No column name given.');
|
||||
return NULL;
|
||||
}
|
||||
if (!$account) {
|
||||
$account = $this->drupalCreateUser(array(
|
||||
'bypass node access',
|
||||
'administer content types',
|
||||
));
|
||||
}
|
||||
$this->drupalLogin($account);
|
||||
|
||||
if (!$node_type) {
|
||||
$node_type = $this->codeTestGenericAddAllFields();
|
||||
}
|
||||
|
||||
if (!$instance_name) {
|
||||
$instance_name = reset($this->instanceNames);
|
||||
}
|
||||
$field = array();
|
||||
$field[LANGUAGE_NONE][0][$column] = $content;
|
||||
|
||||
$settings = array(
|
||||
'type' => $node_type->name,
|
||||
$instance_name => $field,
|
||||
);
|
||||
$node = $this->drupalCreateNode($settings);
|
||||
|
||||
$this->assertTrue($node, 'Node of type ' . $node->type . ' allegedly created.');
|
||||
|
||||
$node = node_load($node->nid);
|
||||
debug('Loaded node id: ' . $node->nid);
|
||||
$this->assertTrue($node->$instance_name, 'Field actually created.');
|
||||
$field = $node->$instance_name;
|
||||
$this->assertTrue($field[LANGUAGE_NONE][0][$column] == $content,
|
||||
'Content was stored properly on the field.');
|
||||
return $node;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class FieldTestPermissionsExample extends GenericFieldTest {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp(array('field_permission_example'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Field Permission Example',
|
||||
'description' => 'Various tests on the functionality of the Fieldnote field.',
|
||||
'group' => 'Examples',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getFieldTypes() {
|
||||
return array('field_permission_example_fieldnote');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getModule() {
|
||||
return 'field_permission_example';
|
||||
}
|
||||
|
||||
/**
|
||||
* Override createFieldContentForUser().
|
||||
*
|
||||
* We override so we can make sure $column is set to 'notes'.
|
||||
*/
|
||||
public function createFieldContentForUser(
|
||||
$account = NULL,
|
||||
$content = 'fieldnote_testable_content',
|
||||
$node_type = NULL,
|
||||
$instance_name = '',
|
||||
$column = 'notes'
|
||||
) {
|
||||
return parent::createFieldContentForUser($account, $content, $node_type, $instance_name, $column);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test of hook_field_info() and other implementation requirements.
|
||||
*
|
||||
* @see GenericFieldTest::runTestGenericFieldInfo()
|
||||
*/
|
||||
public function testFieldnoteInfo() {
|
||||
$this->runTestGenericFieldInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add and remove the field through Form API.
|
||||
*/
|
||||
public function testAddRemoveFieldnoteForm() {
|
||||
$this->formTestGenericFieldNodeAddDeleteForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add and remove the field through code.
|
||||
*/
|
||||
public function testAddRemoveFieldnoteCode() {
|
||||
$node_type = $this->codeTestGenericAddAllFields();
|
||||
$this->codeTestGenericRemoveAllFields($node_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test view permissions.
|
||||
*/
|
||||
public function testFieldnoteViewPerms() {
|
||||
// We create two sets of content so we can get a few
|
||||
// test cases out of the way.
|
||||
$view_own_content = $this->randomName(23);
|
||||
$view_any_content = $this->randomName(23);
|
||||
$view_own_node = $this->createFieldContentForUser(NULL, $view_own_content);
|
||||
// Get the type of the node so we can create another one.
|
||||
$node_type = node_type_load($view_own_node->type);
|
||||
$view_any_node = $this->createFieldContentForUser(NULL, $view_any_content, $node_type);
|
||||
|
||||
// There should be a node now, with some lovely content, but it's the wrong
|
||||
// user for the view-own test.
|
||||
$view_own_account = $this->drupalCreateUser(array(
|
||||
'view own fieldnote',
|
||||
));
|
||||
debug("Created user with 'view own fieldnote' permission.");
|
||||
|
||||
// Now change the user id for the test node.
|
||||
$view_own_node = node_load($view_own_node->nid);
|
||||
$view_own_node->uid = $view_own_account->uid;
|
||||
node_save($view_own_node);
|
||||
$view_own_node = node_load($view_own_node->nid);
|
||||
$this->assertTrue($view_own_node->uid == $view_own_account->uid, 'New user assigned to node.');
|
||||
|
||||
// Now we want to look at the page with the field and
|
||||
// check that we can see it.
|
||||
$this->drupalLogin($view_own_account);
|
||||
|
||||
$this->drupalGet('node/' . $view_own_node->nid);
|
||||
// Check that the field content is present.
|
||||
$output_strings = $this->xpath("//div[contains(@class,'stickynote')]/text()");
|
||||
$this->assertEqual((string) reset($output_strings), $view_own_content);
|
||||
debug("'view own fieldnote' can view own field.");
|
||||
|
||||
// This account shouldn't be able to see the field on the
|
||||
// 'view any' node.
|
||||
$this->drupalGet('node/' . $view_any_node->nid);
|
||||
// Check that the field content is not present.
|
||||
$output_strings = $this->xpath("//div[contains(@class,'stickynote')]/text()");
|
||||
$this->assertNotEqual((string) reset($output_strings), $view_any_content);
|
||||
debug("'view own fieldnote' cannot view other field.");
|
||||
|
||||
// Now, to test for 'view any fieldnote' we create another user
|
||||
// with that permission, and try to look at the same node.
|
||||
$view_any_account = $this->drupalCreateUser(array(
|
||||
'view any fieldnote',
|
||||
));
|
||||
debug("Created user with 'view any fieldnote' permission.");
|
||||
$this->drupalLogin($view_any_account);
|
||||
// This account should be able to see the field on the
|
||||
// 'view any' node.
|
||||
$this->drupalGet('node/' . $view_any_node->nid);
|
||||
// Check that the field content is present.
|
||||
$output_strings = $this->xpath("//div[contains(@class,'stickynote')]/text()");
|
||||
$this->assertEqual((string) reset($output_strings), $view_any_content);
|
||||
debug("'view any fieldnote' can view other field.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test edit permissions.
|
||||
*
|
||||
* Note that this is mostly identical to testFieldnoteViewPerms() and could
|
||||
* probably be refactored.
|
||||
*/
|
||||
public function testFieldnoteEditPerms() {
|
||||
// We create two sets of content so we can get a few
|
||||
// test cases out of the way.
|
||||
$edit_own_content = $this->randomName(23);
|
||||
$edit_any_content = $this->randomName(23);
|
||||
$edit_own_node = $this->createFieldContentForUser(NULL, $edit_own_content);
|
||||
// Get the type of the node so we can create another one.
|
||||
$node_type = node_type_load($edit_own_node->type);
|
||||
$edit_any_node = $this->createFieldContentForUser(NULL, $edit_any_content, $node_type);
|
||||
|
||||
$edit_own_account = $this->drupalCreateUser(array(
|
||||
'edit own ' . $node_type->name . ' content',
|
||||
'edit own fieldnote',
|
||||
));
|
||||
debug("Created user with 'edit own fieldnote' permission.");
|
||||
|
||||
// Now change the user id for the test node.
|
||||
$edit_own_node = node_load($edit_own_node->nid);
|
||||
$edit_own_node->uid = $edit_own_account->uid;
|
||||
node_save($edit_own_node);
|
||||
$edit_own_node = node_load($edit_own_node->nid);
|
||||
$this->assertTrue($edit_own_node->uid == $edit_own_account->uid, 'New edit test user assigned to node.');
|
||||
|
||||
// Now we want to look at the page with the field and
|
||||
// check that we can see it.
|
||||
$this->drupalLogin($edit_own_account);
|
||||
|
||||
$this->drupalGet('node/' . $edit_own_node->nid . '/edit');
|
||||
$this->assertText($edit_own_content, "'edit own fieldnote' can edit own fieldnote.");
|
||||
|
||||
// This account shouldn't be able to edit the field on the
|
||||
// 'edit any' node.
|
||||
$this->drupalGet('node/' . $edit_any_node->nid . '/edit');
|
||||
$this->assertNoText($edit_any_content, "'edit own fieldnote' can not edit any fieldnote.");
|
||||
|
||||
// Now, to test for 'edit any fieldnote' we create another user
|
||||
// with that permission, and try to edit at the same node.
|
||||
// We have to add the ability to edit any node content, as well
|
||||
// or Drupal will deny us access to the page.
|
||||
$edit_any_account = $this->drupalCreateUser(array(
|
||||
'edit any ' . $node_type->name . ' content',
|
||||
'edit any fieldnote',
|
||||
));
|
||||
debug("Created user with 'edit any fieldnote' permission.");
|
||||
$this->drupalLogin($edit_any_account);
|
||||
// This account should be able to see the field on the
|
||||
// 'edit any' node.
|
||||
$this->drupalGet('node/' . $edit_any_node->nid . '/edit');
|
||||
$this->assertText($edit_any_content, "'edit any fieldnote' can edit any fieldnote.");
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user