diff --git a/feeds.info b/feeds.info index ec2ffda..eb7387b 100644 --- a/feeds.info +++ b/feeds.info @@ -41,6 +41,7 @@ files[] = tests/feeds_mapper_profile.test files[] = tests/feeds_mapper.test files[] = tests/feeds_mapper_config.test files[] = tests/feeds_fetcher_file.test +files[] = tests/feeds_mapper_format_config.test files[] = tests/feeds_fetcher_http.test files[] = tests/feeds_processor_entity.test files[] = tests/feeds_processor_node.test diff --git a/mappers/text.inc b/mappers/text.inc index 48d9d7f..6fb50bf 100644 --- a/mappers/text.inc +++ b/mappers/text.inc @@ -36,17 +36,26 @@ function text_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam ); } } + + if (!empty($instance['settings']['text_processing'])) { + $targets[$name]['summary_callback'] = 'text_feeds_summary_callback'; + $targets[$name]['form_callback'] = 'text_feeds_form_callback'; + } } } /** * Callback for mapping text fields. */ -function text_feeds_set_target($source, $entity, $target, array $values) { +function text_feeds_set_target($source, $entity, $target, array $values, $mapping = array()) { list($field_name, $column) = explode(':', $target . ':value'); if ($column === 'value' && isset($source->importer->processor->config['input_format'])) { $format = $source->importer->processor->config['input_format']; + // Add in default values. + $mapping += array( + 'format' => $format, + ); } $field = isset($entity->$field_name) ? $entity->$field_name : array('und' => array()); @@ -63,8 +72,8 @@ function text_feeds_set_target($source, $entity, $target, array $values) { $field['und'][$delta][$column] = (string) $value; - if (isset($format)) { - $field['und'][$delta]['format'] = $format; + if (isset($mapping['format'])) { + $field['und'][$delta]['format'] = $mapping['format']; } } @@ -73,3 +82,58 @@ function text_feeds_set_target($source, $entity, $target, array $values) { $entity->$field_name = $field; } + +/** + * Summary callback for text field targets. + * + * Displays which text format will be used for the text field target. + * + * @see text_feeds_processor_targets_alter() + * @see text_feeds_form_callback() + */ +function text_feeds_summary_callback($mapping, $target, $form, $form_state) { + global $user; + $formats = filter_formats($user); + + // Processor-wide input format setting. + $importer = feeds_importer_load($form['#importer']); + $default_format = isset($importer->processor->config['input_format']) ? $importer->processor->config['input_format'] : filter_fallback_format(); + $mapping += array( + 'format' => $default_format, + ); + + return t('Text format: %format', array('%format' => $formats[$mapping['format']]->name)); +} + +/** + * Form callback for text field targets. + * + * Allows to select a text format for the text field target. + * + * @see text_feeds_processor_targets_alter() + * @see text_feeds_summary_callback() + */ +function text_feeds_form_callback($mapping, $target, $form, $form_state) { + global $user; + $formats_options = array(); + $formats = filter_formats($user); + foreach ($formats as $id => $format) { + $formats_options[$id] = $format->name; + } + + // Processor-wide text format setting. + $importer = feeds_importer_load($form['#importer']); + $default_format = isset($importer->processor->config['input_format']) ? $importer->processor->config['input_format'] : filter_fallback_format(); + $mapping += array( + 'format' => $default_format, + ); + + $config['format'] = array( + '#type' => 'select', + '#title' => t('Text format'), + '#options' => $formats_options, + '#default_value' => $mapping['format'], + ); + + return $config; +} diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc index 6666276..e0b072c 100755 --- a/plugins/FeedsProcessor.inc +++ b/plugins/FeedsProcessor.inc @@ -663,7 +663,7 @@ abstract class FeedsProcessor extends FeedsPlugin { $form['input_format'] = array( '#type' => 'select', '#title' => t('Text format'), - '#description' => t('Select the input format for the body field of the nodes to be created.'), + '#description' => t('Select the default input format for the body field of the nodes to be created.'), '#options' => $format_options, '#default_value' => isset($this->config['input_format']) ? $this->config['input_format'] : 'plain_text', '#required' => TRUE, diff --git a/plugins/FeedsTermProcessor.inc b/plugins/FeedsTermProcessor.inc index b336096..a4843b8 100644 --- a/plugins/FeedsTermProcessor.inc +++ b/plugins/FeedsTermProcessor.inc @@ -34,7 +34,6 @@ class FeedsTermProcessor extends FeedsProcessor { $term = new stdClass(); $term->vid = $vocabulary->vid; $term->vocabulary_machine_name = $vocabulary->machine_name; - $term->format = isset($this->config['input_format']) ? $this->config['input_format'] : filter_fallback_format(); return $term; } @@ -86,7 +85,7 @@ class FeedsTermProcessor extends FeedsProcessor { /** * Override setTargetElement to operate on a target item that is a taxonomy term. */ - public function setTargetElement(FeedsSource $source, $target_term, $target_element, $value) { + public function setTargetElement(FeedsSource $source, $target_term, $target_element, $value, $mapping = array()) { switch ($target_element) { case 'parent': if (!empty($value)) { @@ -126,6 +125,16 @@ class FeedsTermProcessor extends FeedsProcessor { } $target_term->weight = $weight; break; + case 'description': + if (isset($mapping['format'])) { + $target_term->format = $mapping['format']; + } + elseif (isset($this->config['input_format'])) { + $target_term->format = $this->config['input_format']; + } + else { + $target_term->format = filter_fallback_format(); + } default: parent::setTargetElement($source, $target_term, $target_element, $value); break; @@ -161,6 +170,8 @@ class FeedsTermProcessor extends FeedsProcessor { 'description' => array( 'name' => t('Term description'), 'description' => t('Description of the taxonomy term.'), + 'summary_callback' => 'text_feeds_summary_callback', + 'form_callback' => 'text_feeds_form_callback', ), ); diff --git a/tests/feeds_mapper.test b/tests/feeds_mapper.test index 81665b6..492af89 100644 --- a/tests/feeds_mapper.test +++ b/tests/feeds_mapper.test @@ -22,10 +22,13 @@ class FeedsMapperTestCase extends FeedsWebTestCase { 'file' => 'file_generic', 'image' => 'image_image', 'link_field' => 'link_field', + 'list_text' => 'options_select', 'number_float' => 'number', 'number_integer' => 'number', 'nodereference' => 'nodereference_select', 'text' => 'text_textfield', + 'text_long' => 'text_textarea', + 'text_with_summary' => 'text_textarea_with_summary', 'userreference' => 'userreference_select', ); diff --git a/tests/feeds_mapper_format_config.test b/tests/feeds_mapper_format_config.test new file mode 100644 index 0000000..4630293 --- /dev/null +++ b/tests/feeds_mapper_format_config.test @@ -0,0 +1,244 @@ + 'Mapper: Text format mapping configuration', + 'description' => 'Test text format mapping configuration for text fields.', + 'group' => 'Feeds', + ); + } + + public function setUp() { + parent::setUp(array('list', 'taxonomy')); + } + + /** + * Basic test for setting mapping configuration. + */ + public function test() { + // Create content type with three fields. Two that support text formats + // and one that doesn't. + $typename = $this->createContentType(array(), array( + 'alpha' => array( + 'type' => 'text', + 'instance_settings' => array( + 'instance[settings][text_processing]' => 1, + ), + ), + 'beta' => array( + 'type' => 'text_long', + 'instance_settings' => array( + 'instance[settings][text_processing]' => 1, + ), + ), + 'gamma' => array( + 'type' => 'text', + 'instance_settings' => array( + 'instance[settings][text_processing]' => 0, + ), + ), + )); + + // Create a new filter format. + $format = drupal_strtolower($this->randomName()); + $edit = array( + 'format' => $format, + 'name' => $this->randomName(), + // Authenticated users. + 'roles[2]' => TRUE, + ); + $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration')); + + // Create and configure importer. + $this->createImporterConfiguration(); + $this->setSettings('syndication', NULL, array( + 'content_type' => '', + 'import_period' => FEEDS_SCHEDULE_NEVER, + )); + $this->setPlugin('syndication', 'FeedsFileFetcher'); + $this->setPlugin('syndication', 'FeedsCSVParser'); + $this->setSettings('syndication', 'FeedsNodeProcessor', array('bundle' => $typename)); + $this->addMappings('syndication', array( + 0 => array( + 'source' => 'title', + 'target' => 'title', + ), + 1 => array( + 'source' => 'created', + 'target' => 'created', + ), + 2 => array( + 'source' => 'body', + 'target' => 'body', + 'format' => $format, + ), + 3 => array( + 'source' => 'alpha', + 'target' => 'field_alpha', + 'format' => $format, + ), + 4 => array( + 'source' => 'beta', + 'target' => 'field_beta', + 'format' => $format, + ), + 5 => array( + 'source' => 'gamma', + 'target' => 'field_gamma', + ), + )); + // Assert that for the gamma field no format can be chosen. + $this->assertNoText('Text format: Plain text'); + + // Import csv file. + $this->importFile('syndication', $this->absolutePath() . '/tests/feeds/content.csv'); + $this->assertText('Created 2 nodes'); + + // Assert that fields body, alpha and beta got the expected text format. + $node = node_load(1); + $this->assertEqual($format, $node->body[LANGUAGE_NONE][0]['format'], 'The body field got the expected format.'); + $this->assertEqual($format, $node->field_alpha[LANGUAGE_NONE][0]['format'], 'The alpha field got the expected format.'); + $this->assertEqual($format, $node->field_beta[LANGUAGE_NONE][0]['format'], 'The beta field got the expected format.'); + } + + /** + * Tests if an user with limited privileges can only choose the text format + * it has access to. + */ + public function testWithLimitedPrivileges() { + // Create content type with a field that uses a text format. + $typename = $this->createContentType(array(), array( + 'alpha' => array( + 'type' => 'text', + 'instance_settings' => array( + 'instance[settings][text_processing]' => 1, + ), + ), + )); + + // Create a new user with limited privileges. + $account = $this->drupalCreateUser(array('administer feeds')); + + // Create filter format the user may use. + $format1 = drupal_strtolower($this->randomName()); + $edit1 = array( + 'format' => $format1, + 'name' => $this->randomName(), + // Authenticated users. + 'roles[2]' => TRUE, + ); + $this->drupalPost('admin/config/content/formats/add', $edit1, t('Save configuration')); + + // Create filter format the user may NOT use. + $rid = $this->drupalCreateRole(array()); + $format2 = drupal_strtolower($this->randomName()); + $edit2 = array( + 'format' => $format2, + 'name' => $this->randomName(), + 'roles[' . $rid . ']' => TRUE, + ); + $this->drupalPost('admin/config/content/formats/add', $edit2, t('Save configuration')); + + // Login as the user that may only use certain formats. + $this->drupalLogin($account); + + // Create importer and ensure the user can use the first format. + $this->createImporterConfiguration(); + $this->setSettings('syndication', NULL, array( + 'content_type' => '', + 'import_period' => FEEDS_SCHEDULE_NEVER, + )); + $this->setPlugin('syndication', 'FeedsFileFetcher'); + $this->setPlugin('syndication', 'FeedsCSVParser'); + $this->setSettings('syndication', 'FeedsNodeProcessor', array('bundle' => $typename)); + $this->addMappings('syndication', array( + 0 => array( + 'source' => 'alpha', + 'target' => 'field_alpha', + 'format' => $format1, + ), + )); + + // Check user can choose first, but not second format as an option. + $this->drupalPostAJAX(NULL, array(), 'mapping_settings_edit_0'); + $xpath = $this->constructFieldXpath('name', 'config[0][settings][format]'); + $fields = $this->xpath($xpath); + $field = reset($fields); + $format_options = $this->getAllOptions($field); + $format1_found = FALSE; + $format2_found = FALSE; + foreach ($format_options as $option) { + if ($option['value'] == $format1) { + $format1_found = TRUE; + } + if ($option['value'] == $format2) { + $format2_found = TRUE; + } + } + // Assert first format can be chosen. + $this->assertTrue($format1_found, format_string('Text format %format can be chosen.', array('%format' => $format1))); + // Assert second format can NOT be chosen. + $this->assertFalse($format2_found, format_string('Text format %format can NOT be chosen.', array('%format' => $format2))); + } + + /** + * Tests if text format can be set for taxonomy descriptions. + */ + public function testTaxonomyDescriptionTextFormat() { + // Create a vocabulary. + $edit = array( + 'name' => 'Tags', + 'machine_name' => 'tags', + ); + $this->drupalPost('admin/structure/taxonomy/add', $edit, 'Save'); + + // Create a new filter format. + $format = drupal_strtolower($this->randomName()); + $edit = array( + 'format' => $format, + 'name' => $this->randomName(), + // Authenticated users. + 'roles[2]' => TRUE, + ); + $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration')); + + // Create a taxonomy term importer. + $this->createImporterConfiguration(); + $this->setSettings('syndication', NULL, array( + 'content_type' => '', + 'import_period' => FEEDS_SCHEDULE_NEVER, + )); + $this->setPlugin('syndication', 'FeedsFileFetcher'); + $this->setPlugin('syndication', 'FeedsCSVParser'); + $this->setPlugin('syndication', 'FeedsTermProcessor'); + $this->setSettings('syndication', 'FeedsTermProcessor', array('bundle' => 'tags')); + $this->addMappings('syndication', array( + 0 => array( + 'source' => 'title', + 'target' => 'name', + ), + 1 => array( + 'source' => 'body', + 'target' => 'description', + 'format' => $format, + ), + )); + + // Import csv file. + $this->importFile('syndication', $this->absolutePath() . '/tests/feeds/content.csv'); + $this->assertText('Created 2 terms'); + + // Assert that the term description got the expected text format. + $term = taxonomy_term_load(1); + $this->assertEqual($format, $term->format, 'The taxonomy term got the expected format.'); + } +}