Всем добрый день.
Сайт на последней версии Durpal 9.
Задача простая, но не могу найти решение ее для Drupal - передать данные формы в другое место сайта.
Форма создана с помощью кастомного модуля на form api - расчет стоимости доставки через API Почта РФ.
В форме одно текстовое поле и кнопка submit.
Функция submitForm получает данные с формы
<?php
$address = $form_state->getValue('delivery_address');
?>
Далее идет отправка адреса из формы по API почта РФ и получение от туда стоимости доставки.
Стоимость записываю в переменную
<?php
@$_POST['total_price'] = $total_price;
?>
И далее в файле my_theme.theme через preprocess_block пытаюсь там получить эту переменную. В этом блоке будет выводиться этот результат стоимости доставки.
<?php
function theme_preprocess_block__apipost(&$variables) {
kint($_POST);
}
?>
В массиве ничего нет.
Подскажите как передавать переменные из формы в другое место? может через конфигурации? сохранять данные в submitForm в конфигурацию? Есть какой-то стандартный общепринятый способ?
Везде в примерах в интернете полученные данные с формы выводят в статус и никуда не передают.
<?php
\Drupal::messenger()->addStatus(@$_POST['total_price']);
?>
Может их как-то можно передать в контроллер кастомного модуля с формой?
Контроллер модуля формирует вывод формы
<?php
class ApiRussianPost extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$form = \Drupal::formBuilder()->getForm('Drupal\pochta\Form\DeliveryForm');
return $form;
}
}
?>
Комментарии
Почему-бы не писать значение в базу, в куки, в сессию? Смотря где и сколько потом значение должно использоваться.
Как ни крутил вопрос - так и не понял, почему это "другое место". Форма загружается из блока. Но ведь в блоке вам нужен и результат.
Тогда в вашей сабмит-функции можно так:
<?php
...
$address = $form_state->getValue('delivery_address');
...
$total_price = ...; // Результат ваших вызовов API и т.д.
// Записываем значение в $form_state.
$form_state->set('total_price', $total_price);
// В зависимости от механики формы или наличия AJAX'а ещё может
// потребоваться в сабмит-функции добавление вызова $form_state->setRebuild().
$form_state->setRebuild();
...
?>
А в вашем билдере формы тогда можно так:
<?php
...
public function build() {
$form = \Drupal::formBuilder()->getForm('Drupal\pochta\Form\DeliveryForm');
if ($total_price = $form_state->get('total_price')) {
// Выведется как обычный маркап ниже всей формы.
$form['total_price'] = [
'#markup' => 'Total price: ' . $total_price
];
}
return $form;
}
...
?>
PS. Проскочил, у вас же это не build-функция формы, значит $form_state в явном виде недоступен.
Тогда этот блок кода можно поместить в build-функцию формы:
<?php
...
if ($total_price = $form_state->get('total_price')) {
// Выведется как обычный маркап ниже всей формы.
$form['total_price'] = [
'#markup' => 'Total price: ' . $total_price
];
}
...
?>
Спасибо за ответ. Указанный Вами способ работает, но для вывода информации в рядом с формой (в том же блоке).
Нашел для себя вот такое решение https://niklan.net/blog/74
Это работает как мне надо, но появилась новая проблема, значение в форме не сбрасывается после function submitForm. То есть если зайти на другую страницу и вернуться опять на ту где расположена форма, то значения уставлены, которые пользователь вводил последний раз. Более того, даже если закрыть браузер, открыть его заново в инкогнито, все равно в $form_state хранятся данные предыдущего ввода.
В конец функции submitForm вставляю
<?php
$form_state->unsetValue('delivery_address');
?>
Смотри рисунок