It seems that a lot of people learn the hard way (like I did) that if you export anything but "All content" from WordPress you end up with a file that is missing a lot of essential stuff, including the wp:tag and wp:category tags that define these terms.
There was a thread on another issue which seemed to indicate that functionality was added that would trigger the import of terms attached to items even if the wp:tag and wp:category tags are not included in the file.
This is the issue/comment as well as the related commit:
Issue #1565032: Categories or Tags not imported
Commit: Issue #1565032 by mikeryan: Create terms on-the-fly if necessary
I haven't fully examined the code, but reading the thread it sounds like that's what it's supposed to do. If this is correct, then I'm afraid something may have gone wrong along the way as it no longer seems to work.
A quick look at wordpress_item.inc in most recent -dev (paste below) makes me wonder if the tracking vars $tagField and $categoryField will always be NULL, and perhaps this is the source of the problem?
class WordPressItemSource extends MigrateSourceXML {
// ... a bunch of code omitted ...
/**
* Track the fields for the term references, so we can fix up if necessary
* in prepare().
*
* @var string
*/
protected $tagField = NULL;
protected $categoryField = NULL;
/**
* Set it up
*/
public function __construct(array $arguments = array()) {
// ...
if (module_exists('taxonomy')) {
// Map the source fields to the configured vocabularies
if ($arguments['tag_field']) {
$this->addFieldMapping($arguments['tag_field'], 'tag')
->sourceMigration($arguments['group_name'] . $arguments['tag_migration'])
->xpath('category[@domain="post_tag"]/@nicename');
$this->addFieldMapping($arguments['tag_field'] . ':source_type')
->defaultValue('tid');
}
else {
$this->addFieldMapping(NULL, 'tag');
}
if ($arguments['category_field']) {
$this->addFieldMapping($arguments['category_field'], 'category')
->sourceMigration($arguments['group_name'] . $arguments['category_migration'])
->xpath('category[@domain="category"]/@nicename');
$this->addFieldMapping($arguments['category_field'] . ':source_type')
->defaultValue('tid');
}
else {
$this->addFieldMapping(NULL, 'category');
}
}
// ...
}
// ...
public function prepare(stdClass $node, stdClass $row) {
// .. more code omitted ..
// If any term relationships were unresolved, create them the hard way
foreach (array('tag', 'category') as $term_type) {
$meta_field_name = $term_type . 'Field';
if ($this->$meta_field_name) {
$field_name = $this->$meta_field_name;
$value_name = $term_type . '_value';
// Shortcut - if the counts match, don't need to dig deeper
$field_values = field_get_items('node', $node, $field_name);
if (!empty($field_values)) {
$node_count = count($field_values);
}
else {
$node_count = 0;
}
if (isset($row->$term_type)) {
$row_count = count($row->$term_type);
}
else {
$row_count = 0;
}
if ($node_count != $row_count) {
$vid_field = $term_type . 'Vid';
$vid = $this->$vid_field;
// Get any terms already in the field
$done_terms = array();
if (is_array($field_values)) {
foreach ($field_values as $value_array) {
$terms = taxonomy_term_load_multiple($value_array);
foreach ($terms as $term) {
$done_terms[] = $term->name;
}
}
}
if (isset($row->$value_name)) {
$diff = array_diff($row->$value_name, $done_terms);
$field_language = field_language('node', $node, $field_name);
foreach ($diff as $new_term_name) {
// Let's see if the term already exists
$matches = taxonomy_term_load_multiple(array(),
array('name' => trim($new_term_name), 'vid' => $vid));
if ($matches) {
$node->{$field_name}[$field_language][] = array('tid' => key($matches));
}
else {
$term = new stdClass;
$term->name = $new_term_name;
$term->vid = $vid;
taxonomy_term_save($term);
$node->{$field_name}[$field_language][] = array('tid' => $term->tid);
}
}
}
}
}
}
}
// ...
}
If I'm wrong about the functionality this provides, then please change this to a feature request. It would be excellent to have.
Thanks!
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | wpm-screenshot.png | 29.9 KB | othermachines |
| #3 | import_terms_in_the-2416073-3.patch | 3.83 KB | mikeryan |
Comments
Comment #1
othermachines commentedAdding related issue.
Comment #2
mikeryanLooks like when cleaning up things as part of fixing the upgrade path, I missed the usage of $this->tagField and $this->categoryField in prepare(), and simply used the tag_field and category_field arguments directly in __construct(). Should be a simple fix...
Comment #3
mikeryanPlease give this patch a try.
Comment #4
othermachines commentedPatch in #3 works great, thanks!
Would it be proper to update the item count in the results table? I actually didn't realize right away that things were working because it was still showing 0 imported for tags and categories (see below).
Comment #6
mikeryanCommitted.
It wouldn't be too hard to manufacture map table entries so the Imported column showed the tags/categories that were imported as a side-effect of the node migration - but the total items (counted from the source) would still be zero and unprocessed would be negative, which would be even more confusing.
Comment #7
othermachines commentedYes, I was wondering if that might be confusing. What about just outputting a message? It took me 3 tries before I realized what was going on. Mind you I'm not always the brightest bulb... :-P
Thanks for the quick fix!