diff --git a/includes/form.inc b/includes/form.inc index f9cc3d2cf32498db32741bb5227b5e878692ef87..da1b03f243b654e9830bb252465659730fb81304 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -1752,6 +1752,79 @@ function form_process_radios($element) { return $element; } +/** + * Add input format selector to text elements with the #input_format property. + * + * The #input_format property should be the ID of an input format, found in + * {filter_formats}.format, which gets passed to filter_form(). + * + * If the property #input_format is set, the form element will be expanded into + * two separate form elements, one holding the content of the element, and the + * other holding the input format selector. The original element is shifted into + * a child element, but is otherwise unaltered, so that the format selector is + * at the same level as the text field which it affects. + * + * For example: + * @code + * // A simple textarea, such as a node body. + * $form['body'] = array( + * '#type' => 'textarea', + * '#title' => t('Body'), + * '#input_format' => isset($node->format) ? $node->format : FILTER_FORMAT_DEFAULT, + * ); + * @endcode + * + * Becomes: + * @code + * $form['body'] = array( + * // Type switches to 'markup', as we're only interested in submitting the child elements. + * '#type' => 'markup', + * // 'value' holds the original element. + * 'value' => array( + * '#type' => 'textarea', + * '#title' => t('Body'), + * '#parents' => array('body'), + * ), + * // 'format' holds the input format selector. + * 'format' => array( + * '#parents' => array('body_format'), + * ... + * ), + * ); + * @endcode + * + * And would result in: + * @code + * // Original, unaltered form element value. + * $form_state['values']['body'] = 'Example content'; + * // Chosen input format. + * $form_state['values']['body_format'] = 1; + * @endcode + * + * @see system_elements(), filter_form() + */ +function form_process_input_format($element) { + if (isset($element['#input_format'])) { + // Determine the form element parents and element name to use for the input + // format widget. This simulates the 'element' and 'element_format' pair of + // parents that filter_form() expects. + $element_parents = $element['#parents']; + $element_name = array_pop($element_parents); + $element_parents[] = $element_name . '_format'; + + // We need to break references, otherwise form_builder recurses infinitely. + $element['value'] = (array)$element; + $element['#type'] = 'markup'; + $element['format'] = filter_form($element['#input_format'], 1, $element_parents); + + // We need to clear the #input_format from the new child otherwise we + // would get into an infinite loop. + unset($element['value']['#input_format']); + $element['value']['#weight'] = 0; + } + return $element; +} + /** * Add AHAH information about a form element to the page to communicate with * javascript. If #ahah[path] is set on an element, this additional javascript is @@ -1792,6 +1865,8 @@ function form_process_ahah($element) { case 'select': $element['#ahah']['event'] = 'change'; break; + default: + return $element; } } diff --git a/modules/block/block.module b/modules/block/block.module index 46b6f13beb3a020d4e60f513eb86043cae0d08c8..9893cf6db80be74e2f09b9434a03719e916f0fca 100644 --- a/modules/block/block.module +++ b/modules/block/block.module @@ -315,24 +315,21 @@ function block_box_form($edit = array()) { '#type' => 'textarea', '#title' => t('Block body'), '#default_value' => $edit['body'], + '#input_format' => isset($edit['format']) ? $edit['format'] : FILTER_FORMAT_DEFAULT, '#rows' => 15, '#description' => t('The content of the block as shown to the user.'), '#weight' => -17, ); - if (!isset($edit['format'])) { - $edit['format'] = FILTER_FORMAT_DEFAULT; - } - $form['body_field']['format'] = filter_form($edit['format'], -16); return $form; } function block_box_save($edit, $delta) { - if (!filter_access($edit['format'])) { - $edit['format'] = FILTER_FORMAT_DEFAULT; + if (!filter_access($edit['body_format'])) { + $edit['body_format'] = FILTER_FORMAT_DEFAULT; } - db_query("UPDATE {boxes} SET body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['body'], $edit['info'], $edit['format'], $delta); + db_query("UPDATE {boxes} SET body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['body'], $edit['info'], $edit['body_format'], $delta); return TRUE; } diff --git a/modules/comment/comment.module b/modules/comment/comment.module index 4604104dc071569cfa4b30b854ef652dd7ad1d43..f1af2b608d776238aedfeff9d4ea42a7569dccfb 100644 --- a/modules/comment/comment.module +++ b/modules/comment/comment.module @@ -666,7 +666,7 @@ function comment_save($edit) { ); if ($edit['cid']) { // Update the comment in the database. - db_query("UPDATE {comments} SET status = %d, timestamp = %d, subject = '%s', comment = '%s', format = %d, uid = %d, name = '%s', mail = '%s', homepage = '%s' WHERE cid = %d", $edit['status'], $edit['timestamp'], $edit['subject'], $edit['comment'], $edit['format'], $edit['uid'], $edit['name'], $edit['mail'], $edit['homepage'], $edit['cid']); + db_query("UPDATE {comments} SET status = %d, timestamp = %d, subject = '%s', comment = '%s', format = %d, uid = %d, name = '%s', mail = '%s', homepage = '%s' WHERE cid = %d", $edit['status'], $edit['timestamp'], $edit['subject'], $edit['comment'], $edit['comment_format'], $edit['uid'], $edit['name'], $edit['mail'], $edit['homepage'], $edit['cid']); // Allow modules to respond to the updating of a comment. comment_invoke_comment($edit, 'update'); // Add an entry to the watchdog log. @@ -719,7 +719,7 @@ function comment_save($edit) { $edit['name'] = $user->name; } - db_query("INSERT INTO {comments} (nid, pid, uid, subject, comment, format, hostname, timestamp, status, thread, name, mail, homepage) VALUES (%d, %d, %d, '%s', '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s')", $edit['nid'], $edit['pid'], $edit['uid'], $edit['subject'], $edit['comment'], $edit['format'], ip_address(), $edit['timestamp'], $edit['status'], $thread, $edit['name'], $edit['mail'], $edit['homepage']); + db_query("INSERT INTO {comments} (nid, pid, uid, subject, comment, format, hostname, timestamp, status, thread, name, mail, homepage) VALUES (%d, %d, %d, '%s', '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s')", $edit['nid'], $edit['pid'], $edit['uid'], $edit['subject'], $edit['comment'], $edit['comment_format'], ip_address(), $edit['timestamp'], $edit['status'], $thread, $edit['name'], $edit['mail'], $edit['homepage']); $edit['cid'] = db_last_insert_id('comments', 'cid'); // Tell the other modules a new comment has been submitted. comment_invoke_comment($edit, 'insert'); @@ -1341,17 +1341,14 @@ function comment_form(&$form_state, $edit, $title = NULL) { $default = ''; } - $form['comment_filter']['comment'] = array( + $form['comment'] = array( '#type' => 'textarea', '#title' => t('Comment'), '#rows' => 15, '#default_value' => $default, + '#input_format' => isset($edit['format']) ? $edit['format'] : FILTER_FORMAT_DEFAULT, '#required' => TRUE, ); - if (!isset($edit['format'])) { - $edit['format'] = FILTER_FORMAT_DEFAULT; - } - $form['comment_filter']['format'] = filter_form($edit['format']); $form['cid'] = array( '#type' => 'value', @@ -1431,6 +1428,7 @@ function comment_form_add_preview($form, &$form_state) { if (!form_get_errors()) { _comment_form_submit($edit); $comment = (object)$edit; + $comment->format = $comment->comment_format; // Attach the user and time information. if (!empty($edit['author'])) { @@ -1523,7 +1521,7 @@ function _comment_form_submit(&$comment_values) { // 2) Strip out all HTML tags // 3) Convert entities back to plain-text. // Note: format is checked by check_markup(). - $comment_values['subject'] = trim(truncate_utf8(decode_entities(strip_tags(check_markup($comment_values['comment'], $comment_values['format']))), 29, TRUE)); + $comment_values['subject'] = trim(truncate_utf8(decode_entities(strip_tags(check_markup($comment_values['comment'], $comment_values['comment_format']))), 29, TRUE)); // Edge cases where the comment body is populated only by HTML tags will // require a default subject. if ($comment_values['subject'] == '') { @@ -1541,7 +1539,6 @@ function comment_form_submit($form, &$form_state) { $node = node_load($form_state['values']['nid']); $page = comment_new_page_count($node->comment_count, 1, $node); $form_state['redirect'] = array('node/' . $node->nid, $page, "comment-$cid"); - return; } } diff --git a/modules/filter/filter.test b/modules/filter/filter.test index e35b91aa1dfc373a587bec4dad70117b3c508ef9..7ee2977122d7e15321c420ad7addf72d0826c53d 100644 --- a/modules/filter/filter.test +++ b/modules/filter/filter.test @@ -104,7 +104,7 @@ class FilterAdminTestCase extends DrupalWebTestCase { $this->drupalLogin($web_user); $this->drupalGet('node/add/page'); - $this->assertFieldByName('format', $full, t('Full HTML filter accessible.')); + $this->assertFieldByName('body_format', $full, t('Full HTML filter accessible.')); // Use filtered HTML and see if it removes tags that arn't allowed. $body = $this->randomName(); @@ -113,7 +113,7 @@ class FilterAdminTestCase extends DrupalWebTestCase { $edit = array(); $edit['title'] = $this->randomName(); $edit['body'] = $body . '<random>' . $extra_text . '</random>'; - $edit['format'] = $filtered; + $edit['body_format'] = $filtered; $this->drupalPost('node/add/page', $edit, t('Save')); $this->assertRaw(t('Page %title has been created.', array('%title' => $edit['title'])), t('Filtered node created.')); diff --git a/modules/node/node.module b/modules/node/node.module index e32f6eaa3a0e8f4964ef4465f9292559dd88f29f..8f6031cf342982372af0ff2054ad2bc229608b32 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -858,6 +858,7 @@ function node_submit($node) { // module-provided 'teaser' form item). if (!isset($node->teaser)) { if (isset($node->body)) { + $node->format = (!empty($node->body_format) ? $node->body_format : FILTER_FORMAT_DEFAULT); $node->teaser = node_teaser($node->body, isset($node->format) ? $node->format : NULL); // Chop off the teaser from the body if needed. The teaser_include // property might not be set (eg. in Blog API postings), so only act on @@ -938,7 +939,6 @@ function node_save(&$node) { $node->changed = REQUEST_TIME; $node->timestamp = REQUEST_TIME; - $node->format = isset($node->format) ? $node->format : FILTER_FORMAT_DEFAULT; $update_node = TRUE; // Generate the node table query and the node_revisions table query. diff --git a/modules/node/node.pages.inc b/modules/node/node.pages.inc index 1fb688ab65f6cfb70ba95e2a9fd41c4fbd05362a..6f48a74aba7d69629231d66f7c5789a63145cc75 100644 --- a/modules/node/node.pages.inc +++ b/modules/node/node.pages.inc @@ -296,10 +296,9 @@ function node_body_field(&$node, $label, $word_count) { '#default_value' => $include ? $node->body : ($node->teaser . $node->body), '#rows' => 20, '#required' => ($word_count > 0), + '#input_format' => isset($node->format) ? $node->format : FILTER_FORMAT_DEFAULT, ); - $form['format'] = filter_form($node->format); - return $form; } diff --git a/modules/php/php.test b/modules/php/php.test index a046dc808832518b6a430166d36cfd82f04749e5..b127d5ba4e9080f698d5a7d2305c66b8c8f120a5 100644 --- a/modules/php/php.test +++ b/modules/php/php.test @@ -73,7 +73,7 @@ class PHPFitlerTestCase extends PHPTestCase { // Change filter to PHP filter and see that PHP code is evaluated. $edit = array(); - $edit['format'] = 3; + $edit['body_format'] = 3; $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save')); $this->assertRaw(t('Page %title has been updated.', array('%title' => $node->title)), t('PHP code filter turned on.')); @@ -113,6 +113,6 @@ class PHPAccessTestCase extends PHPTestCase { // Make sure that user doesn't have access to filter. $this->drupalGet('node/' . $node->nid . '/edit'); - $this->assertNoFieldByName('format', '3', t('Format not available.')); + $this->assertNoFieldByName('body_format', '3', t('Format not available.')); } } \ No newline at end of file diff --git a/modules/system/system.module b/modules/system/system.module index ef1735e1f87b67b124a1c6bf7425f49a32b040d9..68d2c24ad9f53b5cb75f7aeed76dcf72f7089f75 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -219,7 +219,7 @@ function system_elements() { '#size' => 60, '#maxlength' => 128, '#autocomplete_path' => FALSE, - '#process' => array('form_process_ahah'), + '#process' => array('form_process_input_format', 'form_process_ahah'), ); $type['password'] = array( @@ -239,7 +239,7 @@ function system_elements() { '#cols' => 60, '#rows' => 5, '#resizable' => TRUE, - '#process' => array('form_process_ahah'), + '#process' => array('form_process_input_format', 'form_process_ahah'), ); $type['radios'] = array(