initial commit of starter install drupal 7
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
name = Text
|
||||
description = Defines simple text field types.
|
||||
package = Core
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
dependencies[] = field
|
||||
files[] = text.test
|
||||
required = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2014-11-19
|
||||
version = "7.34"
|
||||
project = "drupal"
|
||||
datestamp = "1416429488"
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the text module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_field_schema().
|
||||
*/
|
||||
function text_field_schema($field) {
|
||||
switch ($field['type']) {
|
||||
case 'text':
|
||||
$columns = array(
|
||||
'value' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => $field['settings']['max_length'],
|
||||
'not null' => FALSE,
|
||||
),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'text_long':
|
||||
$columns = array(
|
||||
'value' => array(
|
||||
'type' => 'text',
|
||||
'size' => 'big',
|
||||
'not null' => FALSE,
|
||||
),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'text_with_summary':
|
||||
$columns = array(
|
||||
'value' => array(
|
||||
'type' => 'text',
|
||||
'size' => 'big',
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'summary' => array(
|
||||
'type' => 'text',
|
||||
'size' => 'big',
|
||||
'not null' => FALSE,
|
||||
),
|
||||
);
|
||||
break;
|
||||
}
|
||||
$columns += array(
|
||||
'format' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
);
|
||||
return array(
|
||||
'columns' => $columns,
|
||||
'indexes' => array(
|
||||
'format' => array('format'),
|
||||
),
|
||||
'foreign keys' => array(
|
||||
'format' => array(
|
||||
'table' => 'filter_format',
|
||||
'columns' => array('format' => 'format'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change text field 'format' columns into varchar.
|
||||
*/
|
||||
function text_update_7000() {
|
||||
$spec = array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
);
|
||||
$fields = _update_7000_field_read_fields(array(
|
||||
'module' => 'text',
|
||||
'storage_type' => 'field_sql_storage',
|
||||
));
|
||||
foreach ($fields as $field) {
|
||||
if ($field['deleted']) {
|
||||
$table = "field_deleted_data_{$field['id']}";
|
||||
$revision_table = "field_deleted_revision_{$field['id']}";
|
||||
}
|
||||
else {
|
||||
$table = "field_data_{$field['field_name']}";
|
||||
$revision_table = "field_revision_{$field['field_name']}";
|
||||
}
|
||||
$column = $field['field_name'] . '_' . 'format';
|
||||
db_change_field($table, $column, $column, $spec);
|
||||
db_change_field($revision_table, $column, $column, $spec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
(function ($) {
|
||||
|
||||
/**
|
||||
* Auto-hide summary textarea if empty and show hide and unhide links.
|
||||
*/
|
||||
Drupal.behaviors.textSummary = {
|
||||
attach: function (context, settings) {
|
||||
$('.text-summary', context).once('text-summary', function () {
|
||||
var $widget = $(this).closest('div.field-type-text-with-summary');
|
||||
var $summaries = $widget.find('div.text-summary-wrapper');
|
||||
|
||||
$summaries.once('text-summary-wrapper').each(function(index) {
|
||||
var $summary = $(this);
|
||||
var $summaryLabel = $summary.find('label').first();
|
||||
var $full = $widget.find('.text-full').eq(index).closest('.form-item');
|
||||
var $fullLabel = $full.find('label').first();
|
||||
|
||||
// Create a placeholder label when the field cardinality is
|
||||
// unlimited or greater than 1.
|
||||
if ($fullLabel.length == 0) {
|
||||
$fullLabel = $('<label></label>').prependTo($full);
|
||||
}
|
||||
|
||||
// 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>');
|
||||
var $a = $link.find('a');
|
||||
var toggleClick = true;
|
||||
$link.bind('click', function (e) {
|
||||
if (toggleClick) {
|
||||
$summary.hide();
|
||||
$a.html(Drupal.t('Edit summary'));
|
||||
$link.appendTo($fullLabel);
|
||||
}
|
||||
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();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,611 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Defines simple text field types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_help().
|
||||
*/
|
||||
function text_help($path, $arg) {
|
||||
switch ($path) {
|
||||
case 'admin/help#text':
|
||||
$output = '';
|
||||
$output .= '<h3>' . t('About') . '</h3>';
|
||||
$output .= '<p>' . t("The Text module defines various text field types for the Field module. A text field may contain plain text only, or optionally, may use Drupal's <a href='@filter-help'>text filters</a> to securely manage HTML output. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, the field can be validated, so that it is limited to a set of allowed values. See the <a href='@field-help'>Field module help page</a> for more information about fields.", array('@field-help' => url('admin/help/field'), '@filter-help' => url('admin/help/filter'))) . '</p>';
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_info().
|
||||
*
|
||||
* Field settings:
|
||||
* - max_length: the maximum length for a varchar field.
|
||||
* Instance settings:
|
||||
* - text_processing: whether text input filters should be used.
|
||||
* - display_summary: whether the summary field should be displayed.
|
||||
* When empty and not displayed the summary will take its value from the
|
||||
* trimmed value of the main text field.
|
||||
*/
|
||||
function text_field_info() {
|
||||
return array(
|
||||
'text' => array(
|
||||
'label' => t('Text'),
|
||||
'description' => t('This field stores varchar text in the database.'),
|
||||
'settings' => array('max_length' => 255),
|
||||
'instance_settings' => array('text_processing' => 0),
|
||||
'default_widget' => 'text_textfield',
|
||||
'default_formatter' => 'text_default',
|
||||
),
|
||||
'text_long' => array(
|
||||
'label' => t('Long text'),
|
||||
'description' => t('This field stores long text in the database.'),
|
||||
'instance_settings' => array('text_processing' => 0),
|
||||
'default_widget' => 'text_textarea',
|
||||
'default_formatter' => 'text_default',
|
||||
),
|
||||
'text_with_summary' => array(
|
||||
'label' => t('Long text and summary'),
|
||||
'description' => t('This field stores long text in the database along with optional summary text.'),
|
||||
'instance_settings' => array('text_processing' => 1, 'display_summary' => 0),
|
||||
'default_widget' => 'text_textarea_with_summary',
|
||||
'default_formatter' => 'text_default',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_settings_form().
|
||||
*/
|
||||
function text_field_settings_form($field, $instance, $has_data) {
|
||||
$settings = $field['settings'];
|
||||
|
||||
$form = array();
|
||||
|
||||
if ($field['type'] == 'text') {
|
||||
$form['max_length'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Maximum length'),
|
||||
'#default_value' => $settings['max_length'],
|
||||
'#required' => TRUE,
|
||||
'#description' => t('The maximum length of the field in characters.'),
|
||||
'#element_validate' => array('element_validate_integer_positive'),
|
||||
// @todo: If $has_data, add a validate handler that only allows
|
||||
// max_length to increase.
|
||||
'#disabled' => $has_data,
|
||||
);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_instance_settings_form().
|
||||
*/
|
||||
function text_field_instance_settings_form($field, $instance) {
|
||||
$settings = $instance['settings'];
|
||||
|
||||
$form['text_processing'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('Text processing'),
|
||||
'#default_value' => $settings['text_processing'],
|
||||
'#options' => array(
|
||||
t('Plain text'),
|
||||
t('Filtered text (user selects text format)'),
|
||||
),
|
||||
);
|
||||
if ($field['type'] == 'text_with_summary') {
|
||||
$form['display_summary'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Summary input'),
|
||||
'#default_value' => $settings['display_summary'],
|
||||
'#description' => t('This allows authors to input an explicit summary, to be displayed instead of the automatically trimmed text when using the "Summary or trimmed" display type.'),
|
||||
);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_validate().
|
||||
*
|
||||
* Possible error codes:
|
||||
* - 'text_value_max_length': The value exceeds the maximum length.
|
||||
* - 'text_summary_max_length': The summary exceeds the maximum length.
|
||||
*/
|
||||
function text_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
|
||||
foreach ($items as $delta => $item) {
|
||||
// @todo Length is counted separately for summary and value, so the maximum
|
||||
// length can be exceeded very easily.
|
||||
foreach (array('value', 'summary') as $column) {
|
||||
if (!empty($item[$column])) {
|
||||
if (!empty($field['settings']['max_length']) && drupal_strlen($item[$column]) > $field['settings']['max_length']) {
|
||||
switch ($column) {
|
||||
case 'value':
|
||||
$message = t('%name: the text may not be longer than %max characters.', array('%name' => $instance['label'], '%max' => $field['settings']['max_length']));
|
||||
break;
|
||||
|
||||
case 'summary':
|
||||
$message = t('%name: the summary may not be longer than %max characters.', array('%name' => $instance['label'], '%max' => $field['settings']['max_length']));
|
||||
break;
|
||||
}
|
||||
$errors[$field['field_name']][$langcode][$delta][] = array(
|
||||
'error' => "text_{$column}_length",
|
||||
'message' => $message,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_load().
|
||||
*
|
||||
* Where possible, generate the sanitized version of each field early so that
|
||||
* it is cached in the field cache. This avoids looking up from the filter cache
|
||||
* separately.
|
||||
*
|
||||
* @see text_field_formatter_view()
|
||||
*/
|
||||
function text_field_load($entity_type, $entities, $field, $instances, $langcode, &$items) {
|
||||
foreach ($entities as $id => $entity) {
|
||||
foreach ($items[$id] as $delta => $item) {
|
||||
// Only process items with a cacheable format, the rest will be handled
|
||||
// by formatters if needed.
|
||||
if (empty($instances[$id]['settings']['text_processing']) || filter_format_allowcache($item['format'])) {
|
||||
$items[$id][$delta]['safe_value'] = isset($item['value']) ? _text_sanitize($instances[$id], $langcode, $item, 'value') : '';
|
||||
if ($field['type'] == 'text_with_summary') {
|
||||
$items[$id][$delta]['safe_summary'] = isset($item['summary']) ? _text_sanitize($instances[$id], $langcode, $item, 'summary') : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_is_empty().
|
||||
*/
|
||||
function text_field_is_empty($item, $field) {
|
||||
if (!isset($item['value']) || $item['value'] === '') {
|
||||
return !isset($item['summary']) || $item['summary'] === '';
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_formatter_info().
|
||||
*/
|
||||
function text_field_formatter_info() {
|
||||
return array(
|
||||
'text_default' => array(
|
||||
'label' => t('Default'),
|
||||
'field types' => array('text', 'text_long', 'text_with_summary'),
|
||||
),
|
||||
'text_plain' => array(
|
||||
'label' => t('Plain text'),
|
||||
'field types' => array('text', 'text_long', 'text_with_summary'),
|
||||
),
|
||||
|
||||
// The text_trimmed formatter displays the trimmed version of the
|
||||
// full element of the field. It is intended to be used with text
|
||||
// and text_long fields. It also works with text_with_summary
|
||||
// fields though the text_summary_or_trimmed formatter makes more
|
||||
// sense for that field type.
|
||||
'text_trimmed' => array(
|
||||
'label' => t('Trimmed'),
|
||||
'field types' => array('text', 'text_long', 'text_with_summary'),
|
||||
'settings' => array('trim_length' => 600),
|
||||
),
|
||||
|
||||
// The 'summary or trimmed' field formatter for text_with_summary
|
||||
// fields displays returns the summary element of the field or, if
|
||||
// the summary is empty, the trimmed version of the full element
|
||||
// of the field.
|
||||
'text_summary_or_trimmed' => array(
|
||||
'label' => t('Summary or trimmed'),
|
||||
'field types' => array('text_with_summary'),
|
||||
'settings' => array('trim_length' => 600),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_formatter_settings_form().
|
||||
*/
|
||||
function text_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
|
||||
$display = $instance['display'][$view_mode];
|
||||
$settings = $display['settings'];
|
||||
|
||||
$element = array();
|
||||
|
||||
if (strpos($display['type'], '_trimmed') !== FALSE) {
|
||||
$element['trim_length'] = array(
|
||||
'#title' => t('Trim length'),
|
||||
'#type' => 'textfield',
|
||||
'#size' => 10,
|
||||
'#default_value' => $settings['trim_length'],
|
||||
'#element_validate' => array('element_validate_integer_positive'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_formatter_settings_summary().
|
||||
*/
|
||||
function text_field_formatter_settings_summary($field, $instance, $view_mode) {
|
||||
$display = $instance['display'][$view_mode];
|
||||
$settings = $display['settings'];
|
||||
|
||||
$summary = '';
|
||||
|
||||
if (strpos($display['type'], '_trimmed') !== FALSE) {
|
||||
$summary = t('Trim length') . ': ' . check_plain($settings['trim_length']);
|
||||
}
|
||||
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_formatter_view().
|
||||
*/
|
||||
function text_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
|
||||
$element = array();
|
||||
|
||||
switch ($display['type']) {
|
||||
case 'text_default':
|
||||
case 'text_trimmed':
|
||||
foreach ($items as $delta => $item) {
|
||||
$output = _text_sanitize($instance, $langcode, $item, 'value');
|
||||
if ($display['type'] == 'text_trimmed') {
|
||||
$output = text_summary($output, $instance['settings']['text_processing'] ? $item['format'] : NULL, $display['settings']['trim_length']);
|
||||
}
|
||||
$element[$delta] = array('#markup' => $output);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'text_summary_or_trimmed':
|
||||
foreach ($items as $delta => $item) {
|
||||
if (!empty($item['summary'])) {
|
||||
$output = _text_sanitize($instance, $langcode, $item, 'summary');
|
||||
}
|
||||
else {
|
||||
$output = _text_sanitize($instance, $langcode, $item, 'value');
|
||||
$output = text_summary($output, $instance['settings']['text_processing'] ? $item['format'] : NULL, $display['settings']['trim_length']);
|
||||
}
|
||||
$element[$delta] = array('#markup' => $output);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'text_plain':
|
||||
foreach ($items as $delta => $item) {
|
||||
$element[$delta] = array('#markup' => strip_tags($item['value']));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the 'value' or 'summary' data of a text value.
|
||||
*
|
||||
* Depending on whether the field instance uses text processing, data is run
|
||||
* through check_plain() or check_markup().
|
||||
*
|
||||
* @param $instance
|
||||
* The instance definition.
|
||||
* @param $langcode
|
||||
* The language associated to $item.
|
||||
* @param $item
|
||||
* The field value to sanitize.
|
||||
* @param $column
|
||||
* The column to sanitize (either 'value' or 'summary').
|
||||
*
|
||||
* @return
|
||||
* The sanitized string.
|
||||
*/
|
||||
function _text_sanitize($instance, $langcode, $item, $column) {
|
||||
// If the value uses a cacheable text format, text_field_load() precomputes
|
||||
// the sanitized string.
|
||||
if (isset($item["safe_$column"])) {
|
||||
return $item["safe_$column"];
|
||||
}
|
||||
return $instance['settings']['text_processing'] ? check_markup($item[$column], $item['format'], $langcode) : check_plain($item[$column]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a trimmed, formatted version of a text field value.
|
||||
*
|
||||
* If the end of the summary is not indicated using the <!--break--> delimiter
|
||||
* then we generate the summary automatically, trying to end it at a sensible
|
||||
* place such as the end of a paragraph, a line break, or the end of a
|
||||
* sentence (in that order of preference).
|
||||
*
|
||||
* @param $text
|
||||
* The content for which a summary will be generated.
|
||||
* @param $format
|
||||
* The format of the content.
|
||||
* If the PHP filter is present and $text contains PHP code, we do not
|
||||
* split it up to prevent parse errors.
|
||||
* If the line break filter is present then we treat newlines embedded in
|
||||
* $text as line breaks.
|
||||
* If the htmlcorrector filter is present, it will be run on the generated
|
||||
* summary (if different from the incoming $text).
|
||||
* @param $size
|
||||
* The desired character length of the summary. If omitted, the default
|
||||
* value will be used. Ignored if the special delimiter is present
|
||||
* in $text.
|
||||
* @return
|
||||
* The generated summary.
|
||||
*/
|
||||
function text_summary($text, $format = NULL, $size = NULL) {
|
||||
|
||||
if (!isset($size)) {
|
||||
// What used to be called 'teaser' is now called 'summary', but
|
||||
// the variable 'teaser_length' is preserved for backwards compatibility.
|
||||
$size = variable_get('teaser_length', 600);
|
||||
}
|
||||
|
||||
// Find where the delimiter is in the body
|
||||
$delimiter = strpos($text, '<!--break-->');
|
||||
|
||||
// If the size is zero, and there is no delimiter, the entire body is the summary.
|
||||
if ($size == 0 && $delimiter === FALSE) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
// If a valid delimiter has been specified, use it to chop off the summary.
|
||||
if ($delimiter !== FALSE) {
|
||||
return substr($text, 0, $delimiter);
|
||||
}
|
||||
|
||||
// We check for the presence of the PHP evaluator filter in the current
|
||||
// format. If the body contains PHP code, we do not split it up to prevent
|
||||
// parse errors.
|
||||
if (isset($format)) {
|
||||
$filters = filter_list_format($format);
|
||||
if (isset($filters['php_code']) && $filters['php_code']->status && strpos($text, '<?') !== FALSE) {
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a short body, the entire body is the summary.
|
||||
if (drupal_strlen($text) <= $size) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
// If the delimiter has not been specified, try to split at paragraph or
|
||||
// sentence boundaries.
|
||||
|
||||
// The summary may not be longer than maximum length specified. Initial slice.
|
||||
$summary = truncate_utf8($text, $size);
|
||||
|
||||
// Store the actual length of the UTF8 string -- which might not be the same
|
||||
// as $size.
|
||||
$max_rpos = strlen($summary);
|
||||
|
||||
// How much to cut off the end of the summary so that it doesn't end in the
|
||||
// middle of a paragraph, sentence, or word.
|
||||
// Initialize it to maximum in order to find the minimum.
|
||||
$min_rpos = $max_rpos;
|
||||
|
||||
// Store the reverse of the summary. We use strpos on the reversed needle and
|
||||
// haystack for speed and convenience.
|
||||
$reversed = strrev($summary);
|
||||
|
||||
// Build an array of arrays of break points grouped by preference.
|
||||
$break_points = array();
|
||||
|
||||
// A paragraph near the end of sliced summary is most preferable.
|
||||
$break_points[] = array('</p>' => 0);
|
||||
|
||||
// If no complete paragraph then treat line breaks as paragraphs.
|
||||
$line_breaks = array('<br />' => 6, '<br>' => 4);
|
||||
// Newline only indicates a line break if line break converter
|
||||
// filter is present.
|
||||
if (isset($filters['filter_autop'])) {
|
||||
$line_breaks["\n"] = 1;
|
||||
}
|
||||
$break_points[] = $line_breaks;
|
||||
|
||||
// If the first paragraph is too long, split at the end of a sentence.
|
||||
$break_points[] = array('. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1);
|
||||
|
||||
// Iterate over the groups of break points until a break point is found.
|
||||
foreach ($break_points as $points) {
|
||||
// Look for each break point, starting at the end of the summary.
|
||||
foreach ($points as $point => $offset) {
|
||||
// The summary is already reversed, but the break point isn't.
|
||||
$rpos = strpos($reversed, strrev($point));
|
||||
if ($rpos !== FALSE) {
|
||||
$min_rpos = min($rpos + $offset, $min_rpos);
|
||||
}
|
||||
}
|
||||
|
||||
// If a break point was found in this group, slice and stop searching.
|
||||
if ($min_rpos !== $max_rpos) {
|
||||
// Don't slice with length 0. Length must be <0 to slice from RHS.
|
||||
$summary = ($min_rpos === 0) ? $summary : substr($summary, 0, 0 - $min_rpos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the htmlcorrector filter is present, apply it to the generated summary.
|
||||
if (isset($filters['filter_htmlcorrector'])) {
|
||||
$summary = _filter_htmlcorrector($summary);
|
||||
}
|
||||
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_info().
|
||||
*/
|
||||
function text_field_widget_info() {
|
||||
return array(
|
||||
'text_textfield' => array(
|
||||
'label' => t('Text field'),
|
||||
'field types' => array('text'),
|
||||
'settings' => array('size' => 60),
|
||||
),
|
||||
'text_textarea' => array(
|
||||
'label' => t('Text area (multiple rows)'),
|
||||
'field types' => array('text_long'),
|
||||
'settings' => array('rows' => 5),
|
||||
),
|
||||
'text_textarea_with_summary' => array(
|
||||
'label' => t('Text area with a summary'),
|
||||
'field types' => array('text_with_summary'),
|
||||
'settings' => array('rows' => 20, 'summary_rows' => 5),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_settings_form().
|
||||
*/
|
||||
function text_field_widget_settings_form($field, $instance) {
|
||||
$widget = $instance['widget'];
|
||||
$settings = $widget['settings'];
|
||||
|
||||
if ($widget['type'] == 'text_textfield') {
|
||||
$form['size'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Size of textfield'),
|
||||
'#default_value' => $settings['size'],
|
||||
'#required' => TRUE,
|
||||
'#element_validate' => array('element_validate_integer_positive'),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$form['rows'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Rows'),
|
||||
'#default_value' => $settings['rows'],
|
||||
'#required' => TRUE,
|
||||
'#element_validate' => array('element_validate_integer_positive'),
|
||||
);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_form().
|
||||
*/
|
||||
function text_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
|
||||
$summary_widget = array();
|
||||
$main_widget = array();
|
||||
|
||||
switch ($instance['widget']['type']) {
|
||||
case 'text_textfield':
|
||||
$main_widget = $element + array(
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL,
|
||||
'#size' => $instance['widget']['settings']['size'],
|
||||
'#maxlength' => $field['settings']['max_length'],
|
||||
'#attributes' => array('class' => array('text-full')),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'text_textarea_with_summary':
|
||||
$display = !empty($items[$delta]['summary']) || !empty($instance['settings']['display_summary']);
|
||||
$summary_widget = array(
|
||||
'#type' => $display ? 'textarea' : 'value',
|
||||
'#default_value' => isset($items[$delta]['summary']) ? $items[$delta]['summary'] : NULL,
|
||||
'#title' => t('Summary'),
|
||||
'#rows' => $instance['widget']['settings']['summary_rows'],
|
||||
'#description' => t('Leave blank to use trimmed value of full text as the summary.'),
|
||||
'#attached' => array(
|
||||
'js' => array(drupal_get_path('module', 'text') . '/text.js'),
|
||||
),
|
||||
'#attributes' => array('class' => array('text-summary')),
|
||||
'#prefix' => '<div class="text-summary-wrapper">',
|
||||
'#suffix' => '</div>',
|
||||
'#weight' => -10,
|
||||
);
|
||||
// Fall through to the next case.
|
||||
|
||||
case 'text_textarea':
|
||||
$main_widget = $element + array(
|
||||
'#type' => 'textarea',
|
||||
'#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL,
|
||||
'#rows' => $instance['widget']['settings']['rows'],
|
||||
'#attributes' => array('class' => array('text-full')),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($main_widget) {
|
||||
// Conditionally alter the form element's type if text processing is enabled.
|
||||
if ($instance['settings']['text_processing']) {
|
||||
$element = $main_widget;
|
||||
$element['#type'] = 'text_format';
|
||||
$element['#format'] = isset($items[$delta]['format']) ? $items[$delta]['format'] : NULL;
|
||||
$element['#base_type'] = $main_widget['#type'];
|
||||
}
|
||||
else {
|
||||
$element['value'] = $main_widget;
|
||||
}
|
||||
}
|
||||
if ($summary_widget) {
|
||||
$element['summary'] = $summary_widget;
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_error().
|
||||
*/
|
||||
function text_field_widget_error($element, $error, $form, &$form_state) {
|
||||
switch ($error['error']) {
|
||||
case 'text_summary_max_length':
|
||||
$error_element = $element[$element['#columns'][1]];
|
||||
break;
|
||||
|
||||
default:
|
||||
$error_element = $element[$element['#columns'][0]];
|
||||
break;
|
||||
}
|
||||
|
||||
form_error($error_element, $error['message']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_prepare_translation().
|
||||
*/
|
||||
function text_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,
|
||||
// we must not expose the source values.
|
||||
$field_name = $field['field_name'];
|
||||
if (!empty($source_entity->{$field_name}[$source_langcode])) {
|
||||
$formats = filter_formats();
|
||||
foreach ($source_entity->{$field_name}[$source_langcode] as $delta => $item) {
|
||||
$format_id = $item['format'];
|
||||
if (!empty($format_id) && !filter_access($formats[$format_id])) {
|
||||
unset($items[$delta]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_filter_format_update().
|
||||
*/
|
||||
function text_filter_format_update($format) {
|
||||
field_cache_clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_filter_format_disable().
|
||||
*/
|
||||
function text_filter_format_disable($format) {
|
||||
field_cache_clear();
|
||||
}
|
||||
@@ -0,0 +1,517 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for text.module.
|
||||
*/
|
||||
|
||||
class TextFieldTestCase extends DrupalWebTestCase {
|
||||
protected $instance;
|
||||
protected $admin_user;
|
||||
protected $web_user;
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Text field',
|
||||
'description' => "Test the creation of text fields.",
|
||||
'group' => 'Field types'
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('field_test');
|
||||
|
||||
$this->admin_user = $this->drupalCreateUser(array('administer filters'));
|
||||
$this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content'));
|
||||
$this->drupalLogin($this->web_user);
|
||||
}
|
||||
|
||||
// Test fields.
|
||||
|
||||
/**
|
||||
* Test text field validation.
|
||||
*/
|
||||
function testTextFieldValidation() {
|
||||
// Create a field with settings to validate.
|
||||
$max_length = 3;
|
||||
$this->field = array(
|
||||
'field_name' => drupal_strtolower($this->randomName()),
|
||||
'type' => 'text',
|
||||
'settings' => array(
|
||||
'max_length' => $max_length,
|
||||
)
|
||||
);
|
||||
field_create_field($this->field);
|
||||
$this->instance = array(
|
||||
'field_name' => $this->field['field_name'],
|
||||
'entity_type' => 'test_entity',
|
||||
'bundle' => 'test_bundle',
|
||||
'widget' => array(
|
||||
'type' => 'text_textfield',
|
||||
),
|
||||
'display' => array(
|
||||
'default' => array(
|
||||
'type' => 'text_default',
|
||||
),
|
||||
),
|
||||
);
|
||||
field_create_instance($this->instance);
|
||||
// Test valid and invalid values with field_attach_validate().
|
||||
$entity = field_test_create_stub_entity();
|
||||
$langcode = LANGUAGE_NONE;
|
||||
for ($i = 0; $i <= $max_length + 2; $i++) {
|
||||
$entity->{$this->field['field_name']}[$langcode][0]['value'] = str_repeat('x', $i);
|
||||
try {
|
||||
field_attach_validate('test_entity', $entity);
|
||||
$this->assertTrue($i <= $max_length, "Length $i does not cause validation error when max_length is $max_length");
|
||||
}
|
||||
catch (FieldValidationException $e) {
|
||||
$this->assertTrue($i > $max_length, "Length $i causes validation error when max_length is $max_length");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test widgets.
|
||||
*/
|
||||
function testTextfieldWidgets() {
|
||||
$this->_testTextfieldWidgets('text', 'text_textfield');
|
||||
$this->_testTextfieldWidgets('text_long', 'text_textarea');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for testTextfieldWidgets().
|
||||
*/
|
||||
function _testTextfieldWidgets($field_type, $widget_type) {
|
||||
// Setup a field and instance
|
||||
$entity_type = 'test_entity';
|
||||
$this->field_name = drupal_strtolower($this->randomName());
|
||||
$this->field = array('field_name' => $this->field_name, 'type' => $field_type);
|
||||
field_create_field($this->field);
|
||||
$this->instance = array(
|
||||
'field_name' => $this->field_name,
|
||||
'entity_type' => 'test_entity',
|
||||
'bundle' => 'test_bundle',
|
||||
'label' => $this->randomName() . '_label',
|
||||
'settings' => array(
|
||||
'text_processing' => TRUE,
|
||||
),
|
||||
'widget' => array(
|
||||
'type' => $widget_type,
|
||||
),
|
||||
'display' => array(
|
||||
'full' => array(
|
||||
'type' => 'text_default',
|
||||
),
|
||||
),
|
||||
);
|
||||
field_create_instance($this->instance);
|
||||
$langcode = LANGUAGE_NONE;
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('test-entity/add/test-bundle');
|
||||
$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();
|
||||
$edit = array(
|
||||
"{$this->field_name}[$langcode][0][value]" => $value,
|
||||
);
|
||||
$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)), '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->assertText($value, 'Filtered tags are not displayed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test widgets + 'formatted_text' setting.
|
||||
*/
|
||||
function testTextfieldWidgetsFormatted() {
|
||||
$this->_testTextfieldWidgetsFormatted('text', 'text_textfield');
|
||||
$this->_testTextfieldWidgetsFormatted('text_long', 'text_textarea');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for testTextfieldWidgetsFormatted().
|
||||
*/
|
||||
function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
|
||||
// Setup a field and instance
|
||||
$entity_type = 'test_entity';
|
||||
$this->field_name = drupal_strtolower($this->randomName());
|
||||
$this->field = array('field_name' => $this->field_name, 'type' => $field_type);
|
||||
field_create_field($this->field);
|
||||
$this->instance = array(
|
||||
'field_name' => $this->field_name,
|
||||
'entity_type' => 'test_entity',
|
||||
'bundle' => 'test_bundle',
|
||||
'label' => $this->randomName() . '_label',
|
||||
'settings' => array(
|
||||
'text_processing' => TRUE,
|
||||
),
|
||||
'widget' => array(
|
||||
'type' => $widget_type,
|
||||
),
|
||||
'display' => array(
|
||||
'full' => array(
|
||||
'type' => 'text_default',
|
||||
),
|
||||
),
|
||||
);
|
||||
field_create_instance($this->instance);
|
||||
$langcode = LANGUAGE_NONE;
|
||||
|
||||
// Disable all text formats besides the plain text fallback format.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
foreach (filter_formats() as $format) {
|
||||
if ($format->format != filter_fallback_format()) {
|
||||
$this->drupalPost('admin/config/content/formats/' . $format->format . '/disable', array(), t('Disable'));
|
||||
}
|
||||
}
|
||||
$this->drupalLogin($this->web_user);
|
||||
|
||||
// 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]", '', '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>';
|
||||
$edit = array(
|
||||
"{$this->field_name}[$langcode][0][value]" => $value,
|
||||
);
|
||||
$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)), '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, '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.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
$edit = array(
|
||||
'format' => drupal_strtolower($this->randomName()),
|
||||
'name' => $this->randomName(),
|
||||
);
|
||||
$this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
|
||||
filter_formats_reset();
|
||||
$this->checkPermissions(array(), TRUE);
|
||||
$format = filter_format_load($edit['format']);
|
||||
$format_id = $format->format;
|
||||
$permission = filter_permission_name($format);
|
||||
$rid = max(array_keys($this->web_user->roles));
|
||||
user_role_grant_permissions($rid, array($permission));
|
||||
$this->drupalLogin($this->web_user);
|
||||
|
||||
// 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, '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)), '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, 'Value is displayed unfiltered');
|
||||
}
|
||||
}
|
||||
|
||||
class TextSummaryTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Text summary',
|
||||
'description' => 'Test text_summary() with different strings and lengths.',
|
||||
'group' => 'Field types',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->article_creator = $this->drupalCreateUser(array('create article content', 'edit own article content'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests an edge case where the first sentence is a question and
|
||||
* subsequent sentences are not. This edge case is documented at
|
||||
* http://drupal.org/node/180425.
|
||||
*/
|
||||
function testFirstSentenceQuestion() {
|
||||
$text = 'A question? A sentence. Another sentence.';
|
||||
$expected = 'A question? A sentence.';
|
||||
$this->callTextSummary($text, $expected, NULL, 30);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test summary with long example.
|
||||
*/
|
||||
function testLongSentence() {
|
||||
$text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' . // 125
|
||||
'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' . // 108
|
||||
'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ' . // 103
|
||||
'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; // 110
|
||||
$expected = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' .
|
||||
'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' .
|
||||
'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.';
|
||||
// First three sentences add up to: 336, so add one for space and then 3 to get half-way into next word.
|
||||
$this->callTextSummary($text, $expected, NULL, 340);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test various summary length edge cases.
|
||||
*/
|
||||
function testLength() {
|
||||
// This string tests a number of edge cases.
|
||||
$text = "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>";
|
||||
|
||||
// The summaries we expect text_summary() to return when $size is the index
|
||||
// of each array item.
|
||||
// Using no text format:
|
||||
$expected = array(
|
||||
"<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
|
||||
"<",
|
||||
"<p",
|
||||
"<p>",
|
||||
"<p>\n",
|
||||
"<p>\nH",
|
||||
"<p>\nHi",
|
||||
"<p>\nHi\n",
|
||||
"<p>\nHi\n<",
|
||||
"<p>\nHi\n</",
|
||||
"<p>\nHi\n</p",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
|
||||
"<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
|
||||
"<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
|
||||
);
|
||||
|
||||
// And using a text format WITH the line-break and htmlcorrector filters.
|
||||
$expected_lb = array(
|
||||
"<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
|
||||
"",
|
||||
"<p></p>",
|
||||
"<p></p>",
|
||||
"<p></p>",
|
||||
"<p></p>",
|
||||
"<p></p>",
|
||||
"<p>\nHi</p>",
|
||||
"<p>\nHi</p>",
|
||||
"<p>\nHi</p>",
|
||||
"<p>\nHi</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>",
|
||||
"<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
|
||||
"<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
|
||||
"<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
|
||||
);
|
||||
|
||||
// Test text_summary() for different sizes.
|
||||
for ($i = 0; $i <= 37; $i++) {
|
||||
$this->callTextSummary($text, $expected[$i], NULL, $i);
|
||||
$this->callTextSummary($text, $expected_lb[$i], 'plain_text', $i);
|
||||
$this->callTextSummary($text, $expected_lb[$i], 'filtered_html', $i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls text_summary() and asserts that the expected teaser is returned.
|
||||
*/
|
||||
function callTextSummary($text, $expected, $format = NULL, $size = NULL) {
|
||||
$summary = text_summary($text, $format, $size);
|
||||
$this->assertIdentical($summary, $expected, format_string('Generated summary "@summary" matches expected "@expected".', array('@summary' => $summary, '@expected' => $expected)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test sending only summary.
|
||||
*/
|
||||
function testOnlyTextSummary() {
|
||||
// Login as article creator.
|
||||
$this->drupalLogin($this->article_creator);
|
||||
// Create article with summary but empty body.
|
||||
$summary = $this->randomName();
|
||||
$edit = array(
|
||||
"title" => $this->randomName(),
|
||||
"body[und][0][summary]" => $summary,
|
||||
);
|
||||
$this->drupalPost('node/add/article', $edit, t('Save'));
|
||||
$node = $this->drupalGetNodeByTitle($edit['title']);
|
||||
|
||||
$this->assertIdentical($node->body['und'][0]['summary'], $summary, 'Article with with summary and no body has been submitted.');
|
||||
}
|
||||
}
|
||||
|
||||
class TextTranslationTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Text translation',
|
||||
'description' => 'Check if the text field is correctly prepared for translation.',
|
||||
'group' => 'Field types',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('locale', 'translation');
|
||||
|
||||
$full_html_format = filter_format_load('full_html');
|
||||
$this->format = $full_html_format->format;
|
||||
$this->admin = $this->drupalCreateUser(array(
|
||||
'administer languages',
|
||||
'administer content types',
|
||||
'access administration pages',
|
||||
'bypass node access',
|
||||
filter_permission_name($full_html_format),
|
||||
));
|
||||
$this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content'));
|
||||
|
||||
// Enable an additional language.
|
||||
$this->drupalLogin($this->admin);
|
||||
$edit = array('langcode' => 'fr');
|
||||
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
|
||||
// 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')), 'Article content type has been updated.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a plaintext textfield widget is correctly populated.
|
||||
*/
|
||||
function testTextField() {
|
||||
// Disable text processing for body.
|
||||
$edit = array('instance[settings][text_processing]' => 0);
|
||||
$this->drupalPost('admin/structure/types/manage/article/fields/body', $edit, t('Save settings'));
|
||||
|
||||
// Login as translator.
|
||||
$this->drupalLogin($this->translator);
|
||||
|
||||
// Create content.
|
||||
$langcode = LANGUAGE_NONE;
|
||||
$body = $this->randomName();
|
||||
$edit = array(
|
||||
"title" => $this->randomName(),
|
||||
"language" => 'en',
|
||||
"body[$langcode][0][value]" => $body,
|
||||
);
|
||||
|
||||
// Translate the article in french.
|
||||
$this->drupalPost('node/add/article', $edit, t('Save'));
|
||||
$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, 'The textfield widget is populated.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that user that does not have access the field format cannot see the
|
||||
* source value when creating a translation.
|
||||
*/
|
||||
function testTextFieldFormatted() {
|
||||
// Make node body multiple.
|
||||
$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'), 'Body field cardinality set to multiple.');
|
||||
|
||||
$body = array(
|
||||
$this->randomName(),
|
||||
$this->randomName(),
|
||||
);
|
||||
|
||||
// Create an article with the first body input format set to "Full HTML".
|
||||
$title = $this->randomName();
|
||||
$edit = array(
|
||||
'title' => $title,
|
||||
'language' => 'en',
|
||||
);
|
||||
$this->drupalPost('node/add/article', $edit, t('Save'));
|
||||
|
||||
// Populate the body field: the first item gets the "Full HTML" input
|
||||
// format, the second one "Filtered HTML".
|
||||
$formats = array('full_html', 'filtered_html');
|
||||
$langcode = LANGUAGE_NONE;
|
||||
foreach ($body as $delta => $value) {
|
||||
$edit = array(
|
||||
"body[$langcode][$delta][value]" => $value,
|
||||
"body[$langcode][$delta][format]" => array_shift($formats),
|
||||
);
|
||||
$this->drupalPost('node/1/edit', $edit, t('Save'));
|
||||
$this->assertText($body[$delta], format_string('The body field with delta @delta has been saved.', array('@delta' => $delta)));
|
||||
}
|
||||
|
||||
// Login as translator.
|
||||
$this->drupalLogin($this->translator);
|
||||
|
||||
// Translate the article in french.
|
||||
$node = $this->drupalGetNodeByTitle($title);
|
||||
$this->drupalGet("node/$node->nid/translate");
|
||||
$this->clickLink(t('add translation'));
|
||||
$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)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user