=== added file 'mappers/content_taxonomy.inc' --- mappers/content_taxonomy.inc 1970-01-01 00:00:00 +0000 +++ mappers/content_taxonomy.inc 2009-11-25 07:38:29 +0000 @@ -0,0 +1,119 @@ + $field) { + if(in_array($field['type'], array('content_taxonomy'))) { + $name = isset($field['widget']['label']) ? $field['widget']['label'] : $field_name; + $targets[$field_name] = array( + 'name' => $name, + 'callback' => 'content_taxonomy_feeds_set_target', + 'description' => t('The CCK %name field of the node (!type).', array('%name' => $name, '!type' => $field['type'])), + ); + } + } + } +} + +/** + * Callback for mapping. Here is where the actual mapping happens. + * + * @param $node + * Reference to the node object we are working on. + * + * @param $vid + * The selected content_taxonomy CCK field. + * + * @param $terms + * Given terms as array. If a string is used, it is converted to an array + * using taxonomy_terms_parse_string($terms)->tids. + * + * @see taxonomy_terms_parse_string(). + * + */ +function content_taxonomy_feeds_set_target(&$node, $field_name, $terms) { + static $fields = array(); + + $field = content_fields($field_name, $node->type); + + // Parse string for multiple tags (comma separated) + if(is_string($terms)) { + $terms = split(',', $terms); + } + + // Return if there are no or empty terms. + if (!is_array($terms) || empty($terms)) { + return; + } + + $tags = $field['widget']['type'] == 'content_taxonomy_autocomplete' && $field['widget']['new_terms']; + $multiple = $field['widget']['multiple']; + + foreach ($terms as $k => $term_name) { + $term_name = trim($term_name); + if ($terms_found = content_taxonomy_get_term_by_name_vid($term_name, $field['vid'])) { + // If any terms are found add them to the field by found tid. + foreach($terms_found as $term_found) { + if(!is_array($node->$field_name)) $node->$field_name = array(); + array_push($node->$field_name, array('value' => $term_found['tid'])); + if ($multiple != 0 && count($node->$field_name) >= $multiple) { + // If the vocab is not for multiple tags break after the first hit. + break; + } + } + } else if ($tags) { + // If the field is configured for free tagging, create a new term + $edit = array('vid' => $field['vid'], 'name' => $term_name); + if ($field['widget']['extra_parent']) { + $edit['parent'] = $field['widget']['extra_parent']; + } + taxonomy_save_term($edit); + if (!is_array($node->$field_name)) { + $node->$field_name = array(); + } + array_push($node->$field_name, array('value' => $edit['tid'])); + } + if ($multiple != 0 && count($node->$field_name) >= $multiple) { + // If the vocab is not for multiple tags break after a first term has been added. + break; + } + } +} + +/** + * Try to map a string to an existing term by name and vocabulary id. + * + * Provides a case-insensitive and trimmed mapping, to maximize the + * likelihood of a successful match limited by a vocabulary id. + * + * @param $name + * Name of the term to search for. + * + * @param $vid + * The vocabulary's ID. + * + * @return + * An array of matching term objects. + */ +function content_taxonomy_get_term_by_name_vid($name, $vid) { + $db_result = db_query(db_rewrite_sql("SELECT t.tid, t.name FROM {term_data} t WHERE LOWER(t.name) = LOWER('%s') AND vid=%d", 't', 'tid'), trim($name), $vid); + $result = array(); + while ($term = db_fetch_array($db_result)) { + $result[] = $term; + } + return $result; +} \ No newline at end of file === added file 'tests/feeds/content-taxonomy.csv' --- tests/feeds/content-taxonomy.csv 1970-01-01 00:00:00 +0000 +++ tests/feeds/content-taxonomy.csv 2009-11-24 08:08:32 +0000 @@ -0,0 +1,2 @@ +"title","created","tags","categories","body" +"Lorem ipsum",1251936720,"lorem, ipsum, dolor, sit, amet","consectetuer,adipiscing","Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat." === added file 'tests/feeds_mapper_content_taxonomy.test' --- tests/feeds_mapper_content_taxonomy.test 1970-01-01 00:00:00 +0000 +++ tests/feeds_mapper_content_taxonomy.test 2009-11-25 07:37:56 +0000 @@ -0,0 +1,186 @@ +content mapper. + */ +class FeedsMapperContentTaxonomyTestCase extends FeedsMapperTestCase { + + public static function getInfo() { + return array( + 'name' => t('Mapper: Content Taxonomy'), + 'description' => t('Test Feeds Mapper support for Content Taxonomy CCK fields'), + 'group' => t('Feeds'), + ); + } + + /** + * Set up the + */ + public function setUp() { + // Call parent setup with the required module + parent::setUp( + 'feeds', 'feeds_ui', 'ctools', 'content', + 'taxonomy', 'content_taxonomy', 'content_taxonomy_autocomplete', 'content_taxonomy_options' + ); + + // Create user and login + $this->drupalLogin($this->drupalCreateUser( + array( + 'administer content types', + 'administer feeds', + 'administer nodes', + 'administer site configuration', + ) + )); + } + + /** + * Basic test loading a single entry CSV file. + */ + public function test() { + + // Create vocabularies + $vocabularies = array( + 'tags' => array( + 'name' => $this->randomName(), + 'tags' => true, + ), + 'categories' => array( + 'name' => $this->randomName(), + 'tags' => false, + ) + ); + foreach ($vocabularies as &$vocabulary) { + taxonomy_save_vocabulary($vocabulary); + } + + // Create terms + $terms = array( + array( + 'name' => 'foo', + 'vid' => $vocabularies['tags']['vid'], + 'weight' => 0, + ), + array( + 'name' => 'lorem', + 'vid' => $vocabularies['tags']['vid'], + 'weight' => 0, + ), + array( + 'name' => 'ipsum', + 'vid' => $vocabularies['tags']['vid'], + 'weight' => 0, + ), + array( + 'name' => 'bar', + 'vid' => $vocabularies['categories']['vid'], + 'weight' => 0, + ), + 'consectetuer' => array( + 'name' => 'consectetuer', + 'vid' => $vocabularies['categories']['vid'], + 'weight' => 0, + ), + ); + foreach ($terms as &$term) { + taxonomy_save_term($term); + } + + // Create content type + $typename = $this->createContentType(NULL, array( + 'tags' => array( + 'type' => 'content_taxonomy', + 'widget' => 'content_taxonomy_autocomplete', + 'settings' => array( + 'new_terms' => 'insert', + 'multiple' => '1', + 'vid' => $vocabularies['tags']['vid'], + ), + ), + 'categories' => array( + 'type' => 'content_taxonomy', + 'widget' => 'content_taxonomy_select', + 'settings' => array( + 'multiple' => '1', + 'vid' => $vocabularies['categories']['vid'], + ), + ), + )); + + // Create importer configuration + $this->createFeedConfiguration('Content Taxonomy CSV', 'csv'); // Create a default importer configuration + $this->setSettings('csv', NULL, array('content_type' => '','import_period' => FEEDS_SCHEDULE_NEVER,)); // Importer setting + $this->setPlugin('csv', 'FeedsFileFetcher'); //Set fetcher + $this->setPlugin('csv', 'FeedsCSVParser'); //Set parser + $this->setSettings('csv', 'FeedsNodeProcessor', array('content_type' => $typename)); // Processor settings + $this->addMappings('csv', array( + array( + 'source' => 'title', + 'target' => 'title' + ), + array( + 'source' => 'created', + 'target' => 'created' + ), + array( + 'source' => 'body', + 'target' => 'body' + ), + array( + 'source' => 'tags', + 'target' => 'field_tags' + ), + array( + 'source' => 'categories', + 'target' => 'field_categories' + ), + )); + + // Import CSV file. + $this->importFile('csv', $this->absolutePath() .'/tests/feeds/content-taxonomy.csv'); + $this->assertText('Created 1 '.$typename.' nodes.'); + + // Edit the imported node + $this->drupalGet('node/1/edit'); + + $this->assertCCKFieldValue('tags', array('lorem', 'ipsum', 'dolor', 'sit', 'amet')); + $this->assertCCKFieldValue('categories', $terms['consectetuer']['tid']); + } + + protected function selectFieldWidget($field_name, $field_type) { + if ($field_type == 'content_taxonomy') { + return 'content_taxonomy_select'; + } else { + return parent::selectFieldWidget($field_name, $field_type); + } + } + + protected function getFormFieldsNames($field_name, $index) { + switch ($field_name) { + case 'tags': + return array("field_{$field_name}[value]"); + case 'categories': + return array("field_{$field_name}[value][]"); + default: + return parent::getFormFieldsNames($field_name, $index); + } + } + + protected function getFormFieldsValues($field_name, $value) { + switch($field_name) { + case 'tags': + if (is_array($value)) { + // @todo sort tags by weight before joining + $value = join(', ', $value); + } + return array($value); + case 'categories': + // @todo return tid(s) from $value + default: + return parent::getFormFieldsValues($field_name, $value); + } + } +}