我正在维护一个模块,我已经为我创建了一个第三方开发程序。I D9 本期在使用其他在D8中工作的模块时出现,并且应该与8& 9兼容。
该模块创建具有事件日期的块,该事件日期是从宋诗服务中提取的,但是在D9页面上,启用了宋诗块会抛出此错误:
Drupal\Core\Security\UntrustedCallbackException:呈现#pre_render回调必须是实现\Drupal\Core\Security\TrustedCallbackInterface的类的方法或匿名函数。回调是_songkick_block_poweredby_prerender。参见Drupal\Core\Render\Renderer->doTrustedCallback()中的https://www.drupal.org/node/2966725 ( /var/www/html/web/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php).的第96行)
我只是一个有限的编码经验的网站建设者,所以我正在寻找帮助,以解决这个问题。错误提到此页解释了这个问题。
下面来自我的.module文件的代码包括提到的pre_render。
/**
* Implements hook_block_view_alter().
*/
function songkick_block_content_view_alter(array &$build) {
$id = $build['#block_content']->id();
$block = \Drupal\block_content\Entity\BlockContent::load($id);
$block_type = $block->type[0]->target_id;
if ($block_type == 'songkick_block') {
$build['#pre_render'][] = '_songkick_block_poweredby_prerender';
}
}
/**
* Get a Upcoming & past events API data.
*/
function _songkick_block_poweredby_prerender(array &$build) {
$id = $build['#block_content']->id();
$block = \Drupal\block_content\Entity\BlockContent::load($id);
$block_type = $block->type[0]->target_id;
if ($block_type == 'songkick_block') {
// Get custom Blocks data.
$artis_id = $block->field_artist_id[0]->value;
$upcoming_show = $block->field_display_upcoming_shows[0]->value;
$past_show = $block->field_display_past_shows[0]->value;
$event_details = $block->field_ticket_button[0]->value;
$events_data = [
'event_details' => $event_details,
'upcoming_show' => $upcoming_show,
'past_show' => $past_show
];
$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 event data.
if ($upcoming_show == '1') {
$apikey = $url . $artis_id. "/calendar.json" . "?apikey=". $api_key;
$request = $client->get($apikey);
$body = $request->getBody()->getContents();
$AllData = (array)json_decode($body);
// Last page data
$per_page = $AllData['resultsPage']->perPage;
$total_entry = $AllData['resultsPage']->totalEntries;
$page = (int)($total_entry / $per_page);
//$mainData = $AllData['resultsPage']->results->event;
$temp_var = [];
for ($x = $page; $x >= 0; $x--){
$final_api_key = $apikey . "&page=" . $x;
$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->resultsPage->results->event);
//$temp_data[] = $mainData;
foreach ($mainData as $value) {
$temp_var[] = $value;
}
}
$upcoming_events_data = [
'#theme' => 'songkick_events',
'#upcoming_event' => $temp_var
];
}
else{
$upcoming_events_data = [
'#theme' => 'songkick_events',
'#upcoming_event' => ''
];
}
// Past event data.
if ($past_show == '1') {
$apikey = $url . $artis_id. "/gigography.json" . "?apikey=". $api_key;
$request = $client->get($apikey);
$body = $request->getBody()->getContents();
$AllData = (array)json_decode($body);
// Last page data
$per_page = $AllData['resultsPage']->perPage;
$total_entry = $AllData['resultsPage']->totalEntries;
$page = (int)($total_entry / $per_page);
$temp_var = [];
for ($x = $page; $x >= 0; $x--){
$final_api_key = $apikey . "&page=" . $x;
$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 as $value) {
$temp_var[] = $value;
}
}
//$final_api_key = $apikey . "&page=" . $page;
// $past_event_request = $client->get($final_api_key);
// $past_event_body = $past_event_request->getBody()->getContents();
// $PastEventAllData = (array)json_decode($past_event_body);
// $mainData = array_reverse($PastEventAllData['resultsPage']->results->event);
$past_events_data = [
'#theme' => 'songkick_events',
'#past_event' => $temp_var
];
}
else{
$past_events_data = [
'#theme' => 'songkick_events',
'#past_event' => ''
];
}
// Merge Upcoming & past evenst data.
$event_data = array_merge($upcoming_events_data,$past_events_data,$events_data);
// Return events data.
return $event_data;
}
}我尝试遵循这句话中的说明,并在src文件夹中添加了一个名为SongkickBlockPoweredByViewBuilder.php的文件,代码如下:
formatPlural($count, '(@count)', '(@count)');
return $build;
}
}我在我的.module文件中添加了以下内容:
use Drupal\Songkick\SongkickBlockPoweredByViewBuilder;
/**
* Implements TrustedCallbackInterface
*/
function _songkick_block_poweredby_prerender(array &$build, Drupal\Core\Block\BlockPluginInterface $block) {
$build['#pre_render'][] = [SongkickBlockPoweredByViewBuilder::class, 'preRender'];
}然后站点抛出这个致命错误:
致命错误:无法重新声明/var/www/html/web/modules/contrib/songkick/songkick.module:14) ()(以前在第51行的/var/www/html/web/modules/contrib/songkick/songkick.module中用_songkick_block_poweredby_prerender声明)
如果删除第14行中的声明,致命错误就会消失,但是原始错误会持续存在。我不知道如何在第51行中定义函数,以解决这个问题。在上述摘录.module文件的注释之后,第51行就开始了:
/***获得即将到来的和过去事件API数据。*/
有小费吗?
发布于 2021-10-22 06:57:32
你有正确的想法,只有几个细节需要修正。
TrustedCallbackInterface最初添加到Drupal8.8中;它在Drupal8.8之前不存在。虽然它在Drupal 8.8和8.9中是可选的,但在Drupal 9中它是强制性的。因此,在进行此更改之前,您的模块与Drupal 9是不兼容的。
首先,将原始版本的_songkick_block_poweredby_prerender()的整个正文复制到public static function preRender($build)中。这就是应该在preRender()方法主体中的全部内容。
第二,从_songkick_block_poweredby_prerender()中删除函数D3(两个副本)。您不再需要它了,因为您已经将该代码放入Drupal\songkick\SongkickBlockPoweredByViewBuilder中。
现在,将use Drupal\songkick\SongkickBlockPoweredByViewBuilder;语句与所有其他use语句放在songkick.module的顶部。然后更改以下语句:
$build['#pre_render'][] = '_songkick_block_poweredby_prerender';指向您的新代码。如下所示:
$build['#pre_render'][] = [SongkickBlockPoweredByViewBuilder::class, 'preRender'];还请注意,正确的命名空间中的“松踢”中有小写“S”。这必须与模块的机器名称相同,并且机器名称不允许大写字母。因此,您需要确保namespace声明在SongkickBlockPoweredByViewBuilder中使用小写,而use语句在songkick.module中使用小写。
Drupal在命名上很挑剔,所以也要确保如果您的.module文件在songkick/songkick.module中,那么类SongkickBlockPoweredByViewBuilder在songkick/src/SongkickBlockPoweredByViewBuilder.php中。
https://drupal.stackexchange.com/questions/307757
复制相似问题