Как залезть в узел по NodeReference?

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

Аватар пользователя ju_monstera ju_monstera 24 января 2010 в 2:03

Есть тип материала А, в нем есть поле NodeReference на материал типа В. В материале типа В есть поле С, числовое. Мне в объекте А надо добыть это значение С из выбранного объекта В. На который есть ссылка! К сожалению, примеров подобных я не нашла, а "интуитивно-очевидный" синтаксис типа field_B->field_C->value не работает. Может быть, эта ссылка - это просто nid? Наверное, тогда должна быть какая-то функция для получения самого нода по ссылке - но я ее тоже не нашла. Кто-то может что-нибудь подсказать?

Комментарии

Аватар пользователя ju_monstera ju_monstera 24 января 2010 в 13:15

Спасибо, но, к сожалению, для меня это оказалось слишком лаконичной рекомендацией Sad

field_name[n]['nid'] - следует ли это понимать так, что поле node reference представляет собой двумерный массив? Где об этом можно почитать? Я предположила, что n - это номер значения, у меня толькл одно, поэтому я указала 0 и надеюсь, что $nid_perform = field_perform[0]['nid']; даст мне nid того узла, на который ссылка. Может, он и дал, я не знаю, как посмотреть промежуточный результат.

Дальше у меня два варианта. Или я получаю сам нод функцией node_load(), допустим $node_perform = node_load($nid_perform); - и как тогда мне получить значение поля field_opera? Оно просто числовое - но ни $node_perform->field_opera, ни оно же с ->value не дали мне нужного результата. Может быть, оно тоже по сути своей массив? $node_perform->field_opera[0] мне тоже не помогло! Где вообще можно об этом (т.е. о структуре добаавленных полей) почитать, чтобы не действовать методом научного тыка?

"Своим запросом дернуть" было бы даже удобнее, но, во-первых, я не уверена, из какой таблицы дергать, если и поле, и тип данных у меня добавленные, во-вторых, опять же, не знаю, что именно дергать. Попытка получить запросом просто field_opera из таблицы с именем нового типа данных по полученному ранее (предположительно) nid'у нужного результата не дала. И я даже не знаю, как посмотреть, что дала! Это полученное число я использую, чтобы отфильтровать нужные варианты для выбора значений, поэтому каждый раз вижу только конечный результат - или работает, или вообще нет, неясно почему.

Аватар пользователя restyler restyler 24 января 2010 в 14:16

у вас все в порядке с логикой, но, кажется, проблемы с php. Вы пробовали использовать var_dump и анализировать структуру нод?
все ведь очень просто делается.
исходные данные - тип материала A, 1 нода этого типа - назовем nA
тип материала B, 1 нода этго типа - nB

nA ссылается на nB.
у nB есть поле C

сначала делаем
$nA = node_load( %nid% );
var_dump($nA);
и изучаем вывод.
Находится $nA -> field_ref, смотрим внутренную структуру. Если мне не изменяет память, искомый nid ноды nB будет лежать в $nA -> field_ref[0]['value']
Это nid второй ноды. Ее загружаем аналогично, $nB = node_load ( $nA -> field_ref[0]['value'] ) ;
и смотрим var_dump($nB);
скорее всего поле C будет доступно через $nb -> field_C[0]['value'];
т.е. чтобы получить поле C, имея только идентификатор nA, примерный код будет:

<?php
$nidA = 'тут nid';
$nA = node_load($nidA);
$nB = node_load($nA -> field_ref[0]['value']);
$field_C = $nB -> field_C[0]['value'];
?>

Аватар пользователя ju_monstera ju_monstera 24 января 2010 в 14:46

Спасибо за ответ. Проблемы с php - это не то слово: я этот php вообще впервые вижу и пытаюсь разобраться по книжечке "Php для начинающих" и разнын тут хелпам. Поэтому и посейчас не знаю, где и каким образом посмотреть вывод var_dump и анализировать структуру нод. У меня оболочки нет - где ее взять? Какая тут вообще технология разработки?

У меня есть Drupal, и я пытаюсь написать этот код в определении списка значений поля в типе А. В типе В для поля С этот список выводится из словаря, отбирая термины нулевого уровня. Это работает - в чем я могу убедиться только, пытаясь создать материал типа В и видя в списке нужный набор. В типе А у меня есть одно поле со ссылкой на тип В, и другое поле, в котором я хочу отобрать для списка значений из того же словаря просто всех "детей" термина, выбранного в поле С объекта, указанного в поле В. Если я в php-коде для формирования этого списка указываю явно какой-то конкретный tid, он честно обирает подчиненные термины (функцией taxonomy_get_children($tid,$vid)) - это тоже работает, в чем я , опять-таки, могу убедиться, только пытаясь создать материал типа А. Осталось добыть реальный tid, который сидит в значении поля С. Я попробовала field_C[0]['value'] - это не помогло. До этого я искала nid ссылаемого поля как field_ref[0]['nid'] - заменила на field_ref[0]['value'] - тоже не помогло :-(. И что делать?

Аватар пользователя ju_monstera ju_monstera 24 января 2010 в 15:39

Ага, технологию я нашла: завела страницу TestProg и в ней все это вывожу. Ваш совет с var_dump оказался замечательно полезным, буду впредь пользоваться, спасибо. Предложенный код, если запускать его "снаружи" узла А, тоже работает (с тем только исправлением, что nid по ссылке все-таки field_ref[0]['nid'] ).

Но! Внутри самого объекта А, при обращении к его собственному field_ref - не работает. Может быть, есть какое-то стандартное обозначение типа "Я сам", от которого уже брать поле? Просто на field_ref[0]['nid'] php ругается синтаксической ошибкой Sad

Аватар пользователя ju_monstera ju_monstera 24 января 2010 в 17:56

Проблема, видимо, в том, что когда я создаю новый объект типа А, я нахожусь в контексте формы создания материала, поэтому использование $this для обращения к значению уже заданного поля вызывает фатальную ошибку с формулировкой "$this не в контексте объекта".

Как же мне это значение получить? Ау, знатоки, помогите! Ведь это же вполне обычная ситуация, когда мне выбор в одном поле определяет возможности выбора в другом поле - неужели никто не сталкивался? Ну пусть не в такой усложненной схеме, как у меня, а просто: Предположим, есть два поля, оба - выбор из списка. Выбираем одно - и меняется возможный список в другом. Как это сделать?

Аватар пользователя restyler restyler 25 января 2010 в 22:12

не надо тестировать ноду, на форме создания которой вы находитесь.
создайте ноду.
создайте свой модуль, реализуйте _init хук, и пишите там свой код. Как создать модуль, я надеюсь вам гугль объяснит.

Аватар пользователя restyler restyler 26 января 2010 в 13:29

это один из удобных и быстрых способов тестировать свой код (любой) - зная nid уже существующей ноды, можно делать анализ структуры возвращаемой node_load(), например. В этой конкретной задаче результирующий код должен быть расположен в node.tpl.php или там в nodeapi хуке, это уж потом, у человека пока проблемы с элементарными вещами, поэтому я и предложил способ экспериментирования.

Аватар пользователя restyler restyler 26 января 2010 в 16:30

Пустая дискуссия. Код бутстрапа-то посмотрите - init модулей вызывается как раз когда "разогрев", как вы выражаетесь, только закончился, и не началось прямое разруливание реквеста - в последней строчке _drupal_bootstrap_full. Удобней места не найти по мне, для "общих" целей, как упомянул выше (проверить что вернет node_load).