[Решено] Feeds: импорт таксономии с сохранением иерархии

Аватар пользователя Sun-fire Sun-fire 6 мая 2012 в 2:34

Суть проблемы.

При импорте значений поля нужно сохранить иерархию таксономии. Для обработки иерархии использую модуль Feeds tamper term hierarchy

Обнаружил следующий баг:

Например есть два термина:

Фурнитура (основной термин)
-Пуговица (подчиненный термин)

Если везде в импорте используется подчиненный термин - все импортируется корректно. Если хотя бы в одном материале подключается основной термин - начинаются сбои импорта: создается куча дублирующих "пар":

Фурнитура
-Пуговица

Которые не привязаны к нодам.

Кто уже сталкивался с подобным багом?

Комментарии

Аватар пользователя divined divined 28 августа 2012 в 10:19

Могу предложить свое решение:

Вот полу-рекурсивная функция на вход которой подается имя искомого термина, tid верхнего уровня и номер словаря:

<?php
function myfeedsmodule_term_hierarchy_fetch_term($name$tid$vid) {
    
$childrens taxonomy_get_children($tid$vid);
    
$rtid 0;
    foreach (
$childrens as $term) {
        if (
drupal_strtolower($term->name) == drupal_strtolower($name)) {
            
$rtid $term->tid;
        } 
    }
    if (
$rtid == 0) {
        
//--Drupal6--//
        
$edit = array('vid' => $vid'name' => $name);
                
$edit['parent'] = $tid;
        
taxonomy_save_term($edit);
        
$rtid $edit['tid'];
        
//--End Drupal6 --//
        
        //--Drupal7--//
        
$term = new stdClass();
        
$term->name $name;
        
$term->vid $vid;
        
$term->parent $tid;
        
taxonomy_term_save($term);
        
$rtid $term->tid;
        
//--End Drupal7--//
    

    return 
$rtid;
}
?>

Используется так:
В файле drupal7 - /modules/feeds/mappers/taxonomy.inc
В файле drupal6 - /modules/feeds/mappers/content_taxonomy.inc
..Указанную выше функцию можно вставить в конце этих файлов, или любом доступном для вас месте, например в своем модуле..
ищем функцию taxonomy_feeds_set_target или content_taxonomy_feeds_set_target для друпала7 и 6 соответственно.

В 7 друпале комментируем блок foreach ($terms as $term) {..}
В 6 друпале комментируем блок foreach ($terms as $term_name) {..}

и перед закомментированным блоком вставляем:

<?php
  $first_term 
array_shift(taxonomy_get_term_by_name(array_shift($terms))); //берем первый термин в иерархии
  
$tid $first_term->tid;  //Присваиваем первому tid значение первого термина
  
$tids = array();
  
$tids[] = $tid//записываем первый tid в массив найденных элементов
  
foreach ($terms as $term) {  //Для всех последующих имен терминов
    
$tid myfeedsmodule_term_hierarchy_fetch_term($term$tid$field['vid']{D7$vocabulary->vid}); // Ищем тот термин с именем $term, tid родителя которого равен $tid.
        
$tids[] = $tid//Дописываем найденные tid'ы
  
}
?>

Далее эти значения нужно отправить на вход элемента для записи, для 7 друпала:

<?php
foreach ($tids as $tid) {
    if (
$tid) {
      
$entity->{$target}['und'][$i]['tid'] = $tid;
    }
}
?>

Для 6 друпала:

<?php
foreach ($tids as $tid) {
  if (!
is_array($node->$field_name)) $node->$field_name = array();
  
array_push($node->$field_name, array('value' => $tid));
  if (
$multiple != && count($node->$field_name) >= $multiple) {
    
// If the vocab is not for multiple tags break after the first hit.
    
break;
  }

}

?>

Если вам нужно записать только последний термин в иерархии, это например нужно для уберкарта, то меняем код блока:

<?php
$first_term 
array_shift(taxonomy_get_term_by_name(array_shift($terms))); //берем первый термин в иерархии
  
$tid $first_term->tid;  //Присваиваем первому tid значение первого термина
  
$tids = array();
  
$tids[] = $tid//записываем первый tid в массив найденных элементов
  
foreach ($terms as $term) {  //Для всех последующих имен терминов
    
$tid myfeedsmodule_term_hierarchy_fetch_term($term$tid$field['vid']{D7$vocabulary->vid}); // Ищем тот термин с именем $term, tid родителя которого равен $tid.
        
$tids[] = $tid//Дописываем найденные tid'ы
  
}
?>

на:

<?php
  $first_term 
array_shift(taxonomy_get_term_by_name(array_shift($terms))); //берем первый термин в иерархии
  
$tid $first_term->tid;  //Присваиваем первому tid значение первого термина
  
$tids = array();
  foreach (
$terms as $term) {  //Для всех последующих имен терминов
    
$tid myfeedsmodule_term_hierarchy_fetch_term($term$tid$field['vid']{D7$vocabulary->vid}); // Ищем тот термин с именем $term, tid родителя которого равен $tid.
  
}
  
$tids[] = $tid;
?>

т.е. записывааем в массив найденных терминов только последний из них

..удачи..

Аватар пользователя divined divined 28 августа 2012 в 10:12

любой какой пожелаете, потом в таблице тампинга добавляете фильтр и указываете там разделитель.

Аватар пользователя sleepnik sleepnik 22 мая 2013 в 17:41

Подскажите пожалуйста как устанавливаются модули из песочницы
Feeds tamper term hierarchy - нужен, чтоб импортировались термины таксономии с иерархией.
Английским к сожалению не владею.
Спасибо!

Аватар пользователя hrizolyt hrizolyt 11 июня 2013 в 14:43

У меня одного Feeds tamper term hierarchy вообще не хочет работать?
Правило в тампинге просто игнорируется

Аватар пользователя hrizolyt hrizolyt 11 июня 2013 в 15:42

Решение нашлось:
1) берем модуль отсюда https://drupal.org/node/1319278 из поста #40
2) в мапинге поле с вашей категорией должно быть настроено на Term ID, а не на Term Name, как это могло бы показаться.

ПРОФИТ

Аватар пользователя hrizolyt hrizolyt 12 июня 2013 в 12:06

Я разобрался со своей проблемой.
У меня тоже косяк был в исходных файлах. Заключался в том, что неправильно обрабатываются категории на конце которых стоит пробел, например, не "Книги", а "Книги ". То есть тампером убрал пробелы ненужные и все стало отлично.

Аватар пользователя mozh mozh 29 мая 2014 в 23:06

"hrizolyt" wrote:
2) в мапинге поле с вашей категорией должно быть настроено на Term ID, а не на Term Name, как это могло бы показаться.

Спасибо, 1744 строки зашло как следует, это термины 3-х уровней вложенности. и после на них наверсил столько же нод.

Ипортировал такую инфу(в качестве заголовка брал значение иерархии):
заголовок;марка;затяжка болтов (NM);размер шин;давление спереди (PSI);давление сзади (PSI)
Alfa Romeo>>MiTo>>08 – 13; Alfa Romeo>>MiTo>>08 – 13; 86;195/55R16; 33; 30
Alfa Romeo>>MiTo>>08 – 13; Alfa Romeo>>MiTo>>08 – 13; 86;205/45R17; 34; 32
Alfa Romeo>>147>>01 – 11; Alfa Romeo>>147>>01 – 11; 98; 185/65R15; 31; 31

материал для пользовательского фильтра по подбору.

Аватар пользователя mozh mozh 3 декабря 2014 в 12:32

"mozh" wrote:
должно быть настроено на Term ID

Спасибо еще раз, я уже и забыл что делал это сам, а тут то пост сохранился))

Аватар пользователя mozh mozh 3 декабря 2014 в 12:32

"mozh" wrote:
должно быть настроено на Term ID

Спасибо еще раз, я уже и забыл что делал это сам, а тут то пост сохранился))