Автоматическое создание ноды[решено]

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

Аватар пользователя Stein Stein 25 июля 2008 в 15:40

Подскажите пожалуста как программно можно создать ноду, чтобы небыло необходимости вводить вручную значения полей, читал местные темы, смотрел node_factory не понял что куда писать, пробовал вставлять в базу строки, но ничего не выходит: материал создается, но вот когда хочешь его просмотреть пишет что страница не найдена. help!!!

Комментарии

Аватар пользователя sadmin sadmin 25 июля 2008 в 17:07

Попробуйте посмотреть из чего состоит нода (на сайте где-то были статьи, недавно смотрел), а потом поэкспериментируйте с кодом

db_query("INSERT INTO {ТАБЛИЦА НОДЫ ОПРЕДЕЛЕННОГО ВИДА} (nid, vid, ...) VALUES (%d, %d, ...) ", $node->nid, $node->vid, ...');

вот тут еще посмотрите http://www.drupal.ru/node/16981

Аватар пользователя tdg tdg 25 июля 2008 в 18:07

Проще и правильнее использовать api функцию node_save

Вот на нее документация: http://api.drupal.org/api/function/node_save/5

Может помочь модуль devel - для просмотра названий переменных, в которые надо поместить значения полей.

Аватар пользователя sadmin sadmin 30 июля 2008 в 12:29

to Stein к вам просьба! Напишите как решили вопрос и приведите фрагмент кода. А заголовок измените на "Автоматическое создание ноды [Решено]"! Тогда обсуждение можно будет считать завершенным, а те кто повстречает подобный вопрос - увидят решение и код, и будут вам благодарны.
Заранее спасибо!

Аватар пользователя Stein Stein 31 июля 2008 в 9:34

Для добавления данных(должны быть предварительно приведены в один формат, хранятся в файле) использовал левый скриптик, который считывает сткроку файла и записывает её в соответсвтующюю таблицу, ничего сложного, просто пхп+mysql.

Аватар пользователя Stein Stein 31 июля 2008 в 9:59

Проглядел, что то не так гдето, например вставил вручную в базу ноду, а если я после этого создам еще ноду с помощью друпала, то почему то она пытается записать на ту что создал вручную тоесть, поле nid почему то принимает значение не следуещее по порядку, а значение большее на 1 nidа ноды созданой в друпале, до добавления вручную, почему так?, пока не выяснил

Аватар пользователя olk olk 31 июля 2008 в 10:23

Да все очень просто, вы не корректно обновляете таблицы Smile
При вставке ноды, задействуются таблицы (для Д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);
?>
Аватар пользователя seaji seaji 12 сентября 2008 в 19:51

Кстати, для справки.
Поля, которые закачивают файлы, таким способом создать не получится.
В Друпале встроена хитрая проверка был ли этот файл закачан через форму или нет. Плюс там встроена проверка расширений файлов и прочего.
У меня стояла задача создавать програмно ноды с имадж филдом (с картинкой). Так вот пришлось создавать свою функцию node_save() скопировав оригинал и еще подергав нужные хуки из включенных модулей. Ну там Path Auto, Taxonomy и пр.

Аватар пользователя Stein Stein 31 июля 2008 в 10:49

Огромнейшее СПАСИБИЩЕ )), теперь работает, пропустил таблицу {sequences}. класс!
Но лучше все же разобраться с апи

Аватар пользователя seaji seaji 31 июля 2008 в 12:12

Как раз вчера занимался решением такой задачи.
Лучше использовать две функции:
node_submit();
node_save();
На вход функции node_submit подается не объект, а массив.
Фактически подглядеть структуру этого массива можно следующим образом:
Дописываете в файле modules/node/node.module в самом начале функции node_submit(); следующий код (только потом стереть не забудьте):
<?php
print_r ($node);
die;
?>
Потом идете на страницу создания вашего материала, заполняете все поля, нажимаете "отправить" и любуетесь массивом.
ЗЫ. сегодня еще с комментариями нужно разобраться, как их экспортировать из левой базы в друпал.

Аватар пользователя Antonytm Antonytm 12 сентября 2008 в 19:15

Решил заглянуть в $node. В функцию node_submit внес изменения. Они не отобразились... Стер вообще все в node.module - тоже ничего... Что надо сделать, чтоб изменения отобраались???

Аватар пользователя seaji seaji 12 сентября 2008 в 19:43

Странно, если стереть все в node.module, то сайт должен лечь с фатальной ошибкой.
Значит у вас node.module не в директории modules/node, либо это НЛО.

Аватар пользователя Antonytm Antonytm 15 сентября 2008 в 15:39

Разобрался. Проблема была вот в чем, редактировал я тот node.module, что надо, но была в каталоге modules еще одна папка идентичная node, но с другим названием (copy of node). Так друпал оказывается все тянул из нее...

Аватар пользователя Antonytm Antonytm 15 сентября 2008 в 17:13

очередная проблема: При сохранении node возникает проблема с русскими буквами... Тоесть сохраняется все до первой русской буквы. В чем тут может быть проблема???

Аватар пользователя Antonytm Antonytm 15 сентября 2008 в 19:02

С русскими буквами разобрался. Помогла перекодировка текста в UTF-8. Дошел до меню и таксономии. Их сохранение через объект $node пока не пошло... Но ведь в node_save передается и таксономия и меню... Отрывать меню от node, делая два отдельных, не очень бы хотелось... Может кто-нибудь подскажет, что делать?

Аватар пользователя seaji seaji 1 декабря 2008 в 14:10

Я же уже сказал, как импортировал картинки. Или Вам конкретный код нужен?
Копируете функцию 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();
?>

Аватар пользователя Serg_M Serg_M 28 марта 2009 в 12:26

А может кто подскажет, куда нужно воткнуть php код, чтобы сразу после создания ноды типа А, автоматически создавалась нода типа Б (с кое-какими параметрами из А), для Drupal6*?

Аватар пользователя seaji seaji 28 марта 2009 в 15:21

Напишите свой модуль и юзайте хук [ru-api=hook_node_api()]hook_node_api()[/ru-api].
Там есть возможность встревать в процесс на стадиях создания/изменения/удаления нод.
Только правильно используйте разные условия, а то если делать создание ноды при создании ноды, то можно попасть в бесконечный цикл и ноды будут создаваться пока не выйдет время жизни скрипта.

Аватар пользователя Serg_M Serg_M 28 марта 2009 в 16:17

"seaji" wrote:
Напишите свой модуль и юзайте хук hook_node_api()

Малограмотные мы пока для таких дел. А ссылка выдает "Страница не найдена"

"seaji" wrote:
а то если делать создание ноды при создании ноды, то можно попасть в бесконечный цикл и ноды будут создаваться пока не выйдет время жизни скрипта

Так и есть :-(. А где уменьшить время жизни скрипта, для экспериментов?

Аватар пользователя seaji seaji 28 марта 2009 в 16:46

Сорри, ошибся немного с именем функции http://api.drupal.ru/api/function/hook_nodeapi/6

На самом деле модуль написать очень просто.
Создаете папочку, например mymodule. Помещаете ее туда, где остальные папки модулей. Обычно это здесь: /sites/all/modules
Самое главное в этой папке должны быть два файла:

mymodule.info - без него модуль не включится, содержимое этого файла можете "содрать" по образу и подобию с других модулей.

mymodule.module - тут собственно кладем скрипты.

В данном случае Вам нужно будет написать всего одну функцию:
mymodule_nodeapi(&$node, $op) {}

Ну и дальше смотрите в документации как эту функцию использовать.

Удачи.

Аватар пользователя Serg_M Serg_M 13 апреля 2009 в 18:53

Нашел решение как создать нод типа Б при создании ноды типа А - модуль autocreate, но мне пришлось долго копаться и патчить код. Решил попробовать написать свой модуль, например, при создании ноды page, должна автоматически создаваться нода story:

<?php
// $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. блин, где только не лазил в поисках решения, а оно на этой-же странице выше

<?php
// $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 - спасибо за подсказку, избавился от громоздко-непонятного модуля.

Аватар пользователя talgar@drupal.org talgar@drupal.org 8 мая 2009 в 12:22

Можно воспользоваться модулем http://drupal.org/project/rules
С помощью него можно легко отловить событие создания ноды определенного типа (типов) и добавить свое действие на это событие. Там среди стандартных действий уже есть "создание новой ноды"

Аватар пользователя petropulos petropulos 12 января 2012 в 15:24

А что нужно добавить в вышеприведенный код, чтобы после создания ноды 'story' открылась созданная нода 'page', поскольку в данном коде в конечном итоге выводится story.
Спасибо.