security upadtes
This commit is contained in:
@@ -1,3 +1,20 @@
|
||||
References 7.x-2.x
|
||||
==================
|
||||
|
||||
#1391814 by yched: Fixed encoded HTML entities in select widget (regression
|
||||
introduced in 2.0)
|
||||
#1354580 by bforchhammer, yched: Fixed unpublished referenced nodes not
|
||||
displayed to users that are allowed to see them (regression introduced in 2.0)
|
||||
#1345816 by bforchhammer: Added support for the 'view_unpublished' module.
|
||||
#1256280 by girishmuraly: Added query alterability in hook_field_prepare_view().
|
||||
#1183300 by scor: Fixed extraneaous #maxlength in node_reference_autocomplete
|
||||
widget.
|
||||
#1410300 by yched: Fixed hook_field_install() should live in .install files.
|
||||
#1409022 by yched: Fixed missing view name notification message in D6 migration.
|
||||
#1391814 followup by yched: Fixed raw HTML in Views exposed filters.
|
||||
#998848 followup by larowlan, stevector, yched: template suggestions for
|
||||
referenced node in a specific view mode are wrong.
|
||||
|
||||
References 7.x-2.0
|
||||
==================
|
||||
|
||||
@@ -72,7 +89,7 @@ settings" will lose the currently selected view if it doesn't have a
|
||||
References 7.x-2.0-beta3
|
||||
========================
|
||||
|
||||
This release primarily aims at facilitating synchronized releases of 3rd party
|
||||
This release primarily aims at facilitating synchronized releases of 3rd party
|
||||
modules making use of the node_reference_potential_references() function.
|
||||
|
||||
#1154998 by yched: Rename _node_reference_potential_references() to
|
||||
|
@@ -7,9 +7,9 @@ dependencies[] = references
|
||||
dependencies[] = options
|
||||
files[] = node_reference.test
|
||||
|
||||
; Information added by drupal.org packaging script on 2011-12-22
|
||||
version = "7.x-2.0"
|
||||
; Information added by Drupal.org packaging script on 2017-04-18
|
||||
version = "7.x-2.2"
|
||||
core = "7.x"
|
||||
project = "references"
|
||||
datestamp = "1324596643"
|
||||
datestamp = "1492534745"
|
||||
|
||||
|
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the node_reference module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_field_schema().
|
||||
*/
|
||||
function node_reference_field_schema($field) {
|
||||
$columns = array(
|
||||
'nid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
);
|
||||
return array(
|
||||
'columns' => $columns,
|
||||
'indexes' => array('nid' => array('nid')),
|
||||
'foreign keys' => array(
|
||||
'nid' => array(
|
||||
'table' => 'node',
|
||||
'columns' => array('nid' => 'nid'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild views data cache (a callabck was renamed).
|
||||
*/
|
||||
function node_reference_update_7000() {
|
||||
if (function_exists('views_invalidate_cache')) {
|
||||
views_invalidate_cache();
|
||||
}
|
||||
}
|
@@ -47,29 +47,6 @@ function node_reference_field_info() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_schema().
|
||||
*/
|
||||
function node_reference_field_schema($field) {
|
||||
$columns = array(
|
||||
'nid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
);
|
||||
return array(
|
||||
'columns' => $columns,
|
||||
'indexes' => array('nid' => array('nid')),
|
||||
'foreign keys' => array(
|
||||
'nid' => array(
|
||||
'table' => 'node',
|
||||
'columns' => array('nid' => 'nid'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_settings_form().
|
||||
*/
|
||||
@@ -220,8 +197,8 @@ function node_reference_field_validate($entity_type, $entity, $field, $instance,
|
||||
function node_reference_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
|
||||
$checked_ids = &drupal_static(__FUNCTION__, array());
|
||||
|
||||
// Set an 'access' property on each item (TRUE if the node exists and is
|
||||
// accessible by the current user.
|
||||
// Set an 'access' property on each item (TRUE if the node exists and is
|
||||
// accessible by the current user).
|
||||
|
||||
// Extract ids to check.
|
||||
$ids = array();
|
||||
@@ -243,22 +220,35 @@ function node_reference_field_prepare_view($entity_type, $entities, $field, $ins
|
||||
$ids_to_check = array_diff($ids, array_keys($checked_ids));
|
||||
if (!empty($ids_to_check)) {
|
||||
$query = db_select('node', 'n')
|
||||
->addTag('node_access')
|
||||
->addMetaData('id', 'node_reference_field_prepare_view')
|
||||
->addMetaData('field', $field)
|
||||
->fields('n', array('nid'))
|
||||
->addTag('node_access');
|
||||
$condition = db_and()
|
||||
->condition('n.nid', $ids_to_check, 'IN')
|
||||
->condition('n.status', NODE_PUBLISHED);
|
||||
// Take the 'view own unpublished content' permission into account to
|
||||
// decide whether unpublished nodes should be hidden.
|
||||
if (!user_access('administer nodes') && !user_access('bypass node access')) {
|
||||
if (user_access('view own unpublished content') && $own_unpublished = db_query('SELECT nid FROM {node} WHERE uid = :uid AND status = :status', array(':uid' => $GLOBALS['user']->uid, ':status' => NODE_NOT_PUBLISHED))->fetchCol()) {
|
||||
// (n.nid IN (nodes) AND n.status = 1) OR n.nid = (unpublished)
|
||||
$condition = db_or()
|
||||
->condition($condition)
|
||||
// WHERE n.nid IN (nids to check) AND ...
|
||||
->condition('n.nid', $ids_to_check, 'IN');
|
||||
|
||||
// Unless the user has the right permissions, restrict on the node status.
|
||||
// (note: the 'view any unpublished content' permission is provided by the
|
||||
// 'view_unpublished' contrib module.)
|
||||
if (!user_access('bypass node access') && !user_access('view any unpublished content')) {
|
||||
// ... AND n.status = 1
|
||||
$status_condition = db_or()
|
||||
->condition('n.status', NODE_PUBLISHED);
|
||||
|
||||
// Take the 'view own unpublished content' permission into account to
|
||||
// decide whether some unpublished nodes should still be visible. We
|
||||
// only need the items in $ids_to_check because those are the only
|
||||
// entries that we are interested in. Any other nodes created by the
|
||||
// user are simply ignored so lets only retrieve that subset.
|
||||
if (user_access('view own unpublished content') && ($own_unpublished = db_query('SELECT nid FROM {node} WHERE uid = :uid AND status = :status AND nid IN (:nodes)', array(':uid' => $GLOBALS['user']->uid, ':status' => NODE_NOT_PUBLISHED, ':nodes' => $ids_to_check))->fetchCol())) {
|
||||
// ... AND (n.status = 1 OR n.nid IN (own unpublished))
|
||||
$status_condition
|
||||
->condition('n.nid', $own_unpublished, 'IN');
|
||||
}
|
||||
|
||||
$query->condition($status_condition);
|
||||
}
|
||||
$query->condition($condition);
|
||||
|
||||
$accessible_ids = $query->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// Populate our static list so that we do not query on those ids again.
|
||||
@@ -599,6 +589,7 @@ function node_reference_field_widget_settings_form($field, $instance) {
|
||||
'#options' => array(
|
||||
'starts_with' => t('Starts with'),
|
||||
'contains' => t('Contains'),
|
||||
'fuzzy' => t('Fuzzy search'),
|
||||
),
|
||||
'#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes.'),
|
||||
);
|
||||
@@ -624,6 +615,7 @@ function node_reference_field_widget_form(&$form, &$form_state, $field, $instanc
|
||||
'#default_value' => isset($items[$delta]['nid']) ? $items[$delta]['nid'] : NULL,
|
||||
'#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'] . '/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/' . $field['field_name'],
|
||||
'#size' => $instance['widget']['settings']['size'],
|
||||
'#maxlength' => NULL,
|
||||
'#element_validate' => array('node_reference_autocomplete_validate'),
|
||||
'#value_callback' => 'node_reference_autocomplete_value',
|
||||
);
|
||||
@@ -675,14 +667,14 @@ function node_reference_autocomplete_validate($element, &$form_state, $form) {
|
||||
// Explicit nid. Check that the 'title' part matches the actual title for
|
||||
// the nid.
|
||||
list(, $title, $nid) = $matches;
|
||||
if (!empty($title)) {
|
||||
if (!empty($nid)) {
|
||||
$real_title = db_select('node', 'n')
|
||||
->fields('n', array('title'))
|
||||
->condition('n.nid', $nid)
|
||||
->execute()
|
||||
->fetchField();
|
||||
if (trim($title) != trim($real_title)) {
|
||||
form_error($element, t('%name: title mismatch. Please check your selection.', array('%name' => $instance['label'])));
|
||||
if (empty($real_title)) {
|
||||
form_error($element, t('%name: No node found. Please check your selection.', array('%name' => $instance['label'])));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -741,14 +733,18 @@ function _node_reference_options($field, $flat = TRUE) {
|
||||
|
||||
$options = array();
|
||||
foreach ($references as $key => $value) {
|
||||
// The label, displayed in selects and checkboxes/radios, should have HTML
|
||||
// entities unencoded. The widgets (core's options.module) take care of
|
||||
// applying the relevant filters (strip_tags() or filter_xss()).
|
||||
$label = html_entity_decode($value['rendered'], ENT_QUOTES);
|
||||
if (empty($value['group']) || $flat) {
|
||||
$options[$key] = $value['rendered'];
|
||||
$options[$key] = $label;
|
||||
}
|
||||
else {
|
||||
// The group name, displayed in selects, cannot contain tags, and should
|
||||
// have HTML entities unencoded.
|
||||
$group = html_entity_decode(strip_tags($value['group']), ENT_QUOTES);
|
||||
$options[$group][$key] = $value['rendered'];
|
||||
$options[$group][$key] = $label;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -842,11 +838,29 @@ function _node_reference_potential_references_standard($field, $options) {
|
||||
}
|
||||
|
||||
$query = db_select('node', 'n');
|
||||
|
||||
if (!user_access('bypass node access')) {
|
||||
// If the user is able to view their own unpublished nodes, allow them to
|
||||
// see these in addition to published nodes. Check that they actually have
|
||||
// some unpublished nodes to view before adding the condition.
|
||||
if (user_access('view own unpublished content') && $own_unpublished = db_query('SELECT nid FROM {node} WHERE uid = :uid AND status = :status', array(':uid' => $GLOBALS['user']->uid, ':status' => NODE_NOT_PUBLISHED))->fetchCol()) {
|
||||
$query->condition(db_or()
|
||||
->condition('n.status', NODE_PUBLISHED)
|
||||
->condition('n.nid', $own_unpublished, 'IN')
|
||||
);
|
||||
}
|
||||
else {
|
||||
// If not, restrict the query to published nodes.
|
||||
$query->condition('n.status', NODE_PUBLISHED);
|
||||
}
|
||||
|
||||
$query->addTag('node_access');
|
||||
}
|
||||
|
||||
$node_nid_alias = $query->addField('n', 'nid');
|
||||
$node_title_alias = $query->addField('n', 'title', 'node_title');
|
||||
$node_type_alias = $query->addField('n', 'type', 'node_type');
|
||||
$query->addTag('node_access')
|
||||
->addMetaData('id', ' _node_reference_potential_references_standard')
|
||||
$query->addMetaData('id', ' _node_reference_potential_references_standard')
|
||||
->addMetaData('field', $field)
|
||||
->addMetaData('options', $options);
|
||||
|
||||
@@ -864,6 +878,13 @@ function _node_reference_potential_references_standard($field, $options) {
|
||||
$query->condition('n.title', $options['string'] . '%', 'LIKE');
|
||||
break;
|
||||
|
||||
case 'fuzzy':
|
||||
$words = explode(' ', $options['string']);
|
||||
foreach ($words as $word) {
|
||||
$query->condition('n.title', '%' . $word . '%', 'LIKE');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'equals':
|
||||
default: // no match type or incorrect match type: use "="
|
||||
$query->condition('n.title', $options['string']);
|
||||
@@ -898,8 +919,8 @@ function _node_reference_potential_references_standard($field, $options) {
|
||||
* Menu callback for the autocomplete results.
|
||||
*/
|
||||
function node_reference_autocomplete($entity_type, $bundle, $field_name, $string = '') {
|
||||
$field = field_info_field($field_name);
|
||||
$instance = field_info_instance($entity_type, $field_name, $bundle);
|
||||
$field = field_info_field($field_name);
|
||||
|
||||
$options = array(
|
||||
'string' => $string,
|
||||
@@ -953,11 +974,11 @@ function node_reference_preprocess_node(&$vars) {
|
||||
// in a specific view mode).
|
||||
if (!empty($vars['node']->referencing_field)) {
|
||||
$node = $vars['node'];
|
||||
$field = $node->referencing_field;
|
||||
$vars['theme_hook_suggestions'][] = 'node_reference';
|
||||
$vars['theme_hook_suggestions'][] = 'node_reference__' . $field['field_name'];
|
||||
$vars['theme_hook_suggestions'][] = 'node_reference__' . $node->type;
|
||||
$vars['theme_hook_suggestions'][] = 'node_reference__' . $field['field_name'] . '__' . $node->type;
|
||||
$field_name = $node->referencing_field;
|
||||
$vars['theme_hook_suggestions'][] = 'node__node_reference';
|
||||
$vars['theme_hook_suggestions'][] = 'node__node_reference__' . $field_name;
|
||||
$vars['theme_hook_suggestions'][] = 'node__node_reference__' . $node->type;
|
||||
$vars['theme_hook_suggestions'][] = 'node__node_reference__' . $field_name . '__' . $node->type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -966,33 +987,42 @@ function node_reference_preprocess_node(&$vars) {
|
||||
*
|
||||
* When preparing a translation, load any translations of existing
|
||||
* references.
|
||||
* @todo Correctly implement after http://drupal.org/node/362021 is fixed.
|
||||
*/
|
||||
function node_reference_field_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
$addition = array();
|
||||
$addition[$field['field_name']] = array();
|
||||
if (isset($entity->translation_source->$field['field_name'])
|
||||
&& is_array($entity->translation_source->$field['field_name'])) {
|
||||
foreach ($entity->translation_source->$field['field_name'] as $key => $reference) {
|
||||
$reference_node = node_load($reference['nid']);
|
||||
// Test if the referenced node type is translatable and, if so,
|
||||
// load translations if the reference is not for the current language.
|
||||
// We can assume the translation module is present because it invokes 'prepare translation'.
|
||||
if (translation_supported_type($reference_node->type)
|
||||
&& !empty($reference_node->language)
|
||||
&& $reference_node->language != $node->language
|
||||
&& $translations = translation_node_get_translations($reference_node->tnid)) {
|
||||
// If there is a translation for the current language, use it.
|
||||
$addition[$field['field_name']][] = array(
|
||||
'nid' => isset($translations[$node->language])
|
||||
? $translations[$node->language]->nid
|
||||
: $reference['nid'],
|
||||
);
|
||||
function node_reference_field_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_langcode) {
|
||||
if (isset($items) && is_array($items)) {
|
||||
// Match each reference with its matching translation, if it exists.
|
||||
foreach ($items as $key => $item) {
|
||||
$reference_node = node_load($item['nid']);
|
||||
$items[$key]['nid'] = node_reference_find_translation($reference_node, $entity->language);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a translation for a specific node reference, if it exists.
|
||||
*
|
||||
* @param $reference_node
|
||||
* The untranslated node reference.
|
||||
* @param $langcode
|
||||
*
|
||||
* @return
|
||||
* A nid for the translation of the node reference,
|
||||
* otherwise the original untranslated nid if no translation exists.
|
||||
*/
|
||||
function node_reference_find_translation($reference_node, $langcode) {
|
||||
// Check if the source node translation is set and if translations are supported.
|
||||
if (isset($reference_node->tnid) && translation_supported_type($reference_node->type)) {
|
||||
// Determine whether an alternative language is being used.
|
||||
if (!empty($reference_node->language) && $reference_node->language != $langcode) {
|
||||
// Return a corresponding translation nid for the reference (if it exists).
|
||||
$translations = translation_node_get_translations($reference_node->tnid);
|
||||
if (isset($translations[$langcode])) {
|
||||
return $translations[$langcode]->nid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $addition;
|
||||
// Return the untranslated reference nid, no matching translations found.
|
||||
return $reference_node->nid;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1028,7 +1058,7 @@ function node_reference_content_migrate_field_alter(&$field_value, $instance_val
|
||||
'args' => $view_args,
|
||||
);
|
||||
if ($view_name) {
|
||||
$field_value['messages'][] = t("The field uses the view @view_name to determine referenceable nodes. You will need to manually edit the view and add a display of type 'References'.");
|
||||
$field_value['messages'][] = t("The field uses the view @view_name to determine referenceable nodes. You will need to manually edit the view and add a display of type 'References'.", array('@view_name' => $view_name));
|
||||
}
|
||||
unset($field_value['settings']['advanced_view']);
|
||||
unset($field_value['settings']['advanced_view_args']);
|
||||
@@ -1105,7 +1135,7 @@ function node_reference_field_views_data($field) {
|
||||
// the field name instead of the whole $field structure to keep views
|
||||
// data to a reasonable size.
|
||||
$data[$table][$id_column]['filter']['handler'] = 'views_handler_filter_in_operator';
|
||||
$data[$table][$id_column]['filter']['options callback'] = 'node_reference_views_options';
|
||||
$data[$table][$id_column]['filter']['options callback'] = 'node_reference_views_filter_options';
|
||||
$data[$table][$id_column]['filter']['options arguments'] = array($field['field_name']);
|
||||
|
||||
// Argument: display node.title in argument titles (handled in our custom
|
||||
@@ -1174,20 +1204,24 @@ function node_reference_field_views_data_views_data_alter(&$data, $field) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper callback for the views_handler_filter_in_operator filter.
|
||||
* 'options callback' for the views_handler_filter_in_operator filter.
|
||||
*
|
||||
* @param $field_name
|
||||
* The field name.
|
||||
*/
|
||||
function node_reference_views_options($field_name) {
|
||||
function node_reference_views_filter_options($field_name) {
|
||||
$options = array();
|
||||
|
||||
if ($field = field_info_field($field_name)) {
|
||||
$options = _node_reference_options($field, TRUE);
|
||||
// The options will be used as is in checkboxes, and thus need to be
|
||||
// sanitized first.
|
||||
|
||||
// The options are displayed in checkboxes within the filter admin form, and
|
||||
// in a select within an exposed filter. Checkboxes accept HTML, other
|
||||
// entities should be encoded; selects require the exact opposite: no HTML,
|
||||
// no encoding. We go for a middle ground: strip tags, leave entities
|
||||
// unencoded.
|
||||
foreach ($options as $key => $value) {
|
||||
$options[$key] = field_filter_xss($value);
|
||||
$options[$key] = strip_tags($value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -97,4 +97,59 @@ class NodeReferenceFormTest extends FieldTestCase {
|
||||
$allowed = array_slice(node_type_get_names(), 0, 1, TRUE);
|
||||
$this->runReferenceableNodeTest($allowed, t('Limited referencing'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test autocomplete widget.
|
||||
*/
|
||||
function testLongNodeReferenceWidget() {
|
||||
// Create regular test user.
|
||||
$web_user = $this->drupalCreateUser(array('create article content', 'access content'));
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
// Create test field instance on article node type.
|
||||
$instance = array(
|
||||
'field_name' => $this->field_name,
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'article',
|
||||
'widget' => array(
|
||||
'type' => 'node_reference_autocomplete',
|
||||
),
|
||||
);
|
||||
$instance = field_create_instance($instance);
|
||||
|
||||
// Create a node with a short title and a node with a title longer than
|
||||
// 128 characters.
|
||||
$node_short_title = $this->drupalCreateNode(array(
|
||||
'type' => 'page',
|
||||
'title' => $this->randomName(8),
|
||||
));
|
||||
$node_long_title = $this->drupalCreateNode(array(
|
||||
'type' => 'page',
|
||||
'title' => $this->randomName(200),
|
||||
));
|
||||
|
||||
// Display node creation form.
|
||||
$langcode = LANGUAGE_NONE;
|
||||
$this->drupalGet('node/add/article');
|
||||
$this->assertFieldByName("{$this->field_name}[$langcode][0][nid]", '', t('Widget is displayed'));
|
||||
|
||||
// Submit node form with autocomplete value for short title.
|
||||
$edit = array(
|
||||
'title' => $this->randomName(8),
|
||||
"{$this->field_name}[$langcode][0][nid]" => $node_short_title->title . ' [nid:' . $node_short_title->nid . ']',
|
||||
);
|
||||
$this->drupalPost('node/add/article', $edit, t('Save'));
|
||||
$this->assertRaw(t('!post %title has been created.', array('!post' => 'Article', '%title' => $edit["title"])), t('Article created.'));
|
||||
$this->assertText($node_short_title->title, t('Referenced node title is displayed.'));
|
||||
|
||||
// Submit node form with autocomplete value for long title.
|
||||
$edit = array(
|
||||
'title' => $this->randomName(8),
|
||||
"{$this->field_name}[$langcode][0][nid]" => $node_long_title->title . ' [nid:' . $node_long_title->nid . ']',
|
||||
);
|
||||
$this->drupalPost('node/add/article', $edit, t('Save'));
|
||||
$this->assertRaw(t('!post %title has been created.', array('!post' => 'Article', '%title' => $edit["title"])), t('Article created.'));
|
||||
$this->assertText($node_long_title->title, t('Referenced node title is displayed.'));
|
||||
}
|
||||
}
|
||||
|
@@ -189,7 +189,7 @@ function user_reference_feeds_processor_targets_alter(&$targets, $entity_type, $
|
||||
* The value to map. Can be an array or a string.
|
||||
*/
|
||||
function references_feeds_set_target($source, $entity, $target, $value) {
|
||||
if (empty($value)) {
|
||||
if (empty($value) || empty($value[key($value)])) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -10,9 +10,9 @@ files[] = views/references_plugin_display.inc
|
||||
files[] = views/references_plugin_style.inc
|
||||
files[] = views/references_plugin_row_fields.inc
|
||||
|
||||
; Information added by drupal.org packaging script on 2011-12-22
|
||||
version = "7.x-2.0"
|
||||
; Information added by Drupal.org packaging script on 2017-04-18
|
||||
version = "7.x-2.2"
|
||||
core = "7.x"
|
||||
project = "references"
|
||||
datestamp = "1324596643"
|
||||
datestamp = "1492534745"
|
||||
|
||||
|
@@ -13,8 +13,8 @@
|
||||
*/
|
||||
function reference_autocomplete_access($entity_type, $bundle, $field_name, $entity = NULL, $account = NULL) {
|
||||
return user_access('access content', $account)
|
||||
&& ($field = field_info_field($field_name))
|
||||
&& field_info_instance($entity_type, $field_name, $bundle)
|
||||
&& ($field = field_info_field($field_name))
|
||||
&& field_access('view', $field, $entity_type, $entity, $account)
|
||||
&& field_access('edit', $field, $entity_type, $entity, $account);
|
||||
}
|
||||
|
@@ -0,0 +1,12 @@
|
||||
name = References UUID
|
||||
core = 7.x
|
||||
package = Fields
|
||||
dependencies[] = references
|
||||
dependencies[] = uuid
|
||||
|
||||
; Information added by Drupal.org packaging script on 2017-04-18
|
||||
version = "7.x-2.2"
|
||||
core = "7.x"
|
||||
project = "references"
|
||||
datestamp = "1492534745"
|
||||
|
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* This provides UUID support for node and user references
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_load().
|
||||
*/
|
||||
function node_reference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_id_to_uuid($items, 'node', 'nid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_presave().
|
||||
*/
|
||||
function node_reference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_uuid_to_id($items, 'node', 'nid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_load().
|
||||
*/
|
||||
function user_reference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_id_to_uuid($items, 'user', 'uid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_presave().
|
||||
*/
|
||||
function user_reference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_uuid_to_id($items, 'user', 'uid');
|
||||
}
|
@@ -6,9 +6,9 @@ dependencies[] = field
|
||||
dependencies[] = references
|
||||
dependencies[] = options
|
||||
|
||||
; Information added by drupal.org packaging script on 2011-12-22
|
||||
version = "7.x-2.0"
|
||||
; Information added by Drupal.org packaging script on 2017-04-18
|
||||
version = "7.x-2.2"
|
||||
core = "7.x"
|
||||
project = "references"
|
||||
datestamp = "1324596643"
|
||||
datestamp = "1492534745"
|
||||
|
||||
|
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the user_reference module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_field_schema();
|
||||
*/
|
||||
function user_reference_field_schema($field) {
|
||||
$columns = array(
|
||||
'uid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
);
|
||||
return array(
|
||||
'columns' => $columns,
|
||||
'indexes' => array('uid' => array('uid')),
|
||||
'foreign keys' => array(
|
||||
'uid' => array(
|
||||
'table' => 'users',
|
||||
'columns' => array('uid' => 'uid'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
@@ -46,29 +46,6 @@ function user_reference_field_info() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_schema();
|
||||
*/
|
||||
function user_reference_field_schema($field) {
|
||||
$columns = array(
|
||||
'uid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
);
|
||||
return array(
|
||||
'columns' => $columns,
|
||||
'indexes' => array('uid' => array('uid')),
|
||||
'foreign keys' => array(
|
||||
'uid' => array(
|
||||
'table' => 'users',
|
||||
'columns' => array('uid' => 'uid'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_settings_form().
|
||||
*/
|
||||
@@ -250,6 +227,8 @@ function user_reference_field_prepare_view($entity_type, $entities, $field, $ins
|
||||
$ids_to_check = array_diff($ids, array_keys($checked_ids));
|
||||
if (!empty($ids_to_check)) {
|
||||
$query = db_select('users', 'u')
|
||||
->addMetaData('id', 'user_reference_field_prepare_view')
|
||||
->addMetaData('field', $field)
|
||||
->fields('u', array('uid'))
|
||||
->condition('u.uid', $ids_to_check, 'IN');
|
||||
$accessible_ids = $query->execute()->fetchAllAssoc('uid');
|
||||
@@ -415,7 +394,7 @@ function user_reference_field_formatter_prepare_view($entity_type, $entities, $f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -766,14 +745,18 @@ function _user_reference_options($field, $flat = TRUE) {
|
||||
|
||||
$options = array();
|
||||
foreach ($references as $key => $value) {
|
||||
// The label, displayed in selects and checkboxes/radios, should have HTML
|
||||
// entities unencoded. The widgets (core's options.module) take care of
|
||||
// applying the relevant filters (strip_tags() or filter_xss()).
|
||||
$label = html_entity_decode($value['rendered'], ENT_QUOTES);
|
||||
if (empty($value['group']) || $flat) {
|
||||
$options[$key] = $value['rendered'];
|
||||
$options[$key] = $label;
|
||||
}
|
||||
else {
|
||||
// The group name, displayed in selects, cannot contain tags, and should
|
||||
// have HTML entities unencoded.
|
||||
$group = html_entity_decode(strip_tags($value['group']), ENT_QUOTES);
|
||||
$options[$group][$key] = $value['rendered'];
|
||||
$options[$group][$key] = $label;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -929,8 +912,8 @@ function _user_reference_potential_references_standard($field, $options) {
|
||||
* Menu callback; Retrieve a pipe delimited string of autocomplete suggestions for existing users
|
||||
*/
|
||||
function user_reference_autocomplete($entity_type, $bundle, $field_name, $string = '') {
|
||||
$field = field_info_field($field_name);
|
||||
$instance = field_info_instance($entity_type, $field_name, $bundle);
|
||||
$field = field_info_field($field_name);
|
||||
|
||||
$options = array(
|
||||
'string' => $string,
|
||||
@@ -1062,7 +1045,7 @@ function user_reference_content_migrate_field_alter(&$field_value, $instance_val
|
||||
'args' => $view_args,
|
||||
);
|
||||
if ($view_name) {
|
||||
$field_value['messages'][] = t("The field uses the view @view_name to determine referenceable users. You will need to manually edit the view and add a display of type 'References'.");
|
||||
$field_value['messages'][] = t("The field uses the view @view_name to determine referenceable users. You will need to manually edit the view and add a display of type 'References'.", array('@view_name' => $view_name));
|
||||
}
|
||||
unset($field_value['settings']['advanced_view']);
|
||||
unset($field_value['settings']['advanced_view_args']);
|
||||
@@ -1197,7 +1180,7 @@ function user_reference_field_views_data_views_data_alter(&$data, $field) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper callback for the views_handler_filter_in_operator filter.
|
||||
* 'options callback' for the views_handler_filter_in_operator filter.
|
||||
*
|
||||
* @param $field_name
|
||||
* The field name.
|
||||
@@ -1210,10 +1193,14 @@ function user_reference_views_filter_options($field_name) {
|
||||
|
||||
if ($field = field_info_field($field_name)) {
|
||||
$options = _user_reference_options($field, TRUE);
|
||||
// The options will be used as is in checkboxes, and thus need to be
|
||||
// sanitized first.
|
||||
|
||||
// The options are displayed in checkboxes within the filter admin form, and
|
||||
// in a select within an exposed filter. Checkboxes accept HTML, other
|
||||
// entities should be encoded; selects require the exact opposite: no HTML,
|
||||
// no encoding. We go for a middle ground: strip tags, leave entities
|
||||
// unencoded.
|
||||
foreach ($options as $key => $value) {
|
||||
$options[$key] = field_filter_xss($value);
|
||||
$options[$key] = strip_tags($value);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user