На PHP получить значение поля из таблицы, связанной через Entity reference

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

Аватар пользователя il-ir il-ir 6 сентября 2020 в 13:58

Здравствуйте.

Требуется при сделать правило, когда перед сохранением материала «Номер (выпуск) журнала» в поле title этого материала присваивается программно формируемое значение.

Сделаны типы материалов:

1. Тип материала «Издатель».
Поля:
- Название (наименование) издателя
- Веб-сайт издателя
- Описание издателя

2. Тип материала «Журнал».
Поля:
- Название (заголовок) журнала
- Ссылка на издателя
- ISSN журнала
- Описание журнала

3. Тип материала «Номер (выпуск) журнала».
Поля:
- Название (заголовок) номера (выпуска)
- Ссылка на журнал
- Номер выпуска
- Год выпуска
- Ссылка на файл с номером

Поля «Ссылка на издателя» и «Ссылка на журнал» связаны с полем id материала в соответствующих таблицах через Entity reference.

Сделал всё, что хотел, но один момент не смог понять.
У меня материал «Номер (выпуск) журнала» связан с материалом «Журнал» через поле «Ссылка на журнал» с использованием Entity reference. То есть, в поле «Ссылка на журнал» должен храниться nid записи конкретного журнала, информация о котором записана в таблице «Журнал».

Использую код:

Вариант 1:

//Получаем наименование журнала, для которого вводится номер (выпуск)
$field_name = 'field_journal_issue_journal_ref';
$items = field_get_items('node', $node, $field_name, $node->language);
$output = field_view_value('node', $node, $field_name, $items[0]);
$journal_issue_journal_ref = render ($output);

Вариант 2:

//Альтернативный способ - Получаем наименование журнала, для которого вводится номер (выпуск)
$journal_issue_journal_ref = token_replace('[node:field-journal-issue-journal-ref]');

Планировал получить значение nid, а дальше через запрос db_query выдернуть нужное поле из записи с заданным nid.
Но почему-то в обеих случаях мне вместо nid, записанного в поле «field_journal_issue_journal_ref», выдаётся значение поля «title» записи с nid из этого поля из таблицы «Журнал».

То есть, вместо числа получаю строку с наименование журнала.

Вопрос 1: Что я делаю не так и что надо исправить, чтобы получить не поле title из таблицы «Журнал», а поле с заданным наименованием?

Вопрос 2: Поясните, пожалуйста, чем отличается токен с дефисом (символ "-") от токена с подчёркиванием (символ "_").
Например, в чём отличие токенов (получено из раздела «ПОКАЗАТЬ ПОДСТАНОВОЧНЫЕ ШАБЛОНЫ»):

[node:field-journal-issue-journal-ref]  Ссылка на журнал  Поле "field_journal_issue_journal_ref".
[node:field_journal_issue_journal_ref]  Ссылка на журнал  Поле Ссылка на сущность.

При использовании оба токена дают одинаковое значение - содержимое поля title.

Опять же не понял, в чём тут разница Sad

Вопрос 3: Если использовать вариант 2

//Альтернативный способ - Получаем наименование журнала, для которого вводится номер (выпуск)
$journal_issue_journal_ref = token_replace('[node:field-journal-issue-journal-ref]');

$node->title = $journal_issue_journal_ref;
echo $journal_issue_journal_ref;

То в поле title записывается текст «[node:field-journal-issue-journal-ref]», а через оператор «echo» возвращается наименование журнала.

То есть, для оператора «echo ...» оба варианта (1 и 2) одинаково работают.
А для конструкции «$node->title = ...» вариант 1 записывает содержимое поля, а вариант 2 записывает текст «[node:field-journal-issue-journal-ref]». То есть, почему-то по разному работают.

Это вообще не могу понять.

Спасибо за ответ(ы).

Комментарии

Аватар пользователя marassa marassa 6 сентября 2020 в 16:02

il-ir wrote: в поле title этого материала присваивается программно формируемое значение

Там какие-то сложные вычисления, просто через токены и модуль auto_entitylabel никак не получается?

Аватар пользователя il-ir il-ir 7 сентября 2020 в 15:09

Не, у меня другая задача.
Модуль Automatic Entity Label у меня стоит и он позволяет при сохранении материала менять значение поля title. Классный модуль.

Но мне надо получить другое поле из связанной таблицы, а не поле title.

Чтоб было понятно в чём проблема опишу всю задачу.
Создан и сохранён материал «Журнал».
Создаётся новый материал «Номер (выпуск) журнала», в котором хранятся конкретные выпуски этого журнала.
При сохранении надо у этого нового материала title сделать таким:
«Журнал Растениеводство ISSN 1234-5678 год 2019 номер 12».

Где:
1. «Растениеводство» - содержимое поля «Название (заголовок) журнала», тип материала «Журнал».
2. «1234-5678» - содержимое поля «ISSN журнала», тип материала «Журнал».
3. «2019» - содержимое поля «Год выпуска», тип материала «Номер (выпуск) журнала».
4. «12» - содержимое поля «Номер выпуска», тип материала «Номер (выпуск) журнала».

Поля в п. 3. и п. 4. - это поля в новом, сохраняемом материале хранятся. Доступ к ним лёгкий.
А поля в п. 1 и п. 2 - это поля в материале «Журнал», связанном с создаваемым материалом через поле «Ссылка на журнал» материала «Номер (выпуск) журнала». То есть, их надо как-то вытащить из другого материала, созданного ранее.

И вот с этим у меня затык.
То есть, когда я в создаваемом материале «Номер (выпуск) журнала» пытаюсь получить значение поля «Ссылка на журнал» этим кодом:

//Получаем наименование журнала, для которого вводится номер (выпуск)
$field_name = 'field_journal_issue_journal_ref';
$items = field_get_items('node', $node, $field_name, $node->language);
$output = field_view_value('node', $node, $field_name, $items[0]);
$journal_issue_journal_ref = render ($output);

то мне почему-то выдается не то, что записано в поле «Ссылка на журнал» материала «Номер (выпуск) журнала» (там записан nid связанного материала типа «Журнал»), а сразу выдаётся значение поля title в связанном материале типа «Журнал».

И это и был вопрос 1: как получить nid, являющийся значением поля «Ссылка на журнал» материала «Номер (выпуск) журнала».

Аватар пользователя marassa marassa 7 сентября 2020 в 15:21
1

il-ir wrote: Но мне надо получить другое поле из связанной таблицы, а не поле title.

И модуль Automatic Entity Label (а точнее подсистема токенов Друпал, по крайней мере в восьмерке) это легко позволяет сделать.

il-ir wrote: поля в п. 1 и п. 2 - это поля в материале «Журнал», связанном с создаваемым материалом через поле «Ссылка на журнал» материала «Номер (выпуск) журнала». То есть, их надо как-то вытащить из другого материала, созданного ранее.

Никаких проблем (в восьмёрке Друпал): [node:<полеСсылкаНаЖурнал>:entity:<любоеПолеСущностиЖурнал>]. Но про семёрку я ничего не знаю, возможно это там не работает.

Аватар пользователя il-ir il-ir 8 сентября 2020 в 13:16

marassa wrote: Никаких проблем (в восьмёрке Друпал): [node:<полеСсылкаНаЖурнал>:entity:<любоеПолеСущностиЖурнал>].

В коде написал так:
$journal_issn =  token_replace([node:field_journal_issue_journal_ref:entity:field_journal_issn]);

В итоге получил сообщение:
ParseError: syntax error, unexpected ':', expecting ']' в функции rules_php_eval() (строка 16 в файле W:\domains\testsite.ru\sites\all\modules\rules\modules\php.eval.inc(156) : eval()'d code).

Тестовый сайт работает на OpenServer - поэтому такой странный адрес.

Или я не правильно понял и реализовал Вашу идею?

Аватар пользователя marassa marassa 8 сентября 2020 в 18:45

Значит, как я и боялся, семёрка не поддерживает chained tokens. Возможно есть какой-то контрибный модуль, но откуда мне знать.
А вообще, использование механизма токенов внутри php-кода выглядит несколько неестественно. Токены придуманы для ввода через админку без программирования, как например в модуле Auto Entity Label. Если уж писать код, то конечно по варианту 1. Только почему он у Вас не работает - не могу подсказать, так как ничего не знаю про семёрку.

Аватар пользователя OldWarrior OldWarrior 8 сентября 2020 в 19:42
1

il-ir wrote:... И это и был вопрос 1: как получить nid, являющийся значением поля «Ссылка на журнал» материала «Номер (выпуск) журнала»...

Как-то так можно попробовать:

<?php
$nid 
$node->field_journal_issue_journal_ref['und'][0]['target_id'];
?>

Если не проканает, то

<?php
print_r
($node->field_journal_issue_journal_ref['und'][0]);
?>

и посмотреть, что там вместо 'target_id'

Аватар пользователя OldWarrior OldWarrior 8 сентября 2020 в 21:42
1

В выводе print_r();
Должно выхлопнуть на фронт, перед началом любого HTML. Бывает сложно найти, это обычно где-то над шапкой сайта.

Либо так, чтобы через друпаловский месседж:

<?php
drupal_set_message
(var_export($node->field_journal_issue_journal_ref['und'][0], TRUE));
?>