首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用$entity()获取"$entity“参数错误的模块

用$entity()获取"$entity“参数错误的模块
EN

Drupal用户
提问于 2021-03-03 07:01:09
回答 2查看 291关注 0票数 0

我试图在Drupal 8 (8.9.11)中创建一个模块,该模块使用函数hook_entity_presave以编程方式更新节点/实体。我尝试了钩子_实体_presave()不工作的答案,我能够在我的代码中添加这些答案。

sno.routing.yml

代码语言:javascript
复制
sno.content:
  path: /node/add/issuances
  defaults:
    _controller: Drupal\sno\Controller\SnoController::sno_entity_presave
  requirements:
    _permission: 'access content'

src/Controller/SnoController.php

名称空间Drupal\sno\Controller;

使用Drupal\Core\EntityInterface;使用Drupal\节点\NodeInterface;

代码语言:javascript
复制
class SnoController {

  public function sno_entity_presave(\Drupal\Core\Entity\EntityInterface $entity) {
    if ($entity->getEntityType()->id() == 'issuances') {
      $entity->set('field_s', ', s. ');
    }   
  }

}

当我开始添加内容类型发布(/node/add/发行量)的内容时,我会得到以下错误。

网站遇到了一个意外的错误。请稍后再试。控制器"Drupal\sno\Controller\SnoController::sno_entity_presave()“需要为"$entity”参数提供一个值。要么参数为空且没有提供空值,要么没有提供默认值,或者因为在这个参数之后有一个非可选的参数。在Symfony\Component\HttpKernel\Controller\ArgumentResolver->getArguments()中( /var/www/senate-library/vendor/symfony/http-kernel/Controller/ArgumentResolver.php).的第78行)

EN

回答 2

Drupal用户

发布于 2021-03-03 09:04:40

您获得的异常(Controller "Drupal\sno\Controller\SnoController::sno_entity_presave()“要求为"$entity”参数提供一个值)是由于与您定义的sno.content路由相关联的控制器的方法没有得到任何$entity参数而导致的,而后者是作为其参数列出的。

那是一条路线,反正不是钩子。如果要实现hook_entity_presave(),则不需要为此定义路由。如果模块没有定义其他路由,那么甚至不需要sno.routing、yml文件。

正如Jaypan已经说过的,钩子不是在类中实现的方法。它们是具有特定名称的普通PHP函数。在您的例子中,它应该是以下函数。我更正了函数代码,因为:

  • 在像/ node /add/发行量这样的路径中,发行是内容类型,或者节点包,而不是实体类型。由于代码应该对其包是发行人的节点起作用,所以代码需要检查从$entity->bundle()返回的值。
  • 因为每个实体都会调用hook_entity_presave(),所以有必要通过检查从$entity->getEntityTypeId()返回的值(而不仅仅是它的包)来检查保存的是哪个实体。这将处理两个不同实体具有相同名称的包的情况。

我从问题代码中使用的命名空间和路由文件的名称中获取模块机器名。如果这些都是正确的,那么模块机器名也应该是正确的。

代码语言:javascript
复制
// Put the following line on the top of the sno.module file.
use \Drupal\Core\Entity\EntityInterface;

/**
 * Implements hook_entity_presave().
 */
function sno_entity_presave(EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->bundle() == 'issuances') {
     $entity->set('field_s', '');
  }
}

或者,如果模块只有单个实体类型的代码,则可以使用hook_ENTITY_TYPE_presave()。在这种情况下,不需要检查实体类型,因为钩子只对单个实体类型调用。(在本例中,实体类型为Node。)

代码语言:javascript
复制
// Put the following line on the top of the sno.module file.
use \Drupal\Core\Entity\EntityInterface;

/**
 * Implements hook_ENTITY_TYPE_presave().
 */
function sno_node_presave(EntityInterface $entity) {
  if ($entity->bundle() == 'issuances') {
     $entity->set('field_s', '');
  }
}

对于字段,它通常是通过UI添加的字段的field_s。如果它是从代码中定义的,那么这个字段就是s。您需要验证引用该字段的正确方式,因为代码中显示的代码并不清楚。

另外,如果编辑已安装模块的代码,则需要安装或卸载模块,以使Drupal注意到您在该已安装模块中添加了一个钩子,因为Drupal缓存了由模块实现的钩子列表,并在模块安装或卸载时清除它。

票数 1
EN

Drupal用户

发布于 2021-03-03 07:09:52

钩子不是类的一部分。钩子进入.module文件,hook被替换为模块的键。在您的例子中,您的模块似乎被命名为sno,因此函数名是正确的。它不应该是一个类的一部分。

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

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

复制
相关文章

相似问题

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