diff --git a/modules/media_wysiwyg/includes/media_wysiwyg.filter.inc b/modules/media_wysiwyg/includes/media_wysiwyg.filter.inc index 1ac35c26ba2bf3da4b2a3a3fdb9466097ea01919..1436a52808e7011c3a2630d8bd3ce91fc6d282c0 100644 --- a/modules/media_wysiwyg/includes/media_wysiwyg.filter.inc +++ b/modules/media_wysiwyg/includes/media_wysiwyg.filter.inc @@ -388,31 +388,51 @@ function media_wysiwyg_token_to_markup($match, $wysiwyg = FALSE, $langcode = NUL } /** - * Parse the field array from the collapsed AJAX string. + * Parse the 'fields' entry of $tag_info into structured, sanitized fields data. + * + * The keys of the fields array are the string equivalent of accessing the + * field's value, e.g. 'field_file_image_alt_text[und][0][value]' and the value + * is the actual field value. These parts are turned into sanitized fields data + * arrays with the full hierarchy of language, deltas, data column and finally + * value. + * + * Only configured or programmed fields present in the site's installation is + * parsed and returned. + * + * @param array $tag_info + * Media token as PHP array equivalent. + * + * @return array + * An array of fields with sanitized field data structures. */ -function media_wysiwyg_filter_field_parser($tag_info) { +function media_wysiwyg_filter_field_parser(array $tag_info) { $fields = array(); if (isset($tag_info['fields'])) { - // Field names that end in [format] are associated with long-text fields that may have HTML Entities. - // Those values will need to be URLDecoded as well as HTMLDecoded. + // Field value reference candidates (keys) that end in [format] are + // associated with long-text fields that may have HTML Entities. Those + // values will need to be URLDecoded as well as HTMLDecoded. $url_encoded_fields = array(); - foreach($tag_info['fields'] as $field_name => $field_value) { - if (preg_match('/\[format\]$/', $field_name) > 0){ - $url_encoded_fields[] = preg_replace('/\[format\]$/', '[value]', $field_name); + foreach ($tag_info['fields'] as $candidate => $field_value) { + if (preg_match('/\[format\]$/', $candidate) > 0) { + $url_encoded_fields[] = preg_replace('/\[format\]$/', '[value]', $candidate); } } - foreach($tag_info['fields'] as $field_name => $field_value) { - if (strpos($field_name, 'field_') === 0) { - $parsed_field = explode('[', str_replace(']', '', $field_name)); - $ref = &$fields; + foreach ($tag_info['fields'] as $candidate => $field_value) { + if (strpos($candidate, 'field_') === 0) { + $parsed_field = explode('[', str_replace(']', '', $candidate)); + // We are garuanteed to have a value in $parsed_field[0]. + $info = field_info_field($parsed_field[0]); + if (!$info) { + // Not an existing/configured field. + continue; + } // Certain types of fields, because of differences in markup, end up // here with incomplete arrays. Make a best effort to support as many // types of fields as possible. // Single-value select lists show up here with only 2 array items. if (count($parsed_field) == 2) { - $info = field_info_field($parsed_field[0]); if ($info && !empty($info['columns'])) { // Assume single-value. $parsed_field[] = 0; @@ -422,21 +442,20 @@ function media_wysiwyg_filter_field_parser($tag_info) { } // Multi-value select lists show up here with 3 array items. elseif (count($parsed_field) == 3 && (empty($parsed_field[2]) || is_numeric($parsed_field[2]))) { - $info = field_info_field($parsed_field[0]); // They just need the value column. $parsed_field[3] = key($info['columns']); } // Each key of the field needs to be the child of the previous key. + $ref = &$fields; foreach ($parsed_field as $key) { if (!isset($ref[$key])) { $ref[$key] = array(); } $ref = &$ref[$key]; } - // The value should be set at the deepest level. - if (in_array($field_name, $url_encoded_fields)){ + if (in_array($candidate, $url_encoded_fields)) { // Fields that use rich-text markup will be urlencoded. $ref = urldecode(decode_entities($field_value)); } @@ -446,6 +465,16 @@ function media_wysiwyg_filter_field_parser($tag_info) { } } } + // Strip fields for empty values. This is necessary to do post parsing of + // all field entries as they may refer to the same field several times. + foreach ($fields as $field_name => $field_languages) { + $info = field_info_field($field_name); + if (isset($field_languages) && is_array($field_languages)) { + foreach ($field_languages as $lang => $items) { + $fields[$field_name][$lang] = _field_filter_items($info, $items); + } + } + } } return $fields; } diff --git a/modules/media_wysiwyg/tests/media_wysiwyg.macro.test b/modules/media_wysiwyg/tests/media_wysiwyg.macro.test index 82af18affac13f03783fa11878825387d9220790..b3407fe38a5ddcda12b980841e758f08b863ad3d 100644 --- a/modules/media_wysiwyg/tests/media_wysiwyg.macro.test +++ b/modules/media_wysiwyg/tests/media_wysiwyg.macro.test @@ -6,28 +6,25 @@ */ /** - * Defines media macro test cases. + * Base class for testing rendered wysiwyg macros. */ -class MediaWYSIWYGWYSIWYGOverridesTest extends MediaWYSIWYGTestHelper { +abstract class MediaWYSIWYGMacroTestHelper extends MediaWYSIWYGTestHelper { /** - * Provide test information. + * Common setup routines for rendered media macros. */ - public static function getInfo() { - return array( - 'name' => t('Media WYSIWYG WYSIWYG overrides'), - 'description' => t('Tests that overridden attributes display correct.'), - 'group' => t('Media WYSIWYG'), - 'dependencies' => array('token'), - ); - } - public function setUp() { - parent::setUp('token'); + parent::setUp(array('field_ui', 'token')); // Create and log in a user. - $account = $this->drupalCreateUser(array('create article content', 'administer filters', 'use text format filtered_html')); - $this->drupalLogin($account); + $this->admin_user = $this->drupalCreateUser(array( + 'administer file types', + 'administer fields', + 'administer filters', + 'create article content', + 'use text format filtered_html', + )); + $this->drupalLogin($this->admin_user); // Enable the media filter for full html. $edit = array( @@ -37,6 +34,74 @@ class MediaWYSIWYGWYSIWYGOverridesTest extends MediaWYSIWYGTestHelper { $this->drupalPost('admin/config/content/formats/filtered_html', $edit, t('Save configuration')); } +} + +/** + * Defines rendered media macros test cases. + */ +class MediaWYSIWYGRenderMacrosTest extends MediaWYSIWYGMacroTestHelper { + + /** + * Test information. + */ + public static function getInfo() { + return array( + 'name' => t('Media WYSIWYG Rendered Macros test'), + 'description' => t('Test that rendered macros are displayed correctly.'), + 'group' => t('Media WYSIWYG'), + 'dependencies' => array('token'), + ); + } + + /** + * Test that displayed fields on file entity are rendered correctly. + */ + public function testEmptyField() { + // Add a field as part of the rendered macro. + $edit = array( + 'fields[field_file_image_title_text][type]' => 'text_default', + ); + $this->drupalPost('admin/structure/file-types/manage/image/display/preview', $edit, t('Save')); + + // Assert that fields that are enabled in display settings for macro are NOT + // rendered if empty. + $files = $this->drupalGetTestFiles('image'); + $attributes = array( + 'alt' => $this->randomName(), + 'title' => '', + ); + $fields = array( + 'field_file_image_alt_text[und][0][value]' => $attributes['alt'], + 'field_file_image_title_text[und][0][value]' => $attributes['title'], + ); + $files[0]->field_file_image_alt_text[LANGUAGE_NONE][0]['value'] = $attributes['alt']; + $files[0]->field_file_image_title_text[LANGUAGE_NONE][0]['value'] = $attributes['title']; + $file = file_save($files[0]); + $nid = $this->createNode($file->fid, $attributes, $fields); + $this->drupalGet('node/' . $nid); + // Assert that the empty field isn't rendered. + $this->assertNoPattern('|
]*field-name-field-file-image-title-text|', t('Displayed text field with empty value not rendered.')); + } + +} + +/** + * Defines media macro override test cases. + */ +class MediaWYSIWYGWYSIWYGOverridesTest extends MediaWYSIWYGMacroTestHelper { + + /** + * Provide test information. + */ + public static function getInfo() { + return array( + 'name' => t('Media WYSIWYG WYSIWYG overrides'), + 'description' => t('Tests that overridden attributes display correct.'), + 'group' => t('Media WYSIWYG'), + 'dependencies' => array('token'), + ); + } + /** * Test image media overrides. */