updated core to 7.73
This commit is contained in:
+90
-16
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Hooks provided by the Field module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup hooks
|
||||
@@ -23,14 +27,22 @@
|
||||
* @see hook_field_extra_fields_alter()
|
||||
*
|
||||
* @return
|
||||
* A nested array of 'pseudo-field' components. Each list is nested within
|
||||
* the following keys: entity type, bundle name, context (either 'form' or
|
||||
* A nested array of 'pseudo-field' elements. Each list is nested within the
|
||||
* following keys: entity type, bundle name, context (either 'form' or
|
||||
* 'display'). The keys are the name of the elements as appearing in the
|
||||
* renderable array (either the entity form or the displayed entity). The
|
||||
* value is an associative array:
|
||||
* - label: The human readable name of the component.
|
||||
* - description: A short description of the component contents.
|
||||
* - label: The human readable name of the element.
|
||||
* - description: A short description of the element contents.
|
||||
* - weight: The default weight of the element.
|
||||
* - edit: (optional) String containing markup (normally a link) used as the
|
||||
* element's 'edit' operation in the administration interface. Only for
|
||||
* 'form' context.
|
||||
* - delete: (optional) String containing markup (normally a link) used as the
|
||||
* element's 'delete' operation in the administration interface. Only for
|
||||
* 'form' context.
|
||||
*
|
||||
* @ingroup field_types
|
||||
*/
|
||||
function hook_field_extra_fields() {
|
||||
$extra['node']['poll'] = array(
|
||||
@@ -70,6 +82,8 @@ function hook_field_extra_fields() {
|
||||
* The associative array of 'pseudo-field' components.
|
||||
*
|
||||
* @see hook_field_extra_fields()
|
||||
*
|
||||
* @ingroup field_types
|
||||
*/
|
||||
function hook_field_extra_fields_alter(&$info) {
|
||||
// Force node title to always be at the top of the list by default.
|
||||
@@ -107,6 +121,9 @@ function hook_field_extra_fields_alter(&$info) {
|
||||
/**
|
||||
* Define Field API field types.
|
||||
*
|
||||
* Along with this hook, you also need to implement other hooks. See
|
||||
* @link field_types Field Types API @endlink for more information.
|
||||
*
|
||||
* @return
|
||||
* An array whose keys are field type names and whose values are arrays
|
||||
* describing the field type, with the following key/value pairs:
|
||||
@@ -193,8 +210,11 @@ function hook_field_info_alter(&$info) {
|
||||
/**
|
||||
* Define the Field API schema for a field structure.
|
||||
*
|
||||
* This hook MUST be defined in .install for it to be detected during
|
||||
* installation and upgrade.
|
||||
* This is invoked when a field is created, in order to obtain the database
|
||||
* schema from the module that defines the field's type.
|
||||
*
|
||||
* This hook must be defined in the module's .install file for it to be detected
|
||||
* during installation and upgrade.
|
||||
*
|
||||
* @param $field
|
||||
* A field structure.
|
||||
@@ -644,6 +664,8 @@ function hook_field_delete_revision($entity_type, $entity, $field, $instance, $l
|
||||
* The source entity from which field values are being copied.
|
||||
* @param $source_langcode
|
||||
* The source language from which field values are being copied.
|
||||
*
|
||||
* @ingroup field_language
|
||||
*/
|
||||
function hook_field_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_langcode) {
|
||||
// If the translating user is not permitted to use the assigned text format,
|
||||
@@ -1238,7 +1260,7 @@ function hook_field_formatter_view($entity_type, $entity, $field, $instance, $la
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup field_attach
|
||||
* @addtogroup field_attach
|
||||
* @{
|
||||
*/
|
||||
|
||||
@@ -1300,9 +1322,33 @@ function hook_field_attach_load($entity_type, $entities, $age, $options) {
|
||||
* This hook is invoked after the field module has performed the operation.
|
||||
*
|
||||
* See field_attach_validate() for details and arguments.
|
||||
*
|
||||
* @param $entity_type
|
||||
* The type of $entity; e.g., 'node' or 'user'.
|
||||
* @param $entity
|
||||
* The entity with fields to validate.
|
||||
* @param array $errors
|
||||
* The array of errors (keyed by field name, language code, and delta) that
|
||||
* have already been reported for the entity. The function should add its
|
||||
* errors to this array. Each error is an associative array with the following
|
||||
* keys and values:
|
||||
* - error: An error code (should be a string prefixed with the module name).
|
||||
* - message: The human readable message to be displayed.
|
||||
*/
|
||||
function hook_field_attach_validate($entity_type, $entity, &$errors) {
|
||||
// @todo Needs function body.
|
||||
// Make sure any images in article nodes have an alt text.
|
||||
if ($entity_type == 'node' && $entity->type == 'article' && !empty($entity->field_image)) {
|
||||
foreach ($entity->field_image as $langcode => $items) {
|
||||
foreach ($items as $delta => $item) {
|
||||
if (!empty($item['fid']) && empty($item['alt'])) {
|
||||
$errors['field_image'][$langcode][$delta][] = array(
|
||||
'error' => 'field_example_invalid',
|
||||
'message' => t('All images in articles need to have an alternative text set.'),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1504,6 +1550,8 @@ function hook_field_attach_prepare_translation_alter(&$entity, $context) {
|
||||
* - entity_type: The type of the entity to be displayed.
|
||||
* - entity: The entity with fields to render.
|
||||
* - langcode: The language code $entity has to be displayed in.
|
||||
*
|
||||
* @ingroup field_language
|
||||
*/
|
||||
function hook_field_language_alter(&$display_language, $context) {
|
||||
// Do not apply core language fallback rules if they are disabled or if Locale
|
||||
@@ -1525,6 +1573,8 @@ function hook_field_language_alter(&$display_language, $context) {
|
||||
* An associative array containing:
|
||||
* - entity_type: The type of the entity the field is attached to.
|
||||
* - field: A field data structure.
|
||||
*
|
||||
* @ingroup field_language
|
||||
*/
|
||||
function hook_field_available_languages_alter(&$languages, $context) {
|
||||
// Add an unavailable language.
|
||||
@@ -1575,7 +1625,7 @@ function hook_field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new)
|
||||
* @param $entity_type
|
||||
* The type of entity; for example, 'node' or 'user'.
|
||||
* @param $bundle
|
||||
* The bundle that was just deleted.
|
||||
* The name of the bundle that was just deleted.
|
||||
* @param $instances
|
||||
* An array of all instances that existed for the bundle before it was
|
||||
* deleted.
|
||||
@@ -1590,7 +1640,7 @@ function hook_field_attach_delete_bundle($entity_type, $bundle, $instances) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "defgroup field_attach".
|
||||
* @} End of "addtogroup field_attach".
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -1847,7 +1897,7 @@ function hook_field_storage_write($entity_type, $entity, $op, $fields) {
|
||||
$items = (array) $entity->{$field_name}[$langcode];
|
||||
$delta_count = 0;
|
||||
foreach ($items as $delta => $item) {
|
||||
// We now know we have someting to insert.
|
||||
// We now know we have something to insert.
|
||||
$do_insert = TRUE;
|
||||
$record = array(
|
||||
'entity_type' => $entity_type,
|
||||
@@ -2250,6 +2300,10 @@ function hook_field_storage_pre_update($entity_type, $entity, &$skip_fields) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup field_storage
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the maximum weight for the entity components handled by the module.
|
||||
*
|
||||
@@ -2263,9 +2317,12 @@ function hook_field_storage_pre_update($entity_type, $entity, &$skip_fields) {
|
||||
* @param $context
|
||||
* The context for which the maximum weight is requested. Either 'form', or
|
||||
* the name of a view mode.
|
||||
*
|
||||
* @return
|
||||
* The maximum weight of the entity's components, or NULL if no components
|
||||
* were found.
|
||||
*
|
||||
* @ingroup field_info
|
||||
*/
|
||||
function hook_field_info_max_weight($entity_type, $bundle, $context) {
|
||||
$weights = array();
|
||||
@@ -2277,6 +2334,11 @@ function hook_field_info_max_weight($entity_type, $bundle, $context) {
|
||||
return $weights ? max($weights) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup field_types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Alters the display settings of a field before it gets displayed.
|
||||
*
|
||||
@@ -2343,6 +2405,10 @@ function hook_field_display_ENTITY_TYPE_alter(&$display, $context) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup field_types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Alters the display settings of pseudo-fields before an entity is displayed.
|
||||
*
|
||||
@@ -2358,6 +2424,8 @@ function hook_field_display_ENTITY_TYPE_alter(&$display, $context) {
|
||||
* - entity_type: The entity type; e.g., 'node' or 'user'.
|
||||
* - bundle: The bundle name.
|
||||
* - view_mode: The view mode, e.g. 'full', 'teaser'...
|
||||
*
|
||||
* @ingroup field_types
|
||||
*/
|
||||
function hook_field_extra_fields_display_alter(&$displays, $context) {
|
||||
if ($context['entity_type'] == 'taxonomy_term' && $context['view_mode'] == 'full') {
|
||||
@@ -2387,6 +2455,8 @@ function hook_field_extra_fields_display_alter(&$displays, $context) {
|
||||
* - instance: The instance of the field.
|
||||
*
|
||||
* @see hook_field_widget_properties_alter()
|
||||
*
|
||||
* @ingroup field_widget
|
||||
*/
|
||||
function hook_field_widget_properties_ENTITY_TYPE_alter(&$widget, $context) {
|
||||
// Change a widget's type according to the time of day.
|
||||
@@ -2397,10 +2467,6 @@ function hook_field_widget_properties_ENTITY_TYPE_alter(&$widget, $context) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup field_storage".
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup field_crud
|
||||
* @{
|
||||
@@ -2508,7 +2574,7 @@ function hook_field_delete_field($field) {
|
||||
*
|
||||
* @param $instance
|
||||
* The instance as it is post-update.
|
||||
* @param $prior_$instance
|
||||
* @param $prior_instance
|
||||
* The instance as it was pre-update.
|
||||
*/
|
||||
function hook_field_update_instance($instance, $prior_instance) {
|
||||
@@ -2596,6 +2662,8 @@ function hook_field_purge_instance($instance) {
|
||||
*
|
||||
* @param $field
|
||||
* The field being purged.
|
||||
*
|
||||
* @ingroup field_storage
|
||||
*/
|
||||
function hook_field_storage_purge_field($field) {
|
||||
$table_name = _field_sql_storage_tablename($field);
|
||||
@@ -2613,6 +2681,8 @@ function hook_field_storage_purge_field($field) {
|
||||
*
|
||||
* @param $instance
|
||||
* The instance being purged.
|
||||
*
|
||||
* @ingroup field_storage
|
||||
*/
|
||||
function hook_field_storage_purge_field_instance($instance) {
|
||||
db_delete('my_module_field_instance_info')
|
||||
@@ -2634,6 +2704,8 @@ function hook_field_storage_purge_field_instance($instance) {
|
||||
* The (possibly deleted) field whose data is being purged.
|
||||
* @param $instance
|
||||
* The deleted field instance whose data is being purged.
|
||||
*
|
||||
* @ingroup field_storage
|
||||
*/
|
||||
function hook_field_storage_purge($entity_type, $entity, $field, $instance) {
|
||||
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
|
||||
@@ -2673,6 +2745,8 @@ function hook_field_storage_purge($entity_type, $entity, $field, $instance) {
|
||||
*
|
||||
* @return
|
||||
* TRUE if the operation is allowed, and FALSE if the operation is denied.
|
||||
*
|
||||
* @ingroup field_types
|
||||
*/
|
||||
function hook_field_access($op, $field, $entity_type, $entity, $account) {
|
||||
if ($field['field_name'] == 'field_of_interest' && $op == 'edit') {
|
||||
|
||||
@@ -318,7 +318,7 @@ function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b =
|
||||
// Unless a language suggestion is provided we iterate on all the
|
||||
// available languages.
|
||||
$available_languages = field_available_languages($entity_type, $field);
|
||||
$language = !empty($options['language'][$id]) ? $options['language'][$id] : $options['language'];
|
||||
$language = is_array($options['language']) && !empty($options['language'][$id]) ? $options['language'][$id] : $options['language'];
|
||||
$languages = _field_language_suggestion($available_languages, $language, $field_name);
|
||||
foreach ($languages as $langcode) {
|
||||
$grouped_items[$field_id][$langcode][$id] = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array();
|
||||
@@ -976,6 +976,12 @@ function field_attach_insert($entity_type, $entity) {
|
||||
/**
|
||||
* Save field data for an existing entity.
|
||||
*
|
||||
* When calling this function outside an entity save operation be sure to
|
||||
* clear caches for the entity:
|
||||
* @code
|
||||
* entity_get_controller($entity_type)->resetCache(array($entity_id))
|
||||
* @endcode
|
||||
*
|
||||
* @param $entity_type
|
||||
* The type of $entity; e.g. 'node' or 'user'.
|
||||
* @param $entity
|
||||
|
||||
@@ -60,11 +60,11 @@ function field_create_field($field) {
|
||||
}
|
||||
// Field type is required.
|
||||
if (empty($field['type'])) {
|
||||
throw new FieldException('Attempt to create a field with no type.');
|
||||
throw new FieldException(format_string('Attempt to create field @field_name with no type.', array('@field_name' => $field['field_name'])));
|
||||
}
|
||||
// Field name cannot contain invalid characters.
|
||||
if (!preg_match('/^[_a-z]+[_a-z0-9]*$/', $field['field_name'])) {
|
||||
throw new FieldException('Attempt to create a field with invalid characters. Only lowercase alphanumeric characters and underscores are allowed, and only lowercase letters and underscore are allowed as the first character');
|
||||
throw new FieldException(format_string('Attempt to create a field @field_name with invalid characters. Only lowercase alphanumeric characters and underscores are allowed, and only lowercase letters and underscore are allowed as the first character', array('@field_name' => $field['field_name'])));
|
||||
}
|
||||
|
||||
// Field name cannot be longer than 32 characters. We use drupal_strlen()
|
||||
@@ -189,7 +189,7 @@ function field_create_field($field) {
|
||||
}
|
||||
|
||||
// Clear caches
|
||||
field_cache_clear(TRUE);
|
||||
field_cache_clear();
|
||||
|
||||
// Invoke external hooks after the cache is cleared for API consistency.
|
||||
module_invoke_all('field_create_field', $field);
|
||||
@@ -244,9 +244,11 @@ function field_update_field($field) {
|
||||
// $prior_field may no longer be right.
|
||||
module_load_install($field['module']);
|
||||
$schema = (array) module_invoke($field['module'], 'field_schema', $field);
|
||||
$schema += array('columns' => array(), 'indexes' => array());
|
||||
$schema += array('columns' => array(), 'indexes' => array(), 'foreign keys' => array());
|
||||
// 'columns' are hardcoded in the field type.
|
||||
$field['columns'] = $schema['columns'];
|
||||
// 'foreign keys' are hardcoded in the field type.
|
||||
$field['foreign keys'] = $schema['foreign keys'];
|
||||
// 'indexes' can be both hardcoded in the field type, and specified in the
|
||||
// incoming $field definition.
|
||||
$field += array(
|
||||
@@ -286,7 +288,7 @@ function field_update_field($field) {
|
||||
drupal_write_record('field_config', $field, $primary_key);
|
||||
|
||||
// Clear caches
|
||||
field_cache_clear(TRUE);
|
||||
field_cache_clear();
|
||||
|
||||
// Invoke external hooks after the cache is cleared for API consistency.
|
||||
module_invoke_all('field_update_field', $field, $prior_field, $has_data);
|
||||
@@ -428,7 +430,7 @@ function field_delete_field($field_name) {
|
||||
->execute();
|
||||
|
||||
// Clear the cache.
|
||||
field_cache_clear(TRUE);
|
||||
field_cache_clear();
|
||||
|
||||
module_invoke_all('field_delete_field', $field);
|
||||
}
|
||||
@@ -522,17 +524,30 @@ function field_create_instance($instance) {
|
||||
* Updates an instance of a field.
|
||||
*
|
||||
* @param $instance
|
||||
* An associative array representing an instance structure. The required
|
||||
* keys and values are:
|
||||
* An associative array representing an instance structure. The following
|
||||
* required array elements specify which field instance is being updated:
|
||||
* - entity_type: The type of the entity the field is attached to.
|
||||
* - bundle: The bundle this field belongs to.
|
||||
* - field_name: The name of an existing field.
|
||||
* Read-only_id properties are assigned automatically. Any other
|
||||
* properties specified in $instance overwrite the existing values for
|
||||
* the instance.
|
||||
* The other array elements represent properties of the instance, and all
|
||||
* properties must be specified or their default values will be used (except
|
||||
* internal-use properties, which are assigned automatically). To avoid
|
||||
* losing the previously stored properties of the instance when making a
|
||||
* change, first load the instance with field_info_instance(), then override
|
||||
* the values you want to override, and finally save using this function.
|
||||
* Example:
|
||||
* @code
|
||||
* // Fetch an instance info array.
|
||||
* $instance_info = field_info_instance($entity_type, $field_name, $bundle_name);
|
||||
* // Change a single property in the instance definition.
|
||||
* $instance_info['required'] = TRUE;
|
||||
* // Write the changed definition back.
|
||||
* field_update_instance($instance_info);
|
||||
* @endcode
|
||||
*
|
||||
* @throws FieldException
|
||||
*
|
||||
* @see field_info_instance()
|
||||
* @see field_create_instance()
|
||||
*/
|
||||
function field_update_instance($instance) {
|
||||
|
||||
@@ -11,8 +11,7 @@ dependencies[] = field_sql_storage
|
||||
required = TRUE
|
||||
stylesheets[all][] = theme/field.css
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -146,7 +146,10 @@ class FieldInfo {
|
||||
|
||||
// Save in "static" and persistent caches.
|
||||
$this->fieldMap = $map;
|
||||
cache_set('field_info:field_map', $map, 'cache_field');
|
||||
if (lock_acquire('field_info:field_map')) {
|
||||
cache_set('field_info:field_map', $map, 'cache_field');
|
||||
lock_release('field_info:field_map');
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
@@ -174,7 +177,10 @@ class FieldInfo {
|
||||
}
|
||||
|
||||
// Store in persistent cache.
|
||||
cache_set('field_info:fields', $this->fieldsById, 'cache_field');
|
||||
if (lock_acquire('field_info:fields')) {
|
||||
cache_set('field_info:fields', $this->fieldsById, 'cache_field');
|
||||
lock_release('field_info:fields');
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the name/ID map.
|
||||
@@ -231,7 +237,10 @@ class FieldInfo {
|
||||
}
|
||||
|
||||
// Store in persistent cache.
|
||||
cache_set('field_info:instances', $this->bundleInstances, 'cache_field');
|
||||
if (lock_acquire('field_info:instances')) {
|
||||
cache_set('field_info:instances', $this->bundleInstances, 'cache_field');
|
||||
lock_release('field_info:instances');
|
||||
}
|
||||
}
|
||||
|
||||
$this->loadedAllInstances = TRUE;
|
||||
@@ -419,7 +428,11 @@ class FieldInfo {
|
||||
foreach ($instances as $instance) {
|
||||
$cache['fields'][] = $this->fieldsById[$instance['field_id']];
|
||||
}
|
||||
cache_set("field_info:bundle:$entity_type:$bundle", $cache, 'cache_field');
|
||||
|
||||
if (lock_acquire("field_info:bundle:$entity_type:$bundle")) {
|
||||
cache_set("field_info:bundle:$entity_type:$bundle", $cache, 'cache_field');
|
||||
lock_release("field_info:bundle:$entity_type:$bundle");
|
||||
}
|
||||
|
||||
return $instances;
|
||||
}
|
||||
@@ -460,7 +473,10 @@ class FieldInfo {
|
||||
|
||||
// Store in the 'static' and persistent caches.
|
||||
$this->bundleExtraFields[$entity_type][$bundle] = $info;
|
||||
cache_set("field_info:bundle_extra:$entity_type:$bundle", $info, 'cache_field');
|
||||
if (lock_acquire("field_info:bundle_extra:$entity_type:$bundle")) {
|
||||
cache_set("field_info:bundle_extra:$entity_type:$bundle", $info, 'cache_field');
|
||||
lock_release("field_info:bundle_extra:$entity_type:$bundle");
|
||||
}
|
||||
|
||||
return $this->bundleExtraFields[$entity_type][$bundle];
|
||||
}
|
||||
@@ -596,10 +612,12 @@ class FieldInfo {
|
||||
// Fill in default values.
|
||||
$display += array(
|
||||
'label' => 'above',
|
||||
'type' => $field_type_info['default_formatter'],
|
||||
'settings' => array(),
|
||||
'weight' => 0,
|
||||
);
|
||||
if (empty($display['type'])) {
|
||||
$display['type'] = $field_type_info['default_formatter'];
|
||||
}
|
||||
if ($display['type'] != 'hidden') {
|
||||
$formatter_type_info = field_info_formatter_types($display['type']);
|
||||
// Fall back to default formatter if formatter type is not available.
|
||||
|
||||
@@ -223,7 +223,11 @@ function _field_info_collate_types($reset = FALSE) {
|
||||
}
|
||||
drupal_alter('field_storage_info', $info['storage types']);
|
||||
|
||||
cache_set("field_info_types:$langcode", $info, 'cache_field');
|
||||
// Set the cache if we can acquire a lock.
|
||||
if (lock_acquire("field_info_types:$langcode")) {
|
||||
cache_set("field_info_types:$langcode", $info, 'cache_field');
|
||||
lock_release("field_info_types:$langcode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,6 +453,17 @@ function field_info_bundles($entity_type = NULL) {
|
||||
* - type: The field type.
|
||||
* - bundles: The bundles in which the field appears, as an array with entity
|
||||
* types as keys and the array of bundle names as values.
|
||||
* Example:
|
||||
* @code
|
||||
* array(
|
||||
* 'body' => array(
|
||||
* 'bundles' => array(
|
||||
* 'node' => array('page', 'article'),
|
||||
* ),
|
||||
* 'type' => 'text_with_summary',
|
||||
* ),
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
function field_info_field_map() {
|
||||
$cache = _field_info_field_cache();
|
||||
|
||||
@@ -128,7 +128,7 @@ function field_schema() {
|
||||
'not null' => TRUE,
|
||||
'default' => ''
|
||||
),
|
||||
'entity_type' => array(
|
||||
'entity_type' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 32,
|
||||
'not null' => TRUE,
|
||||
@@ -162,6 +162,7 @@ function field_schema() {
|
||||
),
|
||||
);
|
||||
$schema['cache_field'] = drupal_get_schema_unprocessed('system', 'cache');
|
||||
$schema['cache_field']['description'] = 'Cache table for the Field module to store already built field information.';
|
||||
|
||||
return $schema;
|
||||
}
|
||||
@@ -466,6 +467,27 @@ function field_update_7003() {
|
||||
// Empty update to force a rebuild of the registry.
|
||||
}
|
||||
|
||||
/**
|
||||
* Grant the new "administer fields" permission to trusted users.
|
||||
*/
|
||||
function field_update_7004() {
|
||||
// Assign the permission to anyone that already has a trusted core permission
|
||||
// that would have previously let them administer fields on an entity type.
|
||||
$rids = array();
|
||||
$permissions = array(
|
||||
'administer site configuration',
|
||||
'administer content types',
|
||||
'administer users',
|
||||
);
|
||||
foreach ($permissions as $permission) {
|
||||
$rids = array_merge($rids, array_keys(user_roles(FALSE, $permission)));
|
||||
}
|
||||
$rids = array_unique($rids);
|
||||
foreach ($rids as $rid) {
|
||||
_update_7000_user_role_grant_permissions($rid, array('administer fields'), 'field');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup updates-7.x-extra".
|
||||
*/
|
||||
|
||||
+31
-16
@@ -316,6 +316,21 @@ function field_help($path, $arg) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function field_permission() {
|
||||
return array(
|
||||
'administer fields' => array(
|
||||
'title' => t('Administer fields'),
|
||||
'description' => t('Additional permissions are required based on what the fields are attached to (for example, <a href="@url">administer content types</a> to manage fields attached to content).', array(
|
||||
'@url' => '#module-node',
|
||||
)),
|
||||
'restrict access' => TRUE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
@@ -342,17 +357,6 @@ function field_cron() {
|
||||
field_purge_batch($limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_modules_uninstalled().
|
||||
*/
|
||||
function field_modules_uninstalled($modules) {
|
||||
module_load_include('inc', 'field', 'field.crud');
|
||||
foreach ($modules as $module) {
|
||||
// TODO D7: field_module_delete is not yet implemented
|
||||
// field_module_delete($module);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_system_info_alter().
|
||||
*
|
||||
@@ -819,9 +823,9 @@ function field_view_value($entity_type, $entity, $field_name, $item, $display =
|
||||
*
|
||||
* This function can be used by third-party modules that need to output an
|
||||
* isolated field.
|
||||
* - Do not use inside node (or other entities) templates, use
|
||||
* - Do not use inside node (or any other entity) templates; use
|
||||
* render($content[FIELD_NAME]) instead.
|
||||
* - Do not use to display all fields in an entity, use
|
||||
* - Do not use to display all fields in an entity; use
|
||||
* field_attach_prepare_view() and field_attach_view() instead.
|
||||
* - The field_view_value() function can be used to output a single formatted
|
||||
* field value, without label or wrapping field markup.
|
||||
@@ -905,6 +909,7 @@ function field_view_field($entity_type, $entity, $field_name, $display = array()
|
||||
'entity' => $entity,
|
||||
'view_mode' => '_custom',
|
||||
'display' => $display,
|
||||
'language' => $langcode,
|
||||
);
|
||||
drupal_alter('field_attach_view', $result, $context);
|
||||
|
||||
@@ -947,20 +952,30 @@ function field_get_items($entity_type, $entity, $field_name, $langcode = NULL) {
|
||||
*/
|
||||
function field_has_data($field) {
|
||||
$query = new EntityFieldQuery();
|
||||
return (bool) $query
|
||||
->fieldCondition($field)
|
||||
$query = $query->fieldCondition($field)
|
||||
->range(0, 1)
|
||||
->count()
|
||||
// Neutralize the 'entity_field_access' query tag added by
|
||||
// field_sql_storage_field_storage_query(). The result cannot depend on the
|
||||
// access grants of the current user.
|
||||
->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT')
|
||||
->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');
|
||||
|
||||
return (bool) $query
|
||||
->execute() || (bool) $query
|
||||
->age(FIELD_LOAD_REVISION)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user has access to a given field.
|
||||
*
|
||||
* This function does not determine whether access is granted to the entity
|
||||
* itself, only the specific field. Callers are responsible for ensuring that
|
||||
* entity access is also respected. For example, when checking field access for
|
||||
* nodes, check node_access() before checking field_access(), and when checking
|
||||
* field access for entities using the Entity API contributed module,
|
||||
* check entity_access() before checking field_access().
|
||||
*
|
||||
* @param $op
|
||||
* The operation to be performed. Possible values:
|
||||
* - 'edit'
|
||||
|
||||
@@ -7,8 +7,7 @@ dependencies[] = field
|
||||
files[] = field_sql_storage.test
|
||||
required = TRUE
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -64,6 +64,49 @@ function _field_sql_storage_revision_tablename($field) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a table alias for a field data table.
|
||||
*
|
||||
* The table alias is unique for each unique combination of field name
|
||||
* (represented by $tablename), delta_group and language_group.
|
||||
*
|
||||
* @param $tablename
|
||||
* The name of the data table for this field.
|
||||
* @param $field_key
|
||||
* The numeric key of this field in this query.
|
||||
* @param $query
|
||||
* The EntityFieldQuery that is executed.
|
||||
*
|
||||
* @return
|
||||
* A string containing the generated table alias.
|
||||
*/
|
||||
function _field_sql_storage_tablealias($tablename, $field_key, EntityFieldQuery $query) {
|
||||
// No conditions present: use a unique alias.
|
||||
if (empty($query->fieldConditions[$field_key])) {
|
||||
return $tablename . $field_key;
|
||||
}
|
||||
|
||||
// Find the delta and language condition values and append them to the alias.
|
||||
$condition = $query->fieldConditions[$field_key];
|
||||
$alias = $tablename;
|
||||
$has_group_conditions = FALSE;
|
||||
|
||||
foreach (array('delta', 'language') as $column) {
|
||||
if (isset($condition[$column . '_group'])) {
|
||||
$alias .= '_' . $column . '_' . $condition[$column . '_group'];
|
||||
$has_group_conditions = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the alias when it has delta/language group conditions.
|
||||
if ($has_group_conditions) {
|
||||
return $alias;
|
||||
}
|
||||
|
||||
// Return a unique alias in other cases.
|
||||
return $tablename . $field_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a column name for a field data table.
|
||||
*
|
||||
@@ -180,7 +223,17 @@ function _field_sql_storage_schema($field) {
|
||||
foreach ($field['indexes'] as $index_name => $columns) {
|
||||
$real_name = _field_sql_storage_indexname($field['field_name'], $index_name);
|
||||
foreach ($columns as $column_name) {
|
||||
$current['indexes'][$real_name][] = _field_sql_storage_columnname($field['field_name'], $column_name);
|
||||
// Indexes can be specified as either a column name or an array with
|
||||
// column name and length. Allow for either case.
|
||||
if (is_array($column_name)) {
|
||||
$current['indexes'][$real_name][] = array(
|
||||
_field_sql_storage_columnname($field['field_name'], $column_name[0]),
|
||||
$column_name[1],
|
||||
);
|
||||
}
|
||||
else {
|
||||
$current['indexes'][$real_name][] = _field_sql_storage_columnname($field['field_name'], $column_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +241,7 @@ function _field_sql_storage_schema($field) {
|
||||
foreach ($field['foreign keys'] as $specifier => $specification) {
|
||||
$real_name = _field_sql_storage_indexname($field['field_name'], $specifier);
|
||||
$current['foreign keys'][$real_name]['table'] = $specification['table'];
|
||||
foreach ($specification['columns'] as $column => $referenced) {
|
||||
foreach ($specification['columns'] as $column_name => $referenced) {
|
||||
$sql_storage_column = _field_sql_storage_columnname($field['field_name'], $column_name);
|
||||
$current['foreign keys'][$real_name]['columns'][$sql_storage_column] = $referenced;
|
||||
}
|
||||
@@ -289,7 +342,17 @@ function field_sql_storage_field_storage_update_field($field, $prior_field, $has
|
||||
$real_name = _field_sql_storage_indexname($field['field_name'], $name);
|
||||
$real_columns = array();
|
||||
foreach ($columns as $column_name) {
|
||||
$real_columns[] = _field_sql_storage_columnname($field['field_name'], $column_name);
|
||||
// Indexes can be specified as either a column name or an array with
|
||||
// column name and length. Allow for either case.
|
||||
if (is_array($column_name)) {
|
||||
$real_columns[] = array(
|
||||
_field_sql_storage_columnname($field['field_name'], $column_name[0]),
|
||||
$column_name[1],
|
||||
);
|
||||
}
|
||||
else {
|
||||
$real_columns[] = _field_sql_storage_columnname($field['field_name'], $column_name);
|
||||
}
|
||||
}
|
||||
db_add_index($table, $real_name, $real_columns);
|
||||
db_add_index($revision_table, $real_name, $real_columns);
|
||||
@@ -422,7 +485,7 @@ function field_sql_storage_field_storage_write($entity_type, $entity, $op, $fiel
|
||||
$items = (array) $entity->{$field_name}[$langcode];
|
||||
$delta_count = 0;
|
||||
foreach ($items as $delta => $item) {
|
||||
// We now know we have someting to insert.
|
||||
// We now know we have something to insert.
|
||||
$do_insert = TRUE;
|
||||
$record = array(
|
||||
'entity_type' => $entity_type,
|
||||
@@ -504,17 +567,21 @@ function field_sql_storage_field_storage_query(EntityFieldQuery $query) {
|
||||
$id_key = 'revision_id';
|
||||
}
|
||||
$table_aliases = array();
|
||||
$query_tables = NULL;
|
||||
// Add tables for the fields used.
|
||||
foreach ($query->fields as $key => $field) {
|
||||
$tablename = $tablename_function($field);
|
||||
// Every field needs a new table.
|
||||
$table_alias = $tablename . $key;
|
||||
$table_alias = _field_sql_storage_tablealias($tablename, $key, $query);
|
||||
$table_aliases[$key] = $table_alias;
|
||||
if ($key) {
|
||||
$select_query->join($tablename, $table_alias, "$table_alias.entity_type = $field_base_table.entity_type AND $table_alias.$id_key = $field_base_table.$id_key");
|
||||
if (!isset($query_tables[$table_alias])) {
|
||||
$select_query->join($tablename, $table_alias, "$table_alias.entity_type = $field_base_table.entity_type AND $table_alias.$id_key = $field_base_table.$id_key");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$select_query = db_select($tablename, $table_alias);
|
||||
// Store a reference to the list of joined tables.
|
||||
$query_tables =& $select_query->getTables();
|
||||
// Allow queries internal to the Field API to opt out of the access
|
||||
// check, for situations where the query's results should not depend on
|
||||
// the access grants for the current user.
|
||||
|
||||
@@ -126,7 +126,7 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
|
||||
$rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
|
||||
foreach ($values as $delta => $value) {
|
||||
if ($delta < $this->field['cardinality']) {
|
||||
$this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], t("Value $delta is inserted correctly"));
|
||||
$this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], format_string("Value %delta is inserted correctly", array('%delta' => $delta)));
|
||||
}
|
||||
else {
|
||||
$this->assertFalse(array_key_exists($delta, $rows), "No extraneous value gets inserted.");
|
||||
@@ -145,7 +145,7 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
|
||||
$rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
|
||||
foreach ($values as $delta => $value) {
|
||||
if ($delta < $this->field['cardinality']) {
|
||||
$this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], t("Value $delta is updated correctly"));
|
||||
$this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], format_string("Value %delta is updated correctly", array('%delta' => $delta)));
|
||||
}
|
||||
else {
|
||||
$this->assertFalse(array_key_exists($delta, $rows), "No extraneous value gets updated.");
|
||||
@@ -175,7 +175,7 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
|
||||
$rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
|
||||
foreach ($values as $delta => $value) {
|
||||
if ($delta < $this->field['cardinality']) {
|
||||
$this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], t("Update with no field_name entry leaves value $delta untouched"));
|
||||
$this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], format_string("Update with no field_name entry leaves value %delta untouched", array('%delta' => $delta)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
|
||||
$entity->{$this->field_name} = NULL;
|
||||
field_attach_update($entity_type, $entity);
|
||||
$rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
|
||||
$this->assertEqual(count($rows), 0, t("Update with an empty field_name entry empties the field."));
|
||||
$this->assertEqual(count($rows), 0, "Update with an empty field_name entry empties the field.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,7 +326,7 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Ensure that the field tables are still there.
|
||||
foreach (_field_sql_storage_schema($prior_field) as $table_name => $table_info) {
|
||||
$this->assertTrue(db_table_exists($table_name), t('Table %table exists.', array('%table' => $table_name)));
|
||||
$this->assertTrue(db_table_exists($table_name), format_string('Table %table exists.', array('%table' => $table_name)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,8 +345,8 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Verify the indexes we will create do not exist yet.
|
||||
foreach ($tables as $table) {
|
||||
$this->assertFalse(Database::getConnection()->schema()->indexExists($table, 'value'), t("No index named value exists in $table"));
|
||||
$this->assertFalse(Database::getConnection()->schema()->indexExists($table, 'value_format'), t("No index named value_format exists in $table"));
|
||||
$this->assertFalse(Database::getConnection()->schema()->indexExists($table, 'value'), format_string("No index named value exists in %table", array('%table' => $table)));
|
||||
$this->assertFalse(Database::getConnection()->schema()->indexExists($table, 'value_format'), format_string("No index named value_format exists in %table", array('%table' => $table)));
|
||||
}
|
||||
|
||||
// Add data so the table cannot be dropped.
|
||||
@@ -355,24 +355,24 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
|
||||
field_attach_insert('test_entity', $entity);
|
||||
|
||||
// Add an index
|
||||
$field = array('field_name' => $field_name, 'indexes' => array('value' => array('value')));
|
||||
$field = array('field_name' => $field_name, 'indexes' => array('value' => array(array('value', 255))));
|
||||
field_update_field($field);
|
||||
foreach ($tables as $table) {
|
||||
$this->assertTrue(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value"), t("Index on value created in $table"));
|
||||
$this->assertTrue(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value"), format_string("Index on value created in %table", array('%table' => $table)));
|
||||
}
|
||||
|
||||
// Add a different index, removing the existing custom one.
|
||||
$field = array('field_name' => $field_name, 'indexes' => array('value_format' => array('value', 'format')));
|
||||
$field = array('field_name' => $field_name, 'indexes' => array('value_format' => array(array('value', 127), array('format', 127))));
|
||||
field_update_field($field);
|
||||
foreach ($tables as $table) {
|
||||
$this->assertTrue(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value_format"), t("Index on value_format created in $table"));
|
||||
$this->assertFalse(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value"), t("Index on value removed in $table"));
|
||||
$this->assertTrue(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value_format"), format_string("Index on value_format created in %table", array('%table' => $table)));
|
||||
$this->assertFalse(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value"), format_string("Index on value removed in %table", array('%table' => $table)));
|
||||
}
|
||||
|
||||
// Verify that the tables were not dropped.
|
||||
$entity = field_test_create_stub_entity(0, 0, $instance['bundle']);
|
||||
field_attach_load('test_entity', array(0 => $entity));
|
||||
$this->assertEqual($entity->{$field_name}[LANGUAGE_NONE][0]['value'], 'field data', t("Index changes performed without dropping the tables"));
|
||||
$this->assertEqual($entity->{$field_name}[LANGUAGE_NONE][0]['value'], 'field data', "Index changes performed without dropping the tables");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -387,19 +387,19 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
|
||||
$instance = field_info_instance($this->instance['entity_type'], $this->instance['field_name'], $this->instance['bundle']);
|
||||
|
||||
// The storage details are indexed by a storage engine type.
|
||||
$this->assertTrue(array_key_exists('sql', $field['storage']['details']), t('The storage type is SQL.'));
|
||||
$this->assertTrue(array_key_exists('sql', $field['storage']['details']), 'The storage type is SQL.');
|
||||
|
||||
// The SQL details are indexed by table name.
|
||||
$details = $field['storage']['details']['sql'];
|
||||
$this->assertTrue(array_key_exists($current, $details[FIELD_LOAD_CURRENT]), t('Table name is available in the instance array.'));
|
||||
$this->assertTrue(array_key_exists($revision, $details[FIELD_LOAD_REVISION]), t('Revision table name is available in the instance array.'));
|
||||
$this->assertTrue(array_key_exists($current, $details[FIELD_LOAD_CURRENT]), 'Table name is available in the instance array.');
|
||||
$this->assertTrue(array_key_exists($revision, $details[FIELD_LOAD_REVISION]), 'Revision table name is available in the instance array.');
|
||||
|
||||
// Test current and revision storage details together because the columns
|
||||
// are the same.
|
||||
foreach ((array) $this->field['columns'] as $column_name => $attributes) {
|
||||
$storage_column_name = _field_sql_storage_columnname($this->field['field_name'], $column_name);
|
||||
$this->assertEqual($details[FIELD_LOAD_CURRENT][$current][$column_name], $storage_column_name, t('Column name %value matches the definition in %bin.', array('%value' => $column_name, '%bin' => $current)));
|
||||
$this->assertEqual($details[FIELD_LOAD_REVISION][$revision][$column_name], $storage_column_name, t('Column name %value matches the definition in %bin.', array('%value' => $column_name, '%bin' => $revision)));
|
||||
$this->assertEqual($details[FIELD_LOAD_CURRENT][$current][$column_name], $storage_column_name, format_string('Column name %value matches the definition in %bin.', array('%value' => $column_name, '%bin' => $current)));
|
||||
$this->assertEqual($details[FIELD_LOAD_REVISION][$revision][$column_name], $storage_column_name, format_string('Column name %value matches the definition in %bin.', array('%value' => $column_name, '%bin' => $revision)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,21 +407,180 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
|
||||
* Test foreign key support.
|
||||
*/
|
||||
function testFieldSqlStorageForeignKeys() {
|
||||
// Create a decimal field.
|
||||
// Create a 'shape' field, with a configurable foreign key (see
|
||||
// field_test_field_schema()).
|
||||
$field_name = 'testfield';
|
||||
$field = array('field_name' => $field_name, 'type' => 'text');
|
||||
$field = field_create_field($field);
|
||||
// Retrieve the field and instance with field_info and verify the foreign
|
||||
// keys are in place.
|
||||
$foreign_key_name = 'shape';
|
||||
$field = array('field_name' => $field_name, 'type' => 'shape', 'settings' => array('foreign_key_name' => $foreign_key_name));
|
||||
field_create_field($field);
|
||||
|
||||
// Retrieve the field definition and check that the foreign key is in place.
|
||||
$field = field_info_field($field_name);
|
||||
$this->assertEqual($field['foreign keys']['format']['table'], 'filter_format', t('Foreign key table name preserved through CRUD'));
|
||||
$this->assertEqual($field['foreign keys']['format']['columns']['format'], 'format', t('Foreign key column name preserved through CRUD'));
|
||||
$this->assertEqual($field['foreign keys'][$foreign_key_name]['table'], $foreign_key_name, 'Foreign key table name preserved through CRUD');
|
||||
$this->assertEqual($field['foreign keys'][$foreign_key_name]['columns'][$foreign_key_name], 'id', 'Foreign key column name preserved through CRUD');
|
||||
|
||||
// Update the field settings, it should update the foreign key definition
|
||||
// too.
|
||||
$foreign_key_name = 'color';
|
||||
$field['settings']['foreign_key_name'] = $foreign_key_name;
|
||||
field_update_field($field);
|
||||
|
||||
// Retrieve the field definition and check that the foreign key is in place.
|
||||
$field = field_info_field($field_name);
|
||||
$this->assertEqual($field['foreign keys'][$foreign_key_name]['table'], $foreign_key_name, 'Foreign key table name modified after update');
|
||||
$this->assertEqual($field['foreign keys'][$foreign_key_name]['columns'][$foreign_key_name], 'id', 'Foreign key column name modified after update');
|
||||
|
||||
// Now grab the SQL schema and verify that too.
|
||||
$schema = drupal_get_schema(_field_sql_storage_tablename($field));
|
||||
$this->assertEqual(count($schema['foreign keys']), 1, t("There is 1 foreign key in the schema"));
|
||||
$schema = drupal_get_schema(_field_sql_storage_tablename($field), TRUE);
|
||||
$this->assertEqual(count($schema['foreign keys']), 1, 'There is 1 foreign key in the schema');
|
||||
$foreign_key = reset($schema['foreign keys']);
|
||||
$filter_column = _field_sql_storage_columnname($field['field_name'], 'format');
|
||||
$this->assertEqual($foreign_key['table'], 'filter_format', t('Foreign key table name preserved in the schema'));
|
||||
$this->assertEqual($foreign_key['columns'][$filter_column], 'format', t('Foreign key column name preserved in the schema'));
|
||||
$foreign_key_column = _field_sql_storage_columnname($field['field_name'], $foreign_key_name);
|
||||
$this->assertEqual($foreign_key['table'], $foreign_key_name, 'Foreign key table name preserved in the schema');
|
||||
$this->assertEqual($foreign_key['columns'][$foreign_key_column], 'id', 'Foreign key column name preserved in the schema');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test handling multiple conditions on one column of a field.
|
||||
*
|
||||
* Tests both the result and the complexity of the query.
|
||||
*/
|
||||
function testFieldSqlStorageMultipleConditionsSameColumn() {
|
||||
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||
$entity->{$this->field_name}[LANGUAGE_NONE][0] = array('value' => 1);
|
||||
field_test_entity_save($entity);
|
||||
|
||||
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||
$entity->{$this->field_name}[LANGUAGE_NONE][0] = array('value' => 2);
|
||||
field_test_entity_save($entity);
|
||||
|
||||
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||
$entity->{$this->field_name}[LANGUAGE_NONE][0] = array('value' => 3);
|
||||
field_test_entity_save($entity);
|
||||
|
||||
$query = new EntityFieldQuery();
|
||||
// This tag causes field_test_query_store_global_test_query_alter() to be
|
||||
// invoked so that the query can be tested.
|
||||
$query->addTag('store_global_test_query');
|
||||
$query->entityCondition('entity_type', 'test_entity');
|
||||
$query->entityCondition('bundle', 'test_bundle');
|
||||
$query->fieldCondition($this->field_name, 'value', 1, '<>', 0, LANGUAGE_NONE);
|
||||
$query->fieldCondition($this->field_name, 'value', 2, '<>', 0, LANGUAGE_NONE);
|
||||
$result = field_sql_storage_field_storage_query($query);
|
||||
|
||||
// Test the results.
|
||||
$this->assertEqual(1, count($result), format_string('One result should be returned, got @count', array('@count' => count($result))));
|
||||
|
||||
// Test the complexity of the query.
|
||||
$query = $GLOBALS['test_query'];
|
||||
$this->assertNotNull($query, 'Precondition: the query should be available');
|
||||
$tables = $query->getTables();
|
||||
$this->assertEqual(1, count($tables), 'The query contains just one table.');
|
||||
|
||||
// Clean up.
|
||||
unset($GLOBALS['test_query']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test handling multiple conditions on multiple columns of one field.
|
||||
*
|
||||
* Tests both the result and the complexity of the query.
|
||||
*/
|
||||
function testFieldSqlStorageMultipleConditionsDifferentColumns() {
|
||||
// Create the multi-column shape field
|
||||
$field_name = strtolower($this->randomName());
|
||||
$field = array('field_name' => $field_name, 'type' => 'shape', 'cardinality' => 4);
|
||||
$field = field_create_field($field);
|
||||
$instance = array(
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'test_entity',
|
||||
'bundle' => 'test_bundle'
|
||||
);
|
||||
$instance = field_create_instance($instance);
|
||||
|
||||
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||
$entity->{$field_name}[LANGUAGE_NONE][0] = array('shape' => 'A', 'color' => 'X');
|
||||
field_test_entity_save($entity);
|
||||
|
||||
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||
$entity->{$field_name}[LANGUAGE_NONE][0] = array('shape' => 'B', 'color' => 'X');
|
||||
field_test_entity_save($entity);
|
||||
|
||||
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||
$entity->{$field_name}[LANGUAGE_NONE][0] = array('shape' => 'A', 'color' => 'Y');
|
||||
field_test_entity_save($entity);
|
||||
|
||||
$query = new EntityFieldQuery();
|
||||
// This tag causes field_test_query_store_global_test_query_alter() to be
|
||||
// invoked so that the query can be tested.
|
||||
$query->addTag('store_global_test_query');
|
||||
$query->entityCondition('entity_type', 'test_entity');
|
||||
$query->entityCondition('bundle', 'test_bundle');
|
||||
$query->fieldCondition($field_name, 'shape', 'B', '=', 'something', LANGUAGE_NONE);
|
||||
$query->fieldCondition($field_name, 'color', 'X', '=', 'something', LANGUAGE_NONE);
|
||||
$result = field_sql_storage_field_storage_query($query);
|
||||
|
||||
// Test the results.
|
||||
$this->assertEqual(1, count($result), format_string('One result should be returned, got @count', array('@count' => count($result))));
|
||||
|
||||
// Test the complexity of the query.
|
||||
$query = $GLOBALS['test_query'];
|
||||
$this->assertNotNull($query, 'Precondition: the query should be available');
|
||||
$tables = $query->getTables();
|
||||
$this->assertEqual(1, count($tables), 'The query contains just one table.');
|
||||
|
||||
// Clean up.
|
||||
unset($GLOBALS['test_query']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test handling multiple conditions on multiple columns of one field for multiple languages.
|
||||
*
|
||||
* Tests both the result and the complexity of the query.
|
||||
*/
|
||||
function testFieldSqlStorageMultipleConditionsDifferentColumnsMultipleLanguages() {
|
||||
field_test_entity_info_translatable('test_entity', TRUE);
|
||||
|
||||
// Create the multi-column shape field
|
||||
$field_name = strtolower($this->randomName());
|
||||
$field = array('field_name' => $field_name, 'type' => 'shape', 'cardinality' => 4, 'translatable' => TRUE);
|
||||
$field = field_create_field($field);
|
||||
$instance = array(
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'test_entity',
|
||||
'bundle' => 'test_bundle',
|
||||
'settings' => array(
|
||||
// Prevent warning from field_test_field_load().
|
||||
'test_hook_field_load' => FALSE,
|
||||
),
|
||||
);
|
||||
$instance = field_create_instance($instance);
|
||||
|
||||
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||
$entity->{$field_name}[LANGUAGE_NONE][0] = array('shape' => 'A', 'color' => 'X');
|
||||
$entity->{$field_name}['en'][0] = array('shape' => 'B', 'color' => 'Y');
|
||||
field_test_entity_save($entity);
|
||||
$entity = field_test_entity_test_load($entity->ftid);
|
||||
|
||||
$query = new EntityFieldQuery();
|
||||
// This tag causes field_test_query_store_global_test_query_alter() to be
|
||||
// invoked so that the query can be tested.
|
||||
$query->addTag('store_global_test_query');
|
||||
$query->entityCondition('entity_type', 'test_entity');
|
||||
$query->entityCondition('bundle', 'test_bundle');
|
||||
$query->fieldCondition($field_name, 'color', 'X', '=', NULL, LANGUAGE_NONE);
|
||||
$query->fieldCondition($field_name, 'shape', 'B', '=', NULL, 'en');
|
||||
$result = field_sql_storage_field_storage_query($query);
|
||||
|
||||
// Test the results.
|
||||
$this->assertEqual(1, count($result), format_string('One result should be returned, got @count', array('@count' => count($result))));
|
||||
|
||||
// Test the complexity of the query.
|
||||
$query = $GLOBALS['test_query'];
|
||||
$this->assertNotNull($query, 'Precondition: the query should be available');
|
||||
$tables = $query->getTables();
|
||||
$this->assertEqual(2, count($tables), 'The query contains two tables.');
|
||||
|
||||
// Clean up.
|
||||
unset($GLOBALS['test_query']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@ dependencies[] = field
|
||||
dependencies[] = options
|
||||
files[] = tests/list.test
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -61,7 +61,7 @@ function list_update_7001() {
|
||||
|
||||
// Additionally, float keys need to be disambiguated ('.5' is '0.5').
|
||||
if ($field['type'] == 'list_number' && !empty($allowed_values)) {
|
||||
$keys = array_map(create_function('$a', 'return (string) (float) $a;'), array_keys($allowed_values));
|
||||
$keys = array_map('_list_update_7001_float_string_cast', array_keys($allowed_values));
|
||||
$allowed_values = array_combine($keys, array_values($allowed_values));
|
||||
}
|
||||
|
||||
@@ -88,6 +88,13 @@ function list_update_7001() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper callback function to cast the array element.
|
||||
*/
|
||||
function _list_update_7001_float_string_cast($element) {
|
||||
return (string) (float) $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for list_update_7001: extract allowed values from a string.
|
||||
*
|
||||
|
||||
@@ -51,9 +51,9 @@ class ListFieldTestCase extends FieldTestCase {
|
||||
// All three options appear.
|
||||
$entity = field_test_create_stub_entity();
|
||||
$form = drupal_get_form('field_test_entity_form', $entity);
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][1]), t('Option 1 exists'));
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][2]), t('Option 2 exists'));
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][3]), t('Option 3 exists'));
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][1]), 'Option 1 exists');
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][2]), 'Option 2 exists');
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][3]), 'Option 3 exists');
|
||||
|
||||
// Use one of the values in an actual entity, and check that this value
|
||||
// cannot be removed from the list.
|
||||
@@ -77,19 +77,19 @@ class ListFieldTestCase extends FieldTestCase {
|
||||
field_update_field($this->field);
|
||||
$entity = field_test_create_stub_entity();
|
||||
$form = drupal_get_form('field_test_entity_form', $entity);
|
||||
$this->assertTrue(empty($form[$this->field_name][$langcode][1]), t('Option 1 does not exist'));
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][2]), t('Option 2 exists'));
|
||||
$this->assertTrue(empty($form[$this->field_name][$langcode][3]), t('Option 3 does not exist'));
|
||||
$this->assertTrue(empty($form[$this->field_name][$langcode][1]), 'Option 1 does not exist');
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][2]), 'Option 2 exists');
|
||||
$this->assertTrue(empty($form[$this->field_name][$langcode][3]), 'Option 3 does not exist');
|
||||
|
||||
// Completely new options appear.
|
||||
$this->field['settings']['allowed_values'] = array(10 => 'Update', 20 => 'Twenty');
|
||||
field_update_field($this->field);
|
||||
$form = drupal_get_form('field_test_entity_form', $entity);
|
||||
$this->assertTrue(empty($form[$this->field_name][$langcode][1]), t('Option 1 does not exist'));
|
||||
$this->assertTrue(empty($form[$this->field_name][$langcode][2]), t('Option 2 does not exist'));
|
||||
$this->assertTrue(empty($form[$this->field_name][$langcode][3]), t('Option 3 does not exist'));
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][10]), t('Option 10 exists'));
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][20]), t('Option 20 exists'));
|
||||
$this->assertTrue(empty($form[$this->field_name][$langcode][1]), 'Option 1 does not exist');
|
||||
$this->assertTrue(empty($form[$this->field_name][$langcode][2]), 'Option 2 does not exist');
|
||||
$this->assertTrue(empty($form[$this->field_name][$langcode][3]), 'Option 3 does not exist');
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][10]), 'Option 10 exists');
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][20]), 'Option 20 exists');
|
||||
|
||||
// Options are reset when a new field with the same name is created.
|
||||
field_delete_field($this->field_name);
|
||||
@@ -107,9 +107,9 @@ class ListFieldTestCase extends FieldTestCase {
|
||||
$this->instance = field_create_instance($this->instance);
|
||||
$entity = field_test_create_stub_entity();
|
||||
$form = drupal_get_form('field_test_entity_form', $entity);
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][1]), t('Option 1 exists'));
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][2]), t('Option 2 exists'));
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][3]), t('Option 3 exists'));
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][1]), 'Option 1 exists');
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][2]), 'Option 2 exists');
|
||||
$this->assertTrue(!empty($form[$this->field_name][$langcode][3]), 'Option 3 exists');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ class ListFieldUITestCase extends FieldTestCase {
|
||||
parent::setUp('field_test', 'field_ui');
|
||||
|
||||
// Create test user.
|
||||
$admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy'));
|
||||
$admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy', 'administer fields'));
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// Create content type, with underscores.
|
||||
@@ -233,20 +233,20 @@ class ListFieldUITestCase extends FieldTestCase {
|
||||
// Flat list of textual values.
|
||||
$string = "Zero\nOne";
|
||||
$array = array('0' => 'Zero', '1' => 'One');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Unkeyed lists are accepted.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.');
|
||||
// Explicit integer keys.
|
||||
$string = "0|Zero\n2|Two";
|
||||
$array = array('0' => 'Zero', '2' => 'Two');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Integer keys are accepted.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Integer keys are accepted.');
|
||||
// Check that values can be added and removed.
|
||||
$string = "0|Zero\n1|One";
|
||||
$array = array('0' => 'Zero', '1' => 'One');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values can be added and removed.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.');
|
||||
// Non-integer keys.
|
||||
$this->assertAllowedValuesInput("1.1|One", 'keys must be integers', t('Non integer keys are rejected.'));
|
||||
$this->assertAllowedValuesInput("abc|abc", 'keys must be integers', t('Non integer keys are rejected.'));
|
||||
$this->assertAllowedValuesInput("1.1|One", 'keys must be integers', 'Non integer keys are rejected.');
|
||||
$this->assertAllowedValuesInput("abc|abc", 'keys must be integers', 'Non integer keys are rejected.');
|
||||
// Mixed list of keyed and unkeyed values.
|
||||
$this->assertAllowedValuesInput("Zero\n1|One", 'invalid input', t('Mixed lists are rejected.'));
|
||||
$this->assertAllowedValuesInput("Zero\n1|One", 'invalid input', 'Mixed lists are rejected.');
|
||||
|
||||
// Create a node with actual data for the field.
|
||||
$settings = array(
|
||||
@@ -256,22 +256,22 @@ class ListFieldUITestCase extends FieldTestCase {
|
||||
$node = $this->drupalCreateNode($settings);
|
||||
|
||||
// Check that a flat list of values is rejected once the field has data.
|
||||
$this->assertAllowedValuesInput( "Zero\nOne", 'invalid input', t('Unkeyed lists are rejected once the field has data.'));
|
||||
$this->assertAllowedValuesInput( "Zero\nOne", 'invalid input', 'Unkeyed lists are rejected once the field has data.');
|
||||
|
||||
// Check that values can be added but values in use cannot be removed.
|
||||
$string = "0|Zero\n1|One\n2|Two";
|
||||
$array = array('0' => 'Zero', '1' => 'One', '2' => 'Two');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values can be added.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values can be added.');
|
||||
$string = "0|Zero\n1|One";
|
||||
$array = array('0' => 'Zero', '1' => 'One');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values not in use can be removed.'));
|
||||
$this->assertAllowedValuesInput("0|Zero", 'some values are being removed while currently in use', t('Values in use cannot be removed.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
|
||||
$this->assertAllowedValuesInput("0|Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.');
|
||||
|
||||
// Delete the node, remove the value.
|
||||
node_delete($node->nid);
|
||||
$string = "0|Zero";
|
||||
$array = array('0' => 'Zero');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values not in use can be removed.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -284,19 +284,19 @@ class ListFieldUITestCase extends FieldTestCase {
|
||||
// Flat list of textual values.
|
||||
$string = "Zero\nOne";
|
||||
$array = array('0' => 'Zero', '1' => 'One');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Unkeyed lists are accepted.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.');
|
||||
// Explicit numeric keys.
|
||||
$string = "0|Zero\n.5|Point five";
|
||||
$array = array('0' => 'Zero', '0.5' => 'Point five');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Integer keys are accepted.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Integer keys are accepted.');
|
||||
// Check that values can be added and removed.
|
||||
$string = "0|Zero\n.5|Point five\n1.0|One";
|
||||
$array = array('0' => 'Zero', '0.5' => 'Point five', '1' => 'One');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values can be added and removed.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.');
|
||||
// Non-numeric keys.
|
||||
$this->assertAllowedValuesInput("abc|abc\n", 'each key must be a valid integer or decimal', t('Non numeric keys are rejected.'));
|
||||
$this->assertAllowedValuesInput("abc|abc\n", 'each key must be a valid integer or decimal', 'Non numeric keys are rejected.');
|
||||
// Mixed list of keyed and unkeyed values.
|
||||
$this->assertAllowedValuesInput("Zero\n1|One\n", 'invalid input', t('Mixed lists are rejected.'));
|
||||
$this->assertAllowedValuesInput("Zero\n1|One\n", 'invalid input', 'Mixed lists are rejected.');
|
||||
|
||||
// Create a node with actual data for the field.
|
||||
$settings = array(
|
||||
@@ -306,22 +306,22 @@ class ListFieldUITestCase extends FieldTestCase {
|
||||
$node = $this->drupalCreateNode($settings);
|
||||
|
||||
// Check that a flat list of values is rejected once the field has data.
|
||||
$this->assertAllowedValuesInput("Zero\nOne", 'invalid input', t('Unkeyed lists are rejected once the field has data.'));
|
||||
$this->assertAllowedValuesInput("Zero\nOne", 'invalid input', 'Unkeyed lists are rejected once the field has data.');
|
||||
|
||||
// Check that values can be added but values in use cannot be removed.
|
||||
$string = "0|Zero\n.5|Point five\n2|Two";
|
||||
$array = array('0' => 'Zero', '0.5' => 'Point five', '2' => 'Two');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values can be added.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values can be added.');
|
||||
$string = "0|Zero\n.5|Point five";
|
||||
$array = array('0' => 'Zero', '0.5' => 'Point five');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values not in use can be removed.'));
|
||||
$this->assertAllowedValuesInput("0|Zero", 'some values are being removed while currently in use', t('Values in use cannot be removed.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
|
||||
$this->assertAllowedValuesInput("0|Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.');
|
||||
|
||||
// Delete the node, remove the value.
|
||||
node_delete($node->nid);
|
||||
$string = "0|Zero";
|
||||
$array = array('0' => 'Zero');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values not in use can be removed.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,21 +334,21 @@ class ListFieldUITestCase extends FieldTestCase {
|
||||
// Flat list of textual values.
|
||||
$string = "Zero\nOne";
|
||||
$array = array('Zero' => 'Zero', 'One' => 'One');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Unkeyed lists are accepted.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.');
|
||||
// Explicit keys.
|
||||
$string = "zero|Zero\none|One";
|
||||
$array = array('zero' => 'Zero', 'one' => 'One');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Explicit keys are accepted.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Explicit keys are accepted.');
|
||||
// Check that values can be added and removed.
|
||||
$string = "zero|Zero\ntwo|Two";
|
||||
$array = array('zero' => 'Zero', 'two' => 'Two');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values can be added and removed.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.');
|
||||
// Mixed list of keyed and unkeyed values.
|
||||
$string = "zero|Zero\nOne\n";
|
||||
$array = array('zero' => 'Zero', 'One' => 'One');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Mixed lists are accepted.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Mixed lists are accepted.');
|
||||
// Overly long keys.
|
||||
$this->assertAllowedValuesInput("zero|Zero\n" . $this->randomName(256) . "|One", 'each key must be a string at most 255 characters long', t('Overly long keys are rejected.'));
|
||||
$this->assertAllowedValuesInput("zero|Zero\n" . $this->randomName(256) . "|One", 'each key must be a string at most 255 characters long', 'Overly long keys are rejected.');
|
||||
|
||||
// Create a node with actual data for the field.
|
||||
$settings = array(
|
||||
@@ -361,22 +361,22 @@ class ListFieldUITestCase extends FieldTestCase {
|
||||
// data.
|
||||
$string = "Zero\nOne";
|
||||
$array = array('Zero' => 'Zero', 'One' => 'One');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Unkeyed lists are still accepted once the field has data.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are still accepted once the field has data.');
|
||||
|
||||
// Check that values can be added but values in use cannot be removed.
|
||||
$string = "Zero\nOne\nTwo";
|
||||
$array = array('Zero' => 'Zero', 'One' => 'One', 'Two' => 'Two');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values can be added.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values can be added.');
|
||||
$string = "Zero\nOne";
|
||||
$array = array('Zero' => 'Zero', 'One' => 'One');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values not in use can be removed.'));
|
||||
$this->assertAllowedValuesInput("Zero", 'some values are being removed while currently in use', t('Values in use cannot be removed.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
|
||||
$this->assertAllowedValuesInput("Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.');
|
||||
|
||||
// Delete the node, remove the value.
|
||||
node_delete($node->nid);
|
||||
$string = "Zero";
|
||||
$array = array('Zero' => 'Zero');
|
||||
$this->assertAllowedValuesInput($string, $array, t('Values not in use can be removed.'));
|
||||
$this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,15 +395,15 @@ class ListFieldUITestCase extends FieldTestCase {
|
||||
'off' => $off,
|
||||
);
|
||||
$this->drupalPost($this->admin_path, $edit, t('Save settings'));
|
||||
$this->assertText("Saved field_list_boolean configuration.", t("The 'On' and 'Off' form fields work for boolean fields."));
|
||||
$this->assertText("Saved field_list_boolean configuration.", "The 'On' and 'Off' form fields work for boolean fields.");
|
||||
// Test the allowed_values on the field settings form.
|
||||
$this->drupalGet($this->admin_path);
|
||||
$this->assertFieldByName('on', $on, t("The 'On' value is stored correctly."));
|
||||
$this->assertFieldByName('off', $off, t("The 'Off' value is stored correctly."));
|
||||
$this->assertFieldByName('on', $on, "The 'On' value is stored correctly.");
|
||||
$this->assertFieldByName('off', $off, "The 'Off' value is stored correctly.");
|
||||
$field = field_info_field($this->field_name);
|
||||
$this->assertEqual($field['settings']['allowed_values'], $allowed_values, t('The allowed value is correct'));
|
||||
$this->assertFalse(isset($field['settings']['on']), t('The on value is not saved into settings'));
|
||||
$this->assertFalse(isset($field['settings']['off']), t('The off value is not saved into settings'));
|
||||
$this->assertEqual($field['settings']['allowed_values'], $allowed_values, 'The allowed value is correct');
|
||||
$this->assertFalse(isset($field['settings']['on']), 'The on value is not saved into settings');
|
||||
$this->assertFalse(isset($field['settings']['off']), 'The off value is not saved into settings');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,8 +5,7 @@ package = Testing
|
||||
version = VERSION
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -6,8 +6,7 @@ core = 7.x
|
||||
dependencies[] = field
|
||||
files[] = number.test
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -164,6 +164,15 @@ function number_field_presave($entity_type, $entity, $field, $instance, $langcod
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($field['type'] == 'number_float') {
|
||||
// Remove the decimal point from float values with decimal
|
||||
// point but no decimal numbers.
|
||||
foreach ($items as $delta => $item) {
|
||||
if (isset($item['value'])) {
|
||||
$items[$delta]['value'] = floatval($item['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,7 +197,7 @@ function number_field_formatter_info() {
|
||||
'label' => t('Default'),
|
||||
'field types' => array('number_integer'),
|
||||
'settings' => array(
|
||||
'thousand_separator' => ' ',
|
||||
'thousand_separator' => '',
|
||||
// The 'decimal_separator' and 'scale' settings are not configurable
|
||||
// through the UI, and will therefore keep their default values. They
|
||||
// are only present so that the 'number_integer' and 'number_decimal'
|
||||
@@ -202,7 +211,7 @@ function number_field_formatter_info() {
|
||||
'label' => t('Default'),
|
||||
'field types' => array('number_decimal', 'number_float'),
|
||||
'settings' => array(
|
||||
'thousand_separator' => ' ',
|
||||
'thousand_separator' => '',
|
||||
'decimal_separator' => '.',
|
||||
'scale' => 2,
|
||||
'prefix_suffix' => TRUE,
|
||||
@@ -222,6 +231,8 @@ function number_field_formatter_settings_form($field, $instance, $view_mode, $fo
|
||||
$display = $instance['display'][$view_mode];
|
||||
$settings = $display['settings'];
|
||||
|
||||
$element = array();
|
||||
|
||||
if ($display['type'] == 'number_decimal' || $display['type'] == 'number_integer') {
|
||||
$options = array(
|
||||
'' => t('<none>'),
|
||||
|
||||
@@ -23,7 +23,7 @@ class NumberFieldTestCase extends DrupalWebTestCase {
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('field_test');
|
||||
$this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content', 'administer content types'));
|
||||
$this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content', 'administer content types', 'administer fields'));
|
||||
$this->drupalLogin($this->web_user);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ class NumberFieldTestCase extends DrupalWebTestCase {
|
||||
// Display creation form.
|
||||
$this->drupalGet('test-entity/add/test-bundle');
|
||||
$langcode = LANGUAGE_NONE;
|
||||
$this->assertFieldByName("{$this->field['field_name']}[$langcode][0][value]", '', t('Widget is displayed'));
|
||||
$this->assertFieldByName("{$this->field['field_name']}[$langcode][0][value]", '', 'Widget is displayed');
|
||||
|
||||
// Submit a signed decimal value within the allowed precision and scale.
|
||||
$value = '-1234.5678';
|
||||
@@ -68,8 +68,8 @@ class NumberFieldTestCase extends DrupalWebTestCase {
|
||||
$this->drupalPost(NULL, $edit, t('Save'));
|
||||
preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
|
||||
$id = $match[1];
|
||||
$this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), t('Entity was created'));
|
||||
$this->assertRaw(round($value, 2), t('Value is displayed.'));
|
||||
$this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created');
|
||||
$this->assertRaw($value, 'Value is displayed.');
|
||||
|
||||
// Try to create entries with more than one decimal separator; assert fail.
|
||||
$wrong_entries = array(
|
||||
@@ -89,7 +89,7 @@ class NumberFieldTestCase extends DrupalWebTestCase {
|
||||
$this->assertText(
|
||||
t('There should only be one decimal separator (@separator)',
|
||||
array('@separator' => $this->field['settings']['decimal_separator'])),
|
||||
t('Correctly failed to save decimal value with more than one decimal point.')
|
||||
'Correctly failed to save decimal value with more than one decimal point.'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -152,4 +152,50 @@ class NumberFieldTestCase extends DrupalWebTestCase {
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Save'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test number_float field.
|
||||
*/
|
||||
function testNumberFloatField() {
|
||||
$this->field = array(
|
||||
'field_name' => drupal_strtolower($this->randomName()),
|
||||
'type' => 'number_float',
|
||||
'settings' => array(
|
||||
'precision' => 8, 'scale' => 4, 'decimal_separator' => '.',
|
||||
)
|
||||
);
|
||||
field_create_field($this->field);
|
||||
$this->instance = array(
|
||||
'field_name' => $this->field['field_name'],
|
||||
'entity_type' => 'test_entity',
|
||||
'bundle' => 'test_bundle',
|
||||
'widget' => array(
|
||||
'type' => 'number',
|
||||
),
|
||||
'display' => array(
|
||||
'default' => array(
|
||||
'type' => 'number_decimal',
|
||||
),
|
||||
),
|
||||
);
|
||||
field_create_instance($this->instance);
|
||||
|
||||
$langcode = LANGUAGE_NONE;
|
||||
$value = array(
|
||||
'9.' => '9',
|
||||
'.' => '0',
|
||||
'123.55' => '123.55',
|
||||
'.55' => '0.55',
|
||||
'-0.55' => '-0.55',
|
||||
);
|
||||
foreach($value as $key => $value) {
|
||||
$edit = array(
|
||||
"{$this->field['field_name']}[$langcode][0][value]" => $key,
|
||||
);
|
||||
$this->drupalPost('test-entity/add/test-bundle', $edit, t('Save'));
|
||||
$this->assertNoText("PDOException");
|
||||
$this->assertRaw($value, 'Correct value is displayed.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@ core = 7.x
|
||||
dependencies[] = field
|
||||
files[] = options.test
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -185,6 +185,7 @@ function _options_properties($type, $multiple, $required, $has_value) {
|
||||
$base = array(
|
||||
'filter_xss' => FALSE,
|
||||
'strip_tags' => FALSE,
|
||||
'strip_tags_and_unescape' => FALSE,
|
||||
'empty_option' => FALSE,
|
||||
'optgroups' => FALSE,
|
||||
);
|
||||
@@ -195,7 +196,7 @@ function _options_properties($type, $multiple, $required, $has_value) {
|
||||
case 'select':
|
||||
$properties = array(
|
||||
// Select boxes do not support any HTML tag.
|
||||
'strip_tags' => TRUE,
|
||||
'strip_tags_and_unescape' => TRUE,
|
||||
'optgroups' => TRUE,
|
||||
);
|
||||
if ($multiple) {
|
||||
@@ -271,9 +272,16 @@ function _options_prepare_options(&$options, $properties) {
|
||||
_options_prepare_options($options[$value], $properties);
|
||||
}
|
||||
else {
|
||||
// The 'strip_tags' option is deprecated. Use 'strip_tags_and_unescape'
|
||||
// when plain text is required (and where the output will be run through
|
||||
// check_plain() before being inserted back into HTML) or 'filter_xss'
|
||||
// when HTML is required.
|
||||
if ($properties['strip_tags']) {
|
||||
$options[$value] = strip_tags($label);
|
||||
}
|
||||
if ($properties['strip_tags_and_unescape']) {
|
||||
$options[$value] = decode_entities(strip_tags($label));
|
||||
}
|
||||
if ($properties['filter_xss']) {
|
||||
$options[$value] = field_filter_xss($label);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @file
|
||||
* Tests for options.module.
|
||||
*/
|
||||
|
||||
@@ -23,8 +23,15 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
'type' => 'list_integer',
|
||||
'cardinality' => 1,
|
||||
'settings' => array(
|
||||
// Make sure that 0 works as an option.
|
||||
'allowed_values' => array(0 => 'Zero', 1 => 'One', 2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>'),
|
||||
'allowed_values' => array(
|
||||
// Make sure that 0 works as an option.
|
||||
0 => 'Zero',
|
||||
1 => 'One',
|
||||
// Make sure that option text is properly sanitized.
|
||||
2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>',
|
||||
// Make sure that HTML entities in option text are not double-encoded.
|
||||
3 => 'Some HTML encoded markup with < & >',
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->card_1 = field_create_field($this->card_1);
|
||||
@@ -35,8 +42,13 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
'type' => 'list_integer',
|
||||
'cardinality' => 2,
|
||||
'settings' => array(
|
||||
// Make sure that 0 works as an option.
|
||||
'allowed_values' => array(0 => 'Zero', 1 => 'One', 2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>'),
|
||||
'allowed_values' => array(
|
||||
// Make sure that 0 works as an option.
|
||||
0 => 'Zero',
|
||||
1 => 'One',
|
||||
// Make sure that option text is properly sanitized.
|
||||
2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>',
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->card_2 = field_create_field($this->card_2);
|
||||
@@ -47,14 +59,18 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
'type' => 'list_boolean',
|
||||
'cardinality' => 1,
|
||||
'settings' => array(
|
||||
// Make sure that 0 works as a 'on' value'.
|
||||
'allowed_values' => array(1 => 'Zero', 0 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>'),
|
||||
'allowed_values' => array(
|
||||
// Make sure that 1 works as a 'on' value'.
|
||||
1 => 'Zero',
|
||||
// Make sure that option text is properly sanitized.
|
||||
0 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>',
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->bool = field_create_field($this->bool);
|
||||
|
||||
// Create a web user.
|
||||
$this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content'));
|
||||
$this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content', 'administer fields'));
|
||||
$this->drupalLogin($this->web_user);
|
||||
}
|
||||
|
||||
@@ -85,7 +101,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
$this->assertNoFieldChecked("edit-card-1-$langcode-0");
|
||||
$this->assertNoFieldChecked("edit-card-1-$langcode-1");
|
||||
$this->assertNoFieldChecked("edit-card-1-$langcode-2");
|
||||
$this->assertRaw('Some dangerous & unescaped <strong>markup</strong>', t('Option text was properly filtered.'));
|
||||
$this->assertRaw('Some dangerous & unescaped <strong>markup</strong>', 'Option text was properly filtered.');
|
||||
|
||||
// Select first option.
|
||||
$edit = array("card_1[$langcode]" => 0);
|
||||
@@ -139,7 +155,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
$this->assertNoFieldChecked("edit-card-2-$langcode-0");
|
||||
$this->assertNoFieldChecked("edit-card-2-$langcode-1");
|
||||
$this->assertNoFieldChecked("edit-card-2-$langcode-2");
|
||||
$this->assertRaw('Some dangerous & unescaped <strong>markup</strong>', t('Option text was properly filtered.'));
|
||||
$this->assertRaw('Some dangerous & unescaped <strong>markup</strong>', 'Option text was properly filtered.');
|
||||
|
||||
// Submit form: select first and third options.
|
||||
$edit = array(
|
||||
@@ -178,7 +194,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
"card_2[$langcode][2]" => TRUE,
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Save'));
|
||||
$this->assertText('this field cannot hold more than 2 values', t('Validation error was displayed.'));
|
||||
$this->assertText('this field cannot hold more than 2 values', 'Validation error was displayed.');
|
||||
|
||||
// Submit form: uncheck all options.
|
||||
$edit = array(
|
||||
@@ -225,19 +241,20 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
// Display form.
|
||||
$this->drupalGet('test-entity/manage/' . $entity->ftid . '/edit');
|
||||
// A required field without any value has a "none" option.
|
||||
$this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', array(':id' => 'edit-card-1-' . $langcode, ':label' => t('- Select a value -'))), t('A required select list has a "Select a value" choice.'));
|
||||
$this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', array(':id' => 'edit-card-1-' . $langcode, ':label' => t('- Select a value -'))), 'A required select list has a "Select a value" choice.');
|
||||
|
||||
// With no field data, nothing is selected.
|
||||
$this->assertNoOptionSelected("edit-card-1-$langcode", '_none');
|
||||
$this->assertNoOptionSelected("edit-card-1-$langcode", 0);
|
||||
$this->assertNoOptionSelected("edit-card-1-$langcode", 1);
|
||||
$this->assertNoOptionSelected("edit-card-1-$langcode", 2);
|
||||
$this->assertRaw('Some dangerous & unescaped markup', t('Option text was properly filtered.'));
|
||||
$this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.');
|
||||
$this->assertRaw('Some HTML encoded markup with < & >', 'HTML entities in option text were properly handled and not double-encoded');
|
||||
|
||||
// Submit form: select invalid 'none' option.
|
||||
$edit = array("card_1[$langcode]" => '_none');
|
||||
$this->drupalPost(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('!title field is required.', array('!title' => $instance['field_name'])), t('Cannot save a required field when selecting "none" from the select list.'));
|
||||
$this->assertRaw(t('!title field is required.', array('!title' => $instance['field_name'])), 'Cannot save a required field when selecting "none" from the select list.');
|
||||
|
||||
// Submit form: select first option.
|
||||
$edit = array("card_1[$langcode]" => 0);
|
||||
@@ -247,7 +264,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
// Display form: check that the right options are selected.
|
||||
$this->drupalGet('test-entity/manage/' . $entity->ftid . '/edit');
|
||||
// A required field with a value has no 'none' option.
|
||||
$this->assertFalse($this->xpath('//select[@id=:id]//option[@value="_none"]', array(':id' => 'edit-card-1-' . $langcode)), t('A required select list with an actual value has no "none" choice.'));
|
||||
$this->assertFalse($this->xpath('//select[@id=:id]//option[@value="_none"]', array(':id' => 'edit-card-1-' . $langcode)), 'A required select list with an actual value has no "none" choice.');
|
||||
$this->assertOptionSelected("edit-card-1-$langcode", 0);
|
||||
$this->assertNoOptionSelected("edit-card-1-$langcode", 1);
|
||||
$this->assertNoOptionSelected("edit-card-1-$langcode", 2);
|
||||
@@ -259,7 +276,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
// Display form.
|
||||
$this->drupalGet('test-entity/manage/' . $entity->ftid . '/edit');
|
||||
// A non-required field has a 'none' option.
|
||||
$this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', array(':id' => 'edit-card-1-' . $langcode, ':label' => t('- None -'))), t('A non-required select list has a "None" choice.'));
|
||||
$this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', array(':id' => 'edit-card-1-' . $langcode, ':label' => t('- None -'))), 'A non-required select list has a "None" choice.');
|
||||
// Submit form: Unselect the option.
|
||||
$edit = array("card_1[$langcode]" => '_none');
|
||||
$this->drupalPost('test-entity/manage/' . $entity->ftid . '/edit', $edit, t('Save'));
|
||||
@@ -276,8 +293,8 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
$this->assertNoOptionSelected("edit-card-1-$langcode", 0);
|
||||
$this->assertNoOptionSelected("edit-card-1-$langcode", 1);
|
||||
$this->assertNoOptionSelected("edit-card-1-$langcode", 2);
|
||||
$this->assertRaw('Some dangerous & unescaped markup', t('Option text was properly filtered.'));
|
||||
$this->assertRaw('Group 1', t('Option groups are displayed.'));
|
||||
$this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.');
|
||||
$this->assertRaw('Group 1', 'Option groups are displayed.');
|
||||
|
||||
// Submit form: select first option.
|
||||
$edit = array("card_1[$langcode]" => 0);
|
||||
@@ -323,7 +340,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
$this->assertNoOptionSelected("edit-card-2-$langcode", 0);
|
||||
$this->assertNoOptionSelected("edit-card-2-$langcode", 1);
|
||||
$this->assertNoOptionSelected("edit-card-2-$langcode", 2);
|
||||
$this->assertRaw('Some dangerous & unescaped markup', t('Option text was properly filtered.'));
|
||||
$this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.');
|
||||
|
||||
// Submit form: select first and third options.
|
||||
$edit = array("card_2[$langcode][]" => array(0 => 0, 2 => 2));
|
||||
@@ -350,7 +367,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
// Submit form: select the three options while the field accepts only 2.
|
||||
$edit = array("card_2[$langcode][]" => array(0 => 0, 1 => 1, 2 => 2));
|
||||
$this->drupalPost(NULL, $edit, t('Save'));
|
||||
$this->assertText('this field cannot hold more than 2 values', t('Validation error was displayed.'));
|
||||
$this->assertText('this field cannot hold more than 2 values', 'Validation error was displayed.');
|
||||
|
||||
// Submit form: uncheck all options.
|
||||
$edit = array("card_2[$langcode][]" => array());
|
||||
@@ -359,7 +376,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
|
||||
// Test the 'None' option.
|
||||
|
||||
// Check that the 'none' option has no efect if actual options are selected
|
||||
// Check that the 'none' option has no effect if actual options are selected
|
||||
// as well.
|
||||
$edit = array("card_2[$langcode][]" => array('_none' => '_none', 0 => 0));
|
||||
$this->drupalPost('test-entity/manage/' . $entity->ftid . '/edit', $edit, t('Save'));
|
||||
@@ -374,7 +391,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
$instance['required'] = TRUE;
|
||||
field_update_instance($instance);
|
||||
$this->drupalGet('test-entity/manage/' . $entity->ftid . '/edit');
|
||||
$this->assertFalse($this->xpath('//select[@id=:id]//option[@value=""]', array(':id' => 'edit-card-2-' . $langcode)), t('A required select list does not have an empty key.'));
|
||||
$this->assertFalse($this->xpath('//select[@id=:id]//option[@value=""]', array(':id' => 'edit-card-2-' . $langcode)), 'A required select list does not have an empty key.');
|
||||
|
||||
// We do not have to test that a required select list with one option is
|
||||
// auto-selected because the browser does it for us.
|
||||
@@ -393,8 +410,8 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
$this->assertNoOptionSelected("edit-card-2-$langcode", 0);
|
||||
$this->assertNoOptionSelected("edit-card-2-$langcode", 1);
|
||||
$this->assertNoOptionSelected("edit-card-2-$langcode", 2);
|
||||
$this->assertRaw('Some dangerous & unescaped markup', t('Option text was properly filtered.'));
|
||||
$this->assertRaw('Group 1', t('Option groups are displayed.'));
|
||||
$this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.');
|
||||
$this->assertRaw('Group 1', 'Option groups are displayed.');
|
||||
|
||||
// Submit form: select first option.
|
||||
$edit = array("card_2[$langcode][]" => array(0 => 0));
|
||||
@@ -438,7 +455,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
// Display form: with no field data, option is unchecked.
|
||||
$this->drupalGet('test-entity/manage/' . $entity->ftid . '/edit');
|
||||
$this->assertNoFieldChecked("edit-bool-$langcode");
|
||||
$this->assertRaw('Some dangerous & unescaped <strong>markup</strong>', t('Option text was properly filtered.'));
|
||||
$this->assertRaw('Some dangerous & unescaped <strong>markup</strong>', 'Option text was properly filtered.');
|
||||
|
||||
// Submit form: check the option.
|
||||
$edit = array("bool[$langcode]" => TRUE);
|
||||
@@ -459,7 +476,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
$this->assertNoFieldChecked("edit-bool-$langcode");
|
||||
|
||||
// Create admin user.
|
||||
$admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy'));
|
||||
$admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy', 'administer fields'));
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// Create a test field instance.
|
||||
@@ -483,13 +500,13 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
|
||||
$this->assertText(
|
||||
'Use field label instead of the "On value" as label ',
|
||||
t('Display setting checkbox available.')
|
||||
'Display setting checkbox available.'
|
||||
);
|
||||
|
||||
$this->assertFieldByXPath(
|
||||
'*//label[@for="edit-' . $this->bool['field_name'] . '-und" and text()="MyOnValue "]',
|
||||
TRUE,
|
||||
t('Default case shows "On value"')
|
||||
'Default case shows "On value"'
|
||||
);
|
||||
|
||||
// Enable setting
|
||||
@@ -502,16 +519,16 @@ class OptionsWidgetsTestCase extends FieldTestCase {
|
||||
$this->drupalGet($fieldEditUrl);
|
||||
$this->assertText(
|
||||
'Use field label instead of the "On value" as label ',
|
||||
t('Display setting checkbox is available')
|
||||
'Display setting checkbox is available'
|
||||
);
|
||||
$this->assertFieldChecked(
|
||||
'edit-instance-widget-settings-display-label',
|
||||
t('Display settings checkbox checked')
|
||||
'Display settings checkbox checked'
|
||||
);
|
||||
$this->assertFieldByXPath(
|
||||
'*//label[@for="edit-' . $this->bool['field_name'] . '-und" and text()="' . $this->bool['field_name'] . ' "]',
|
||||
TRUE,
|
||||
t('Display label changes label of the checkbox')
|
||||
'Display label changes label of the checkbox'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@ dependencies[] = field
|
||||
files[] = text.test
|
||||
required = TRUE
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -12,9 +12,9 @@ Drupal.behaviors.textSummary = {
|
||||
|
||||
$summaries.once('text-summary-wrapper').each(function(index) {
|
||||
var $summary = $(this);
|
||||
var $summaryLabel = $summary.find('label');
|
||||
var $summaryLabel = $summary.find('label').first();
|
||||
var $full = $widget.find('.text-full').eq(index).closest('.form-item');
|
||||
var $fullLabel = $full.find('label');
|
||||
var $fullLabel = $full.find('label').first();
|
||||
|
||||
// Create a placeholder label when the field cardinality is
|
||||
// unlimited or greater than 1.
|
||||
@@ -23,24 +23,28 @@ Drupal.behaviors.textSummary = {
|
||||
}
|
||||
|
||||
// Setup the edit/hide summary link.
|
||||
var $link = $('<span class="field-edit-link">(<a class="link-edit-summary" href="#">' + Drupal.t('Hide summary') + '</a>)</span>').toggle(
|
||||
function () {
|
||||
var $link = $('<span class="field-edit-link">(<a class="link-edit-summary" href="#">' + Drupal.t('Hide summary') + '</a>)</span>');
|
||||
var $a = $link.find('a');
|
||||
var toggleClick = true;
|
||||
$link.bind('click', function (e) {
|
||||
if (toggleClick) {
|
||||
$summary.hide();
|
||||
$(this).find('a').html(Drupal.t('Edit summary')).end().appendTo($fullLabel);
|
||||
return false;
|
||||
},
|
||||
function () {
|
||||
$summary.show();
|
||||
$(this).find('a').html(Drupal.t('Hide summary')).end().appendTo($summaryLabel);
|
||||
return false;
|
||||
$a.html(Drupal.t('Edit summary'));
|
||||
$link.appendTo($fullLabel);
|
||||
}
|
||||
).appendTo($summaryLabel);
|
||||
else {
|
||||
$summary.show();
|
||||
$a.html(Drupal.t('Hide summary'));
|
||||
$link.appendTo($summaryLabel);
|
||||
}
|
||||
toggleClick = !toggleClick;
|
||||
return false;
|
||||
}).appendTo($summaryLabel);
|
||||
|
||||
// If no summary is set, hide the summary field.
|
||||
if ($(this).find('.text-summary').val() == '') {
|
||||
$link.click();
|
||||
}
|
||||
return;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -223,11 +223,13 @@ function text_field_formatter_settings_form($field, $instance, $view_mode, $form
|
||||
|
||||
if (strpos($display['type'], '_trimmed') !== FALSE) {
|
||||
$element['trim_length'] = array(
|
||||
'#title' => t('Trim length'),
|
||||
'#title' => t('Trimmed limit'),
|
||||
'#type' => 'textfield',
|
||||
'#field_suffix' => t('characters'),
|
||||
'#size' => 10,
|
||||
'#default_value' => $settings['trim_length'],
|
||||
'#element_validate' => array('element_validate_integer_positive'),
|
||||
'#description' => t('If the summary is not set, the trimmed %label field will be shorter than this character limit.', array('%label' => $instance['label'])),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
}
|
||||
@@ -245,7 +247,7 @@ function text_field_formatter_settings_summary($field, $instance, $view_mode) {
|
||||
$summary = '';
|
||||
|
||||
if (strpos($display['type'], '_trimmed') !== FALSE) {
|
||||
$summary = t('Trim length') . ': ' . $settings['trim_length'];
|
||||
$summary = t('Trimmed limit: @trim_length characters', array('@trim_length' => $settings['trim_length']));
|
||||
}
|
||||
|
||||
return $summary;
|
||||
|
||||
@@ -110,8 +110,8 @@ class TextFieldTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('test-entity/add/test-bundle');
|
||||
$this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', t('Widget is displayed'));
|
||||
$this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '1', t('Format selector is not displayed'));
|
||||
$this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', 'Widget is displayed');
|
||||
$this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '1', 'Format selector is not displayed');
|
||||
|
||||
// Submit with some value.
|
||||
$value = $this->randomName();
|
||||
@@ -121,7 +121,7 @@ class TextFieldTestCase extends DrupalWebTestCase {
|
||||
$this->drupalPost(NULL, $edit, t('Save'));
|
||||
preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
|
||||
$id = $match[1];
|
||||
$this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), t('Entity was created'));
|
||||
$this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created');
|
||||
|
||||
// Display the entity.
|
||||
$entity = field_test_entity_test_load($id);
|
||||
@@ -179,8 +179,8 @@ class TextFieldTestCase extends DrupalWebTestCase {
|
||||
// Display the creation form. Since the user only has access to one format,
|
||||
// no format selector will be displayed.
|
||||
$this->drupalGet('test-entity/add/test-bundle');
|
||||
$this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', t('Widget is displayed'));
|
||||
$this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '', t('Format selector is not displayed'));
|
||||
$this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', 'Widget is displayed');
|
||||
$this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '', 'Format selector is not displayed');
|
||||
|
||||
// Submit with data that should be filtered.
|
||||
$value = '<em>' . $this->randomName() . '</em>';
|
||||
@@ -190,14 +190,14 @@ class TextFieldTestCase extends DrupalWebTestCase {
|
||||
$this->drupalPost(NULL, $edit, t('Save'));
|
||||
preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
|
||||
$id = $match[1];
|
||||
$this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), t('Entity was created'));
|
||||
$this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created');
|
||||
|
||||
// Display the entity.
|
||||
$entity = field_test_entity_test_load($id);
|
||||
$entity->content = field_attach_view($entity_type, $entity, 'full');
|
||||
$this->content = drupal_render($entity->content);
|
||||
$this->assertNoRaw($value, t('HTML tags are not displayed.'));
|
||||
$this->assertRaw(check_plain($value), t('Escaped HTML is displayed correctly.'));
|
||||
$this->assertNoRaw($value, 'HTML tags are not displayed.');
|
||||
$this->assertRaw(check_plain($value), 'Escaped HTML is displayed correctly.');
|
||||
|
||||
// Create a new text format that does not escape HTML, and grant the user
|
||||
// access to it.
|
||||
@@ -219,21 +219,21 @@ class TextFieldTestCase extends DrupalWebTestCase {
|
||||
// Display edition form.
|
||||
// We should now have a 'text format' selector.
|
||||
$this->drupalGet('test-entity/manage/' . $id . '/edit');
|
||||
$this->assertFieldByName("{$this->field_name}[$langcode][0][value]", NULL, t('Widget is displayed'));
|
||||
$this->assertFieldByName("{$this->field_name}[$langcode][0][format]", NULL, t('Format selector is displayed'));
|
||||
$this->assertFieldByName("{$this->field_name}[$langcode][0][value]", NULL, 'Widget is displayed');
|
||||
$this->assertFieldByName("{$this->field_name}[$langcode][0][format]", NULL, 'Format selector is displayed');
|
||||
|
||||
// Edit and change the text format to the new one that was created.
|
||||
$edit = array(
|
||||
"{$this->field_name}[$langcode][0][format]" => $format_id,
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('test_entity @id has been updated.', array('@id' => $id)), t('Entity was updated'));
|
||||
$this->assertRaw(t('test_entity @id has been updated.', array('@id' => $id)), 'Entity was updated');
|
||||
|
||||
// Display the entity.
|
||||
$entity = field_test_entity_test_load($id);
|
||||
$entity->content = field_attach_view($entity_type, $entity, 'full');
|
||||
$this->content = drupal_render($entity->content);
|
||||
$this->assertRaw($value, t('Value is displayed unfiltered'));
|
||||
$this->assertRaw($value, 'Value is displayed unfiltered');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,7 +383,7 @@ class TextSummaryTestCase extends DrupalWebTestCase {
|
||||
*/
|
||||
function callTextSummary($text, $expected, $format = NULL, $size = NULL) {
|
||||
$summary = text_summary($text, $format, $size);
|
||||
$this->assertIdentical($summary, $expected, t('Generated summary "@summary" matches expected "@expected".', array('@summary' => $summary, '@expected' => $expected)));
|
||||
$this->assertIdentical($summary, $expected, format_string('Generated summary "@summary" matches expected "@expected".', array('@summary' => $summary, '@expected' => $expected)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -401,7 +401,7 @@ class TextSummaryTestCase extends DrupalWebTestCase {
|
||||
$this->drupalPost('node/add/article', $edit, t('Save'));
|
||||
$node = $this->drupalGetNodeByTitle($edit['title']);
|
||||
|
||||
$this->assertIdentical($node->body['und'][0]['summary'], $summary, t('Article with with summary and no body has been submitted.'));
|
||||
$this->assertIdentical($node->body['und'][0]['summary'], $summary, 'Article with with summary and no body has been submitted.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,6 +424,7 @@ class TextTranslationTestCase extends DrupalWebTestCase {
|
||||
'administer content types',
|
||||
'access administration pages',
|
||||
'bypass node access',
|
||||
'administer fields',
|
||||
filter_permission_name($full_html_format),
|
||||
));
|
||||
$this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content'));
|
||||
@@ -436,7 +437,7 @@ class TextTranslationTestCase extends DrupalWebTestCase {
|
||||
// Set "Article" content type to use multilingual support with translation.
|
||||
$edit = array('language_content_type' => 2);
|
||||
$this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
|
||||
$this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Article')), t('Article content type has been updated.'));
|
||||
$this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Article')), 'Article content type has been updated.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -464,7 +465,7 @@ class TextTranslationTestCase extends DrupalWebTestCase {
|
||||
$node = $this->drupalGetNodeByTitle($edit['title']);
|
||||
$this->drupalGet("node/$node->nid/translate");
|
||||
$this->clickLink(t('add translation'));
|
||||
$this->assertFieldByXPath("//textarea[@name='body[$langcode][0][value]']", $body, t('The textfield widget is populated.'));
|
||||
$this->assertFieldByXPath("//textarea[@name='body[$langcode][0][value]']", $body, 'The textfield widget is populated.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -476,7 +477,7 @@ class TextTranslationTestCase extends DrupalWebTestCase {
|
||||
$edit = array('field[cardinality]' => -1);
|
||||
$this->drupalPost('admin/structure/types/manage/article/fields/body', $edit, t('Save settings'));
|
||||
$this->drupalGet('node/add/article');
|
||||
$this->assertFieldByXPath("//input[@name='body_add_more']", t('Add another item'), t('Body field cardinality set to multiple.'));
|
||||
$this->assertFieldByXPath("//input[@name='body_add_more']", t('Add another item'), 'Body field cardinality set to multiple.');
|
||||
|
||||
$body = array(
|
||||
$this->randomName(),
|
||||
@@ -501,7 +502,7 @@ class TextTranslationTestCase extends DrupalWebTestCase {
|
||||
"body[$langcode][$delta][format]" => array_shift($formats),
|
||||
);
|
||||
$this->drupalPost('node/1/edit', $edit, t('Save'));
|
||||
$this->assertText($body[$delta], t('The body field with delta @delta has been saved.', array('@delta' => $delta)));
|
||||
$this->assertText($body[$delta], format_string('The body field with delta @delta has been saved.', array('@delta' => $delta)));
|
||||
}
|
||||
|
||||
// Login as translator.
|
||||
@@ -511,7 +512,7 @@ class TextTranslationTestCase extends DrupalWebTestCase {
|
||||
$node = $this->drupalGetNodeByTitle($title);
|
||||
$this->drupalGet("node/$node->nid/translate");
|
||||
$this->clickLink(t('add translation'));
|
||||
$this->assertNoText($body[0], t('The body field with delta @delta is hidden.', array('@delta' => 0)));
|
||||
$this->assertText($body[1], t('The body field with delta @delta is shown.', array('@delta' => 1)));
|
||||
$this->assertNoText($body[0], format_string('The body field with delta @delta is hidden.', array('@delta' => 0)));
|
||||
$this->assertText($body[1], format_string('The body field with delta @delta is shown.', array('@delta' => 1)));
|
||||
}
|
||||
}
|
||||
|
||||
+245
-184
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,9 @@ function field_test_field_info() {
|
||||
'shape' => array(
|
||||
'label' => t('Shape'),
|
||||
'description' => t('Another dummy field type.'),
|
||||
'settings' => array(),
|
||||
'settings' => array(
|
||||
'foreign_key_name' => 'shape',
|
||||
),
|
||||
'instance_settings' => array(),
|
||||
'default_widget' => 'test_field_widget',
|
||||
'default_formatter' => 'field_test_default',
|
||||
|
||||
@@ -6,8 +6,7 @@ files[] = field_test.entity.inc
|
||||
version = VERSION
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -60,7 +60,7 @@ function field_test_schema() {
|
||||
'description' => 'The base table for test entities with a bundle key.',
|
||||
'fields' => array(
|
||||
'ftid' => array(
|
||||
'description' => 'The primary indentifier for a test_entity_bundle_key.',
|
||||
'description' => 'The primary identifier for a test_entity_bundle_key.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -79,7 +79,7 @@ function field_test_schema() {
|
||||
'description' => 'The base table for test entities with a bundle.',
|
||||
'fields' => array(
|
||||
'ftid' => array(
|
||||
'description' => 'The primary indentifier for a test_entity_bundle.',
|
||||
'description' => 'The primary identifier for a test_entity_bundle.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -132,6 +132,18 @@ function field_test_field_schema($field) {
|
||||
);
|
||||
}
|
||||
else {
|
||||
$foreign_keys = array();
|
||||
// The 'foreign keys' key is not always used in tests.
|
||||
if (!empty($field['settings']['foreign_key_name'])) {
|
||||
$foreign_keys['foreign keys'] = array(
|
||||
// This is a dummy foreign key definition, references a table that
|
||||
// doesn't exist, but that's not a problem.
|
||||
$field['settings']['foreign_key_name'] => array(
|
||||
'table' => $field['settings']['foreign_key_name'],
|
||||
'columns' => array($field['settings']['foreign_key_name'] => 'id'),
|
||||
),
|
||||
);
|
||||
}
|
||||
return array(
|
||||
'columns' => array(
|
||||
'shape' => array(
|
||||
@@ -145,6 +157,6 @@ function field_test_field_schema($field) {
|
||||
'not null' => FALSE,
|
||||
),
|
||||
),
|
||||
);
|
||||
) + $foreign_keys;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,10 +204,7 @@ function field_test_dummy_field_storage_query(EntityFieldQuery $query) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Entity label callback.
|
||||
*
|
||||
* @param $entity
|
||||
* The entity object.
|
||||
* Implements callback_entity_info_label().
|
||||
*
|
||||
* @return
|
||||
* The label of the entity prefixed with "label callback".
|
||||
@@ -223,6 +220,10 @@ function field_test_field_attach_view_alter(&$output, $context) {
|
||||
if (!empty($context['display']['settings']['alter'])) {
|
||||
$output['test_field'][] = array('#markup' => 'field_test_field_attach_view_alter');
|
||||
}
|
||||
|
||||
if (isset($output['test_field'])) {
|
||||
$output['test_field'][] = array('#markup' => 'field language is ' . $context['language']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,3 +271,14 @@ function field_test_query_efq_table_prefixing_test_alter(&$query) {
|
||||
// exception if the EFQ does not properly prefix the base table.
|
||||
$query->join('test_entity','te2','%alias.ftid = test_entity.ftid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_query_TAG_alter() for tag 'store_global_test_query'.
|
||||
*/
|
||||
function field_test_query_store_global_test_query_alter($query) {
|
||||
// Save the query in a global variable so that it can be examined by tests.
|
||||
// This can be used by any test which needs to check a query, but see
|
||||
// FieldSqlStorageTestCase::testFieldSqlStorageMultipleConditionsSameColumn()
|
||||
// for an example.
|
||||
$GLOBALS['test_query'] = $query;
|
||||
}
|
||||
|
||||
@@ -455,13 +455,13 @@ function field_test_field_attach_rename_bundle($bundle_old, $bundle_new) {
|
||||
function field_test_field_attach_delete_bundle($entity_type, $bundle, $instances) {
|
||||
$data = _field_test_storage_data();
|
||||
|
||||
foreach ($instances as $field_name => $instance) {
|
||||
$field = field_info_field($field_name);
|
||||
foreach ($instances as $instance) {
|
||||
$field = field_info_field_by_id($instance['field_id']);
|
||||
if ($field['storage']['type'] == 'field_test_storage') {
|
||||
$field_data = &$data[$field['id']];
|
||||
foreach (array('current', 'revisions') as $sub_table) {
|
||||
foreach ($field_data[$sub_table] as &$row) {
|
||||
if ($row->bundle == $bundle_old) {
|
||||
if ($row->bundle == $bundle) {
|
||||
$row->deleted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
* @file field.tpl.php
|
||||
* Default template implementation to display the value of a field.
|
||||
*
|
||||
* This file is not used and is here as a starting point for customization only.
|
||||
* @see theme_field()
|
||||
* This file is not used by Drupal core, which uses theme functions instead for
|
||||
* performance reasons. The markup is the same, though, so if you want to use
|
||||
* template files rather than functions to extend field theming, copy this to
|
||||
* your custom theme. See theme_field() for a discussion of performance.
|
||||
*
|
||||
* Available variables:
|
||||
* - $items: An array of field values. Use render() to output them.
|
||||
@@ -45,7 +47,7 @@
|
||||
*/
|
||||
?>
|
||||
<!--
|
||||
THIS FILE IS NOT USED AND IS HERE AS A STARTING POINT FOR CUSTOMIZATION ONLY.
|
||||
This file is not used by Drupal core, which uses theme functions instead.
|
||||
See http://api.drupal.org/api/function/theme_field/7 for details.
|
||||
After copying this file to your theme's folder and customizing it, remove this
|
||||
HTML comment.
|
||||
|
||||
Reference in New Issue
Block a user