首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何实现TrustedCallbackInterface

如何实现TrustedCallbackInterface
EN

Drupal用户
提问于 2021-10-21 14:12:33
回答 1查看 194关注 0票数 1

我正在维护一个模块,我已经为我创建了一个第三方开发程序。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。

代码语言:javascript
复制
/**
 * 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的文件,代码如下:

代码语言:javascript
复制
formatPlural($count, '(@count)', '(@count)');
     return $build;
   }
 
 }

我在我的.module文件中添加了以下内容:

代码语言:javascript
复制
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数据。*/

有小费吗?

EN

回答 1

Drupal用户

回答已采纳

发布于 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的顶部。然后更改以下语句:

代码语言:javascript
复制
$build['#pre_render'][] = '_songkick_block_poweredby_prerender';

指向您的新代码。如下所示:

代码语言:javascript
复制
$build['#pre_render'][] = [SongkickBlockPoweredByViewBuilder::class, 'preRender'];

还请注意,正确的命名空间中的“松踢”中有小写“S”。这必须与模块的机器名称相同,并且机器名称不允许大写字母。因此,您需要确保namespace声明在SongkickBlockPoweredByViewBuilder中使用小写,而use语句在songkick.module中使用小写。

Drupal在命名上很挑剔,所以也要确保如果您的.module文件在songkick/songkick.module中,那么类SongkickBlockPoweredByViewBuildersongkick/src/SongkickBlockPoweredByViewBuilder.php中。

票数 4
EN
页面原文内容由Drupal提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://drupal.stackexchange.com/questions/307757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档