Я поддерживаю модуль, для которого у меня есть сторонняя сборка для разработчиков. я Д9 Эта проблема появился при использовании модуля, который в остальном работает в D8 и должен быть совместим с 8 и 9.
Модуль создает блоки с датами событий, извлеченными из службы Songkick, но на страницах D9 с включенным блоком songkick выдает эту ошибку:
Drupal\Core\Security\UntrustedCallbackException: визуализация #pre_render
обратные вызовы должны быть методами класса, реализующего
\Drupal\Core\Security\TrustedCallbackInterface или быть анонимным
функция. Обратный вызов был _songkick_block_poweredby_prerender. Видеть
https://www.drupal.org/node/2966725 в
Drupal\Core\Render\Renderer->doTrustedCallback() (строка 96
/var/www/html/web/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php).
Я простой создатель сайтов с ограниченным опытом кодирования, поэтому мне нужна помощь, чтобы решить эту проблему. В ошибке упоминается эта страница объясняя проблему.
В приведенном ниже коде из моих файлов .module упоминается pre_render.
/**
* Реализует hook_block_view_alter().
*/
функция songkick_block_content_view_alter (массив и $ сборка) {
$id = $build['#block_content']->id();
$block = \Drupal\block_content\Entity\BlockContent::load($id);
$block_type = $block->type[0]->target_id;
если ($block_type == 'songkick_block') {
$build['#pre_render'][] = '_songkick_block_poweredby_prerender';
}
}
/**
* Получите данные API предстоящих и прошлых событий.
*/
функция _songkick_block_poweredby_prerender (массив и сборка $) {
$id = $build['#block_content']->id();
$block = \Drupal\block_content\Entity\BlockContent::load($id);
$block_type = $block->type[0]->target_id;
если ($block_type == 'songkick_block') {
// Получить данные пользовательских блоков.
$artis_id = $block->field_artist_id[0]->значение;
$upcoming_show = $block->field_display_upcoming_shows[0]->значение;
$past_show = $block->field_display_past_shows[0]->значение;
$event_details = $block->field_ticket_button[0]->значение;
$events_data = [
'event_details' => $event_details,
'предстоящее_шоу' => $предстоящее_шоу,
'прошлое_шоу' => $прошлое_шоу
];
$events_data = [
'#theme' => 'songkick_events',
'#events_data' => $events_data
];
$client = \Drupal::httpClient();
$api_key = \Drupal::config('songkick.settings')->get('songkick_key');
$url = 'http://api.songkick.com/api/3.0/artists/';
// Данные предстоящего события.
если ($upcoming_show == '1') {
$апиключ = $url. $artis_id. "/calendar.json" . "?apikey=". $апи_ключ;
$request = $client->get($apikey);
$body = $request->getBody()->getContents();
$AllData = (массив)json_decode($body);
// Данные последней страницы
$per_page = $AllData['resultsPage']->на страницу;
$total_entry = $AllData['resultsPage']->totalEntries;
$page = (int)($total_entry / $per_page);
//$mainData = $AllData['resultsPage']->результаты->событие;
$temp_var = [];
для ($x = $page; $x >= 0; $x--){
$final_api_key = $apikey. "&страница=" . $х;
$upcoming_event_request = $client->get($final_api_key);
$upcoming_event_body = $upcoming_event_request->getBody()->getContents();
$UpcomingEventAllData = json_decode($upcoming_event_body);
$mainData = array_reverse($UpcomingEventAllData->страница результатов->результаты->событие);
//$temp_data[] = $mainData;
foreach ($mainData как $value) {
$temp_var[] = $значение;
}
}
$upcoming_events_data = [
'#theme' => 'songkick_events',
'#upcoming_event' => $temp_var
];
}
еще{
$upcoming_events_data = [
'#theme' => 'songkick_events',
'#upcoming_event' => ''
];
}
// Данные прошлых событий.
если ($past_show == '1') {
$апиключ = $url. $artis_id. "/гигография.json" . "?apikey=". $апи_ключ;
$request = $client->get($apikey);
$body = $request->getBody()->getContents();
$AllData = (массив)json_decode($body);
// Данные последней страницы
$per_page = $AllData['resultsPage']->на страницу;
$total_entry = $AllData['resultsPage']->totalEntries;
$page = (int)($total_entry / $per_page);
$temp_var = [];
для ($x = $page; $x >= 0; $x--){
$final_api_key = $apikey. "&страница=" . $х;
$past_event_request = $client->get($final_api_key);
$past_event_body = $past_event_request->getBody()->getContents();
$PastEventAllData = json_decode($past_event_body);
$mainData = array_reverse($PastEventAllData->resultsPage->results->event);
//$temp_data[] = $mainData;
foreach ($mainData как $value) {
$temp_var[] = $значение;
}
}
//$final_api_key = $apikey. "&страница=" . $страница;
// $past_event_request = $client->get($final_api_key);
// $past_event_body = $past_event_request->getBody()->getContents();
// $PastEventAllData = (массив)json_decode($past_event_body);
// $mainData = array_reverse($PastEventAllData['resultsPage']->результаты->событие);
$прошлые_события_данные = [
'#theme' => 'songkick_events',
'#past_event' => $temp_var
];
}
еще{
$прошлые_события_данные = [
'#theme' => 'songkick_events',
'#прошедшее_событие' => ''
];
}
// Объединение данных о предстоящих и прошлых событиях.
$event_data = array_merge($upcoming_events_data,$past_events_data,$events_data);
// Возвращаем данные о событиях.
вернуть $event_data;
}
}
Я пытался следовать инструкциям в этот комментарий и добавили файл с именем SongkickBlockPoweredByViewBuilder.php в папку src с этим кодом:
<?php
пространство имен Drupal\Songkick;
используйте Drupal\Core\Security\TrustedCallbackInterface;
/**
* Обеспечивает надежный обратный вызов для блока Songkick Poweredby.
*
*/
class SongkickBlockPoweredByViewBuilder реализует TrustedCallbackInterface {
/**
* {@inheritdoc}
*/
общедоступная статическая функция trustCallbacks() {
возврат ['preRender'];
}
/**
* Устанавливает обратный вызов Songkick - #pre_render.
*/
общедоступная статическая функция preRender($build) {
$count = $build['content']['#count'];
$build['content']['#count_text'] = \Drupal::translation()->formatPlural($count, '(@count)', '(@count)');
вернуть $сборку;
}
}
И я добавил в свой файл .module следующее:
используйте Drupal\Songkick\SongkickBlockPoweredByViewBuilder;
/**
* Реализует TrustedCallbackInterface
*/
function _songkick_block_poweredby_prerender (массив & $ build, Drupal \ Core \ Block \ BlockPluginInterface $ block) {
$build['#pre_render'][] = [SongkickBlockPoweredByViewBuilder::class, 'preRender'];
}
Затем сайт выдает эту фатальную ошибку:
Неустранимая ошибка: невозможно повторно объявить _songkick_block_poweredby_prerender()
(ранее объявлено в
/var/www/html/web/modules/contrib/songkick/songkick.module:14) в
/var/www/html/web/modules/contrib/songkick/songkick.module в строке 51
Фатальная ошибка исчезнет, если я удалю объявление в строке 14, но исходная ошибка сохранится. Я не понимаю, как определить функцию в строке 51 таким образом, чтобы решить проблему. Строка 51 начинается сразу после этого комментария в приведенном выше отрывке из файла .module:
/*** Получить данные API предстоящих и прошлых событий. */
Какие-нибудь советы?