Проблема с hook_nodeapi

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

Аватар пользователя agv agv 5 марта 2010 в 19:34

История такая.
Пытаюсь перед сохранением ноды(seller_bid) поменять значение CCK поля(Изображение), т.е. сделать так чтобы использовался уже существующий файл.

С помощью <pre><?php print_r($node); ?></pre> вывел все переменные ноды, в том числе изображение:

[field_image] => Array
        (
            [0] => Array
                (
                    <strong>[fid] => 87</strong>
                    [list] => 1
                    [data] => Array
                        (
                            [description] =>
                            [alt] =>
                            [title] =>
                        )
                    [uid] => 1
                    [filename] => samsung omnia lite b7300.jpg
                    [filepath] => sites/default/files/samsung omnia lite b7300_1.jpg
                    [filemime] => image/jpeg
                    [filesize] => 144013
                    [status] => 1
                    [timestamp] => 1267804958
                    [nid] => 121
                    [view] =>
                )
        )

По идее меняю field_image[0][fid] на нужный и меняется файл в отображении. Попробовал изменить напрямую в базе.
Изображение изменилось на нужное.
Делаю модуль чтобы заменить при сохранении новой ноды:

<?php
        function seller_bid_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
                switch ($op) {
                        case 'presave':
                                $node->field_image[0][fid]=74;
                                node_save($node);      
                                break;
                }
        }
?>

Изменения field_image[0][fid] не происходит.

Подскажите, что делаю не так?

Комментарии

Аватар пользователя agv agv 6 марта 2010 в 2:47

Cделал var_export() и вывел в drupal_set_message(). Получил следующее:

'field_image' => array (
        0 => array (
                'fid' => '87',
                'list' => '1',
                'data' => array (
                        'description' => '',
                        'alt' => '',
                        'title' => '',
                ),
                'uid' => '1',
                'filename' => 'samsung omnia lite b7300.jpg',
                'filepath' => 'sites/default/files/samsung omnia lite b7300_1.jpg',
                'filemime' => 'image/jpeg',
                'filesize' => '144013',
                'status' => '1',
                'timestamp' => '1267804958',
                'nid' => '121',
                'view' => '',
        ),
)

Добавляю контроль по типу ноды и получаю такой код для модуля:

function seller_bid_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
   if($node->type == 'seller_bid') {
      switch ($op) {
         case 'presave':
            $node->field_image = array(
                 array(
                    'fid' => '74',
                    'list' => '1',
                    'data' => array (
                        'description' => '',
                        'alt' => '',
                        'title' => '',
                        ),
                    'uid' => '1',
                    'filename' => 'Samsung_B7300_Omnia_LITE-1.jpg',
                    'filepath' => 'sites/default/files/Samsung_B7300_Omnia_LITE-1.jpg',
                    'filemime' => 'image/jpeg',
                    'filesize' => '111898',
                    'status' => '1',
                    'timestamp' => '1267652677',
                    'nid' => $node->nid
                    )
                 );
              node_save($node);
              break;
        }
    }
}

И этот код все равно не работает у меня.
Что там с весом модуля? Вес ведь влияет на порядок обработки хука модулями, каким образом он может повлиять на выполнение/невыполнение кода? Можно подробнее об этом?

В базу записываются значения, которые соответствуют тому, что ввел пользователь, данные не подменяются.

В чем может быть еще причина?

Аватар пользователя Dan Dan 6 марта 2010 в 9:01

"alvaxet" wrote:
Пытаюсь перед сохранением ноды(seller_bid) поменять значение CCK поля(Изображение), т.е. сделать так чтобы использовался уже существующий файл.

Несколько нод будут использовать одну запись в БД? Тог при удалении одной из нод - запись будет удалена и остальные останутся без изображения.

Аватар пользователя direqtor direqtor 6 марта 2010 в 10:01
function seller_bid_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
...
node_save($node);
...

Зачем вы кусаете собственный хвост? Читайте в API, что делает [module=hook_nodeapi] и применяйте его для своих задач.

Аватар пользователя agv agv 6 марта 2010 в 13:36

"Dan" wrote:
Несколько нод будут использовать одну запись в БД?

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

"direqtor" wrote:
Зачем вы кусаете собственный хвост?

Не понял Вас. API я почитал перед тем как делать.

«...В основном hook_nodeapi() используется в связке с hook_form_alter(). Модули используют hook_form_alter() для дополнения форм редактирования новыми элементами и hook_nodeapi() для чтения и записи значений этих элементов из и в базу данных.»

Собственно я и пытаюсь(применять hook_nodeapi) на интересующем меня этапе сделать так, чтобы в базу при сохранении ноды записывались нужные данные.

Код выше, но он не работает, и я хочу понять почему.
Поэтому и спрашиваю Ваши мнения.
Вопрос по прежнему актуален: что не так?

Аватар пользователя olk olk 6 марта 2010 в 14:23

Вам просто указали , что по node_save - опять вызывается хук hook_nodeapi с параметром presave, по идее ваш код дожен уйти в бесконечную рекурсию Smile
Уберите node_save (нода и так запишется) ...

Аватар пользователя Dan Dan 6 марта 2010 в 15:42

"alvaxet" wrote:
Нет, мне надо вставить Imagefield из одной ноды в другую, продублировать, файл один, а записи в базе у каждой ноды свои.

Я неверно выразился. Если эти несколько записей в бд будут указывать на один файл, то при удалении одной ноды, удалиться так же и файл - другие ноды останутся "осиротевшими". Этот момент надо учесть.

Аватар пользователя agv agv 6 марта 2010 в 16:37

"olk" wrote:
Уберите node_save

Убрал, спасибо за разъяснение.

"Dan" wrote:
другие ноды останутся "осиротевшими". Этот момент надо учесть.

Спасибо, действительно важный момент.

На данный момент код модуля имеет вид:

function seller_bid_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
   if($node->type == 'seller_bid') {
      switch ($op) {
         case 'presave':
            $node->field_image = array(
               array(
                 'fid' => '74',
                 'list' => '1',
                 'data' => array (
                    'description' => '',
                    'alt' => '',
                    'title' => '',
                 ),
                 'uid' => '1',
                 'filename' => 'Samsung_B7300_Omnia_LITE-1.jpg',
                 'filepath' => 'sites/default/files/Samsung_B7300_Omnia_LITE-1.jpg',
                 'filemime' => 'image/jpeg',
                 'filesize' => '111898',
                 'status' => '1',
                 'timestamp' => '1267652677',
                 'nid' => $node->nid
              )
           );
           break;
        }
    }
}

И код этот по-прежнему не работает...
Какие есть еще мысли?

Аватар пользователя Dark_kz Dark_kz 13 августа 2010 в 8:41

А можно ли hook_nodeapi использовать для типов материалов, которые созданы средством Друпала, а не самописного модуля, и если да, то куда вставить код переопределения, в template.php?