Подскажите пожалуста как программно можно создать ноду, чтобы небыло необходимости вводить вручную значения полей, читал местные темы, смотрел node_factory не понял что куда писать, пробовал вставлять в базу строки, но ничего не выходит: материал создается, но вот когда хочешь его просмотреть пишет что страница не найдена. help!!!
Комментарии
Попробуйте посмотреть из чего состоит нода (на сайте где-то были статьи, недавно смотрел), а потом поэкспериментируйте с кодом
вот тут еще посмотрите http://www.drupal.ru/node/16981
Проще и правильнее использовать api функцию node_save
Вот на нее документация: http://api.drupal.org/api/function/node_save/5
Может помочь модуль devel - для просмотра названий переменных, в которые надо поместить значения полей.
Согласен, принимается
( http://api.drupal.ru/api/function/node_save/5 )
Спасибо, решил всетаки без использования API добавить, работает.
to Stein к вам просьба! Напишите как решили вопрос и приведите фрагмент кода. А заголовок измените на "Автоматическое создание ноды [Решено]"! Тогда обсуждение можно будет считать завершенным, а те кто повстречает подобный вопрос - увидят решение и код, и будут вам благодарны.
Заранее спасибо!
Для добавления данных(должны быть предварительно приведены в один формат, хранятся в файле) использовал левый скриптик, который считывает сткроку файла и записывает её в соответсвтующюю таблицу, ничего сложного, просто пхп+mysql.
Проглядел, что то не так гдето, например вставил вручную в базу ноду, а если я после этого создам еще ноду с помощью друпала, то почему то она пытается записать на ту что создал вручную тоесть, поле nid почему то принимает значение не следуещее по порядку, а значение большее на 1 nidа ноды созданой в друпале, до добавления вручную, почему так?, пока не выяснил
Да все очень просто, вы не корректно обновляете таблицы
При вставке ноды, задействуются таблицы (для Д5)
{node} - непосредственно нода (вернее ее "шапка"}
{node_revisions} - тело ноды
{sequences} - изменяется {node_nid} - текущий счетчик
Кроме того если включен модуль статистики
то изменяются
таблицы
{accesslog}
и кроме того могут быть изменены еще масса данных стронними модулями (у которых реализован хук nodeapi)
поэтому вам и посоветовали воспользоваться node_save,
кроме этого существуют модули импорта/экспорта http://drupal.org/project/Modules/category/64
простой пример создания ноды через node_save
<?php
global $user;
$node = new StdClass();
$node->type = 'story';
$node->title='Новая записка';
$node->body='Содержание записки';
if(($account = user_load(array('uid' => $user->uid)))){
$node->uid=$account->uid;
$node->name=$account->name;
}
$node->status=1; // сразу опубликуем
node_save($node);
?>
Кстати, для справки.
Поля, которые закачивают файлы, таким способом создать не получится.
В Друпале встроена хитрая проверка был ли этот файл закачан через форму или нет. Плюс там встроена проверка расширений файлов и прочего.
У меня стояла задача создавать програмно ноды с имадж филдом (с картинкой). Так вот пришлось создавать свою функцию node_save() скопировав оригинал и еще подергав нужные хуки из включенных модулей. Ну там Path Auto, Taxonomy и пр.
Огромнейшее СПАСИБИЩЕ )), теперь работает, пропустил таблицу {sequences}. класс!
Но лучше все же разобраться с апи
Как раз вчера занимался решением такой задачи.
Лучше использовать две функции:
node_submit();
node_save();
На вход функции node_submit подается не объект, а массив.
Фактически подглядеть структуру этого массива можно следующим образом:
Дописываете в файле modules/node/node.module в самом начале функции node_submit(); следующий код (только потом стереть не забудьте):
<?php
print_r ($node);
die;
?>
Потом идете на страницу создания вашего материала, заполняете все поля, нажимаете "отправить" и любуетесь массивом.
ЗЫ. сегодня еще с комментариями нужно разобраться, как их экспортировать из левой базы в друпал.
Решил заглянуть в $node. В функцию node_submit внес изменения. Они не отобразились... Стер вообще все в node.module - тоже ничего... Что надо сделать, чтоб изменения отобраались???
Странно, если стереть все в node.module, то сайт должен лечь с фатальной ошибкой.
Значит у вас node.module не в директории modules/node, либо это НЛО.
Разобрался. Проблема была вот в чем, редактировал я тот node.module, что надо, но была в каталоге modules еще одна папка идентичная node, но с другим названием (copy of node). Так друпал оказывается все тянул из нее...
очередная проблема: При сохранении node возникает проблема с русскими буквами... Тоесть сохраняется все до первой русской буквы. В чем тут может быть проблема???
С русскими буквами разобрался. Помогла перекодировка текста в UTF-8. Дошел до меню и таксономии. Их сохранение через объект $node пока не пошло... Но ведь в node_save передается и таксономия и меню... Отрывать меню от node, делая два отдельных, не очень бы хотелось... Может кто-нибудь подскажет, что делать?
Решил с добавлением меню ... помогло global $user; Что-то все комментарии в этой теме превратились в монолог... Создам ка я новый топ... http://drupal.ru/node/19422
спасибо, полезно
seaji, для чего прогоняем через ноде_сабмит и как решили импорт картинок?
Я же уже сказал, как импортировал картинки. Или Вам конкретный код нужен?
Копируете функцию node_save() в свою функцию, называете ее ПОДРУГОМУ.
Потом стираете все лишнее и добавляете недостающее.
Лично я убрал вызов node_api в других модулях и прописал этот вызов сам. Все зависит от того, какие модули Вы используете.
Вот примерно так выглядело окончание моей функции (начиная с места, где идет вызов node_api)
<?php
// Call the node specific callback (if any):
/* if ($node->is_new) {
node_invoke($node, 'insert');
node_invoke_nodeapi($node, 'insert');
}
else {
print 'Node IS NOT NEW !!! \n';
} */
/* Save preview */
$fid = db_next_id('{files}_fid');
$table = 'content_type_'.$node->type;
switch ($node->type) {
case 'journal': // Для статьи журнала
$node->field_journal_preview[0]['fid'] = $fid;
$file = $node->field_journal_preview[0];
$field_prefix = 'field_journal_preview';
break;
case 'annons': // Для анонса
$node->field_annons_preview[0]['fid'] = $fid;
$file = $node->field_annons_preview[0];
$field_prefix = 'field_annons_preview';
break;
case 'news_shopping': // Это будут наши старые новости.
$node->field_news_preview[0]['fid'] = $fid;
$file = $node->field_news_preview[0];
$table = 'content_field_news_preview';
$field_prefix = 'field_news_preview';
break;
case 'news_fashion': // Новостей моды пока у нас нету.
break;
}
$field_alt = $field_prefix.'_alt';
$field_title = $field_prefix.'_title';
$field_fid = $field_prefix.'_fid';
$file['filepath'] = $file['filepath'].$file['filename'];
db_query("INSERT into {files} (fid, nid, filename, filepath, filemime, filesize)
VALUES (%d, %d, '%s','%s','%s',%d)",
$file['fid'], $node->nid, $file['filename'], $file['filepath'], $file['filemime'], $file['filesize']);
if ($node->type == 'annons') {
$field_annons_date_value = date('Y-m-d\TH:i:s', $node->created);
db_query("INSERT into {$table} (vid, nid, $field_fid, $field_title, $field_alt, field_annons_date_value, field_annons_date_value2)
VALUES (%d, %d, '%d','%s','%s','%s','%s')",
$node->vid, $node->nid, $file['fid'], $file['title'], $file['alt'], $field_annons_date_value, $field_annons_date_value);
}
else {
db_query("INSERT into {$table} (vid, nid, $field_fid, $field_title, $field_alt)
VALUES (%d, %d, '%d','%s','%s')",
$node->vid, $node->nid, $file['fid'], $file['title'], $file['alt']);
}
comment_nodeapi($node, 'insert');
/* Page Title Insert */
if (strlen(trim($node->page_title)) > 0) {
db_query("INSERT INTO {page_title} VALUES (%d, '%s')", $node->nid, $node->page_title);
}
/* Taxonomy module */
taxonomy_node_save($node->nid, $node->taxonomy);
/* Path module */
if ($node->path) {
path_set_alias("node/$node->nid", $node->path);
}
/* PathAuto - alias */
$pattern = variable_get('pathauto_node_'. $node->type .'_pattern', FALSE);
if (!$pattern) {
$pattern = variable_get('pathauto_node_pattern', FALSE);
}
// Only do work if there's a pattern
if ($pattern) {
// Only create an alias if the checkbox was not provided or if the checkbox was provided and is checked
if (!isset($node->pathauto_perform_alias) || $node->pathauto_perform_alias) {
$placeholders = pathauto_get_placeholders('node', $node);
$src = "node/$node->nid";
$alias = pathauto_create_alias('node', $op, $placeholders, $src, $node->nid, $node->type);
}
}
// Update the node access table for this node.
node_access_acquire_grants($node);
// Clear the cache so an anonymous poster can see the node being added or updated.
// cache_clear_all();
?>
А может кто подскажет, куда нужно воткнуть php код, чтобы сразу после создания ноды типа А, автоматически создавалась нода типа Б (с кое-какими параметрами из А), для Drupal6*?
Напишите свой модуль и юзайте хук [ru-api=hook_node_api()]hook_node_api()[/ru-api].
Там есть возможность встревать в процесс на стадиях создания/изменения/удаления нод.
Только правильно используйте разные условия, а то если делать создание ноды при создании ноды, то можно попасть в бесконечный цикл и ноды будут создаваться пока не выйдет время жизни скрипта.
Малограмотные мы пока для таких дел. А ссылка выдает "Страница не найдена"
Так и есть :-(. А где уменьшить время жизни скрипта, для экспериментов?
Сорри, ошибся немного с именем функции http://api.drupal.ru/api/function/hook_nodeapi/6
На самом деле модуль написать очень просто.
Создаете папочку, например mymodule. Помещаете ее туда, где остальные папки модулей. Обычно это здесь: /sites/all/modules
Самое главное в этой папке должны быть два файла:
mymodule.info - без него модуль не включится, содержимое этого файла можете "содрать" по образу и подобию с других модулей.
mymodule.module - тут собственно кладем скрипты.
В данном случае Вам нужно будет написать всего одну функцию:
mymodule_nodeapi(&$node, $op) {}
Ну и дальше смотрите в документации как эту функцию использовать.
Удачи.
Нашел решение как создать нод типа Б при создании ноды типа А - модуль autocreate, но мне пришлось долго копаться и патчить код. Решил попробовать написать свой модуль, например, при создании ноды page, должна автоматически создаваться нода story:
// $Id: mymodule.module,v 1.23.2.8 2009/03/16 00:37:32 ххх Exp $
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL){
switch($op){
case 'insert':
if ($node->type == 'page') {
$node->type = 'story';
$node->title = '2222';
node_save($node);
}
break;
}
return;
}
но кто разбирается, поймет, что результатом будет создание ВСЕГДА только ноды story (она записывается поверх page). Помогите, что нехватает в коде, чтобы еще создавалась нода page. Или нужно написать модуль, а вызов делать из node.module?
Знаний нехватает, совсем запутался.
P.S. блин, где только не лазил в поисках решения, а оно на этой-же странице выше
// $Id: mymodule.module,v 1.23.2.8 2009/03/16 00:37:32 Serg_M Exp $
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL){
switch($op){
case 'insert':
if ($node->type == 'page') {
$t_args = array('type' => node_get_types('name', $node), '%title' => $node->title);
drupal_set_message(t('type %title has been created.', $t_args));
global $zagolovok;
$zagolovok = $node->title;
$node = new StdClass();
$node->type = 'story';
$node->title = $zagolovok;
$node->body = 'Soderganie';
node_save($node);
}
break;
}
}
вроде работает, да в $node->... запихиваем все свое.
seaji - спасибо за подсказку, избавился от громоздко-непонятного модуля.
Можно воспользоваться модулем http://drupal.org/project/rules
С помощью него можно легко отловить событие создания ноды определенного типа (типов) и добавить свое действие на это событие. Там среди стандартных действий уже есть "создание новой ноды"
А что нужно добавить в вышеприведенный код, чтобы после создания ноды 'story' открылась созданная нода 'page', поскольку в данном коде в конечном итоге выводится story.
Спасибо.