программно создать ноду с cck полями

Главные вкладки

Аватар пользователя colombo_ colombo_ 15 апреля 2012 в 0:35

добрый вечер
создаю программно ноду таким путем

global $user;
$wombat = &$form_state['wombat_obj'];

$node = new stdClass();
$node->title = $wombat->name;
$node->type = 'story';
$node->language = 'ru';
$node->uid = 1;
$node->status = 1;
$node->promote = 0;
$node->comment = 2;

$node->field_marka[0]['value'] = 'Foo'; // текстовое cck поле
$node->field_model[0]['value'] = 'Bar';

$node->body = 'Node body';
// Term reference (taxonomy) field
//$node->field_product_tid[$node->language][]['tid'] = $form_state['values'][''];

//$node->field_customer_nid[$node->language][]['target_id'] = $form_state['values']['entity id'];
//$node->field_customer_nid[$node->language][]['target_type'] = "node";

if($node = node_submit($node)) {
node_save($node);
}
$form_state['redirect'] = '/';

но при этом
$node->field_marka[0]['value'] = 'Foo'; // текстовое cck поле
$node->field_model[0]['value'] = 'Bar';
не отрабатывает и поля не заполняются.
я грешу на то, что возможно я неправильно определяю их, так как поля field_marka и field_model находятся в группе полей group_kategory.
помогите, пожалуйста Smile

ЗЫ: и почему-то автор всех публикаций "гость", хотя указываю вроде как $node->uid = 1;

Комментарии

Аватар пользователя sg85 sg85 15 апреля 2012 в 1:16

На вид все верно, но... У Вас в типе материала указано 'story', я так понимаю поля field_marka и field_model принадлежат именно этому типу материала? Ибо если у указанного типа данных полей нет - возникнет именно эта проблема

Аватар пользователя sg85 sg85 15 апреля 2012 в 1:43

На вид все верно и должно работать(про Term Reference не в курсе, не сталкивался), можно разве что через Devel глянуть на структуру нужного объекта ноды, да бы убедиться, что поля и т.д. названы без ошибок, ибо у меня примерно такой же код сейчас перед глазами, но он работает), Так же смущает, что не проходит uid, такое вроде возможно, если в node_save попадает некорректный объект.

Аватар пользователя colombo_ colombo_ 15 апреля 2012 в 1:48

с Devel еще ни разу не работал Sad
"названы без ошибок" в каком смысле?
названия вроде все совпадают, вручную работает, а полями отказывается.

Аватар пользователя sg85 sg85 15 апреля 2012 в 2:02

ну к примеру букву не ту написать, у меня такое часто бывает, т.е. просто описался. Или еще хуже, тип данных может не совпадать, я помню 2 часа трахался с полем date, пытаясь засунуть туда время в формате UTC, а потом через тот же Devel, выяснил что там должен быть обычный текст, с Devel все просто, ставишь, включаешь, и к примеру, открываешь уже созданную правильно заполненную ноду, и видишь новую вкладку(таб) "Development", там где раньше было только "просмотр" и "редактирование", открываешь, и видишь правильно заполненную структуру объекта этой ноды с подробным описанием, включая типы, названия элементов массивов и т.д. и т.п., словом - идеальный трафарет под эту ноду.

Аватар пользователя colombo_ colombo_ 15 апреля 2012 в 20:28

sg85, эх, вы были абсолютно правы, типы данных были разные Smile
некоторые сск поля имеют тип данных "Категория материала" с автозаполнением. и девел(отличный модуль, спасибо за наводочку) показывает что там String. но при этом в поля с типом данных "Текст" все вставляется и работает ок, то с этими не хочет
и вот я в затруднении, как это побороть? (сменить типо на текст - самое последнее, что хочется сделать)

Аватар пользователя sg85 sg85 15 апреля 2012 в 21:16

Не совсем понял вопроса, String, по сути и есть текст, однако, в некоторых случаях там бывает довольно строгий формат, к примеру, тот же модуль Date, хранит в полях ноды дату в текстовом виде с определенным форматом, и стоит хоть на грамм нарушить этот формат, и при сохранении ноды поле окажется пустым(нулевым, не помню уже точно), попробуйте создать правильную ноду из админки и посмотреть как должны выглядеть данные в этих полях. К примеру, друпал очень любит делать serialize различных массивов и запихивать их в поля таблиц.

Аватар пользователя sg85 sg85 15 апреля 2012 в 22:26

Это тот же случай, что и с таксономией, при создании ноды через админку пишем тэг, он получает его tid(если через апи, то вручную получаем существующий tid), и далее используется только tid, так и тут. Т.е. в том поле должен содержаться некий существующий(обязательно, иначе присвоется 0) индекс, такое обычно используется для привязки кучи таблиц в это поле по некоторому общему индексу. Я просто не совсем понимаю структуру Вашего сайта).

Да кстати, этот тип поля случаем не таксономия?

Аватар пользователя colombo_ colombo_ 15 апреля 2012 в 22:25

ну структура тут не особо сложная. я делаю мультистеп форму с набором полей. и по окончании заполнения формы должна нода создаться по введным данным. но в вижу того, что я пока не особо силен в программировании на друпал, чтобы сразу в ctools загнать cck поля, я просто программно создаю ноду присваивая cck полям значения из обычных полей, заполненных в мультистеп форме)

ЗЫ: получается с таким типом данных я смогу вводить туда программно только те значения, у которых есть tid?

а если поменять тип данных на text, но при этом программно tid для данного термина создавать?

Аватар пользователя sg85 sg85 15 апреля 2012 в 22:40

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

function ваш_модуль_GetTerm($tag,$vid,$parent){
  //Возвращаем индекс совпавшего термина с учетом словаря
  $terms = taxonomy_get_term_by_name($tag);
  foreach($terms as $term)
    if($term->vid==$vid) return $term->tid;
 
  //Если этого не произошло - создаем термин
  $term = array(
    'vid' => $vid,
    'name' => $tag,
    'parent' => $parent,
  );
  taxonomy_save_term($term);
  //Возвращаем его значение
  return $term['tid'];
}

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

            $node->taxonomy=array(
              модуль_GetTerm($текст,$словарь,$предки),
            );

Но это чистая стандартная таксономия 6рки, предки на сколько помню могут быть как массивом так и простым индексом.

tid используется только в таксономии, у Вас случаем не TaxonomyFields используется? А если перевести поле в текст, то индекс будет вовсе ненужен.
З.Ы. Совет, перед тем как использовать таксономию, лучше убедиться, что она там действительно нужна, ибо быстродействием на удивление она не отличается, обычные текстовые CCK поля работают куда быстрее, однако /taxonomy/term/% порой рулит Smile

Аватар пользователя colombo_ colombo_ 15 апреля 2012 в 23:48

там суть в том, что, например, создав ноду с cck полем name равным "ололо" создаться катеригория "ололо" с tid. который и помещается в значение поля, так?
как мне, имея строку какую-то, создать категорию, а потом использовать её tid, чтобы присвоить полю cck?

я код глянул, вроде суть ясна, а как это юзануть хз

Аватар пользователя sg85 sg85 16 апреля 2012 в 0:50

Нет не верно, когда Вы выбираете тип поля, Вы привязываете к ноде некий модуль(модули входящие в состав ССК, прямо или косвенно), который данный тип предоставляет, каждый модуль работает с полями материала по своему, к примеру, простое текстовое поле создаст в таблице конкретного типа материала еще одно поле с простым текстом, с числом суть та же, изображение вообще создает отдельную таблицу и имеет более глубокую структуру в объекте ноды и т.д., и весь принцип построения данных будет зависеть от выбранного Вами типа поля, на всех уровнях, что в БД, что в АПИ(разве что в гуи оно выглядит примерно одинаково), хотя в АПИ все более или менее стандартно, тип поля "Категория материала" мне как-то в работе не встречался, похоже, что он принадлежит модулю TaxonomyField(мне так показалось), который позволяет цеплять таксономию в виде полей материала, но как я уже говорил, я с ним не работал и не в курсе как он на самом деле устроен(ибо я стараюсь по возможности сводить применение таксономии к минимуму, а привязывать её дополнительно еще и к полям... По мне такая надобность может возникнуть уж в очень частных случаях), могу догадываться, что цепляет тот же tid не к ноде, как в стандартном для 6ки случае $node->taxonomy=array($tid);, а что-то вроде $node->field_имя_поля[0]['value']=$tid;(моя догадка), потому то и привел тут принцип работы таксономии.

Использовать приведенную функцию просто(но лучше её перед этим переделать под свои нужды) - передаваемый в поле текст оборачивайте в неё, с указанием словаря, но опять же, это относится только к таксономии. $tag - это собственно текст(имя термина, если выражаться более корректно), $vid - индекс словаря, которому термин будет принадлежать, $parent - это tid родительского термина, если нужна иерархия(в моем случае она была нужна), в Вашем, возможно можно и обойтись, т.е. вообще не указывать при создании, но $vid и $tag обязательны. tid формируется в массиве после применения к нему taxonomy_save_term();

В общем, вариант с таксономией прокатит только при условии, если данный тип поля действительно является полем таксономии, как я уже говорил, почти каждый модуль ССК работает по своему, попробуйте выяснить какому именно модулю принадлежит Ваше поле.

И еще может быть такой вариант - если у Вас заполнено для поля "Допустимые значения", то в нодах будут храниться именно ключи этих значений.

как-то так)

Аватар пользователя colombo_ colombo_ 16 апреля 2012 в 1:11

смотрю, действительно термины таксономии, сейчас ваш код пристроить попытаюсь)

function wombat_taxonom($tag,$vid){
//Возвращаем индекс совпавшего термина с учетом словаря
$terms = taxonomy_get_term_by_name($tag);
foreach($terms as $term)
if($term->vid==$vid) return $term->tid;

//Если этого не произошло - создаем термин
$term = array(
'vid' => $vid,
'name' => $tag,
);
taxonomy_save_term($term);
//Возвращаем его значение
return $term['tid'];
}

а потом

$node->field_marka[0]['value'] = wombat_taxonom($wombat->name, 1);
$node->field_model[0]['value'] = wombat_taxonom($wombat->model, 2);
$node->field_godvipuska[0]['value'] = wombat_taxonom($wombat->year, 3);
$node->field_dvigatel[0]['value'] = wombat_taxonom($wombat->engine, 4);
$node->field_vin[0]['value'] = wombat_taxonom($wombat->vin, 5);
$node->field_gorod[0]['value'] = wombat_taxonom($wombat->city, 6);

работает!)