首页 > 后端开发 > php教程 > 在Drupal -setup中构建您自己的自定义实体

在Drupal -setup中构建您自己的自定义实体

William Shakespeare
发布: 2025-02-21 10:59:08
原创
331 人浏览过

Build Your Own Custom Entities in Drupal - Setup

关键要点

  • Drupal中的实体是组织数据的一种强大方式,可以自定义以表示特定类型的信息。本教程演示如何创建一个名为“项目”的自定义实体类型,其中包括标题、描述和截止日期等属性。
  • 要创建新的实体类型,必须声明其模式定义,这将生成实体数据的数据库表。本教程提供了创建具有四个列(id、name、description和deadline)的“demo_projects”表的代码示例。
  • 实体API模块需要在您的站点上启用并设置为自定义模块的依赖项,它提供了许多Drupal核心缺乏的实体处理功能。这包括创建新实体、将它们保存到数据库以及显示它们。
  • 本教程还解释了如何覆盖默认EntityAPIController类的buildContent()方法来显示您的实体,以及如何通过entity_view()辅助函数创建实体列表。教程的第二部分将介绍创建页面以显示单个项目实体,通过UI使其可字段化,以及将其公开给Views以进行查询和列表显示。

Drupal实体是组织数据的好方法。如果您熟悉节点、分类术语、评论或用户,您还应该知道,自Drupal 7以来,这些都是实体。关于它们另一个重要的方面是,它们可以通过Field API进行字段化

在本教程中,我将向您展示如何定义您自己的自定义实体类型并开始使用它。为什么有人想这样做而不是使用节点?因为虽然它们很棒,但节点有时会过于复杂。您可能不需要很多功能,例如修订或评论。

在本教程中,我们将定义我们自己的名为“项目”的自定义实体类型,以表示我们关于项目的简单信息(标题、描述和截止日期)。然后,我们将了解一些关于使用此类型实体的内容。

为了继续学习,我假设您知道如何编写基本的自定义模块(我的模块名为demo)。您可以在此处找到关于此主题的优秀教程。继续编写.info文件并创建空的.module和.install文件。我还设置了一个Git存储库,您可以在其中获取本教程的所有源代码(每个部分一个分支,将发布两个部分)。

此外,您需要在您的站点上启用Entity API contrib模块并将其设置为自定义模块的依赖项。Entity API模块在处理实体时非常强大,因为它提供了Drupal核心缺乏的许多功能。

定义我们自己的Drupal实体类型

创建新的实体类型首先需要声明其模式定义。也就是说,编写将生成实体数据数据库表的代码。在我的demo.install文件中,我有以下代码:

/**
 * Implements hook_schema().
 */
function demo_schema() {

  $schema = array();

  $schema['demo_projects'] = array(
    'description' => 'The base table for the Project entity',
    'fields' => array(
      'id' => array(
        'description' => 'Primary key of the Project entity',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'name' => array(
        'description' => 'Project name.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => FALSE,
      ),
      'description' => array(
        'description' => 'Project description.',
        'type' => 'text',
        'size' => 'big',
        'not null' => FALSE,
        'default' => NULL
      ),
      'deadline' => array(
        'description' => 'Project deadline.',
        'type' => 'int',
        'length' => 11,
        'not null' => FALSE,
      ),
    ),
    'primary key' => array('id'),
  );

  return $schema;
}
登录后复制
登录后复制

这是hook_schema()的一个简单实现,通过它我们创建一个demo_projects表,该表有4列:id、name、description和deadline,第一列表示主键。没什么大不了的。

接下来,我们需要实现hook_entity_info()。我们可以在这个钩子中指定很多选项,但这里是最基本和必需的选项(这在demo.module文件中):

/**
 * Implements hook_entity_info().
 */
function demo_entity_info() {

  $info = array();

  $info['project'] = array(
    'label' => t('Project'),
    'base table' => 'demo_projects',
    'entity keys' => array(
      'id' => 'id',
      'label' => 'name',
    ),
    'module' => 'demo',
    'entity class' => 'Entity',
    'controller class' => 'ProjectEntityController',
  );

  return $info;
}
登录后复制
登录后复制

通过这个钩子,我们在$info数组中返回一个新的键,它表示实体机器名。在这个数组中,我们指定了选项(我们将在本教程的过程中添加更多选项)。现在,我们将坚持使用标签(实体类型的可读名称)、存储实体数据的基表、充当实体标识符的属性的实体键以及指定哪个模块定义实体类型的模块。最后一个不是强制性的,但建议使用。

这样,我们就用Drupal注册了我们自己的基本实体类型。要测试它是否有效,请首次启用该模块并检查该表是否已在数据库中创建。然后用几行填充它,以便有一些内容可以使用:

INSERT INTO `demo_projects` (`id`, `name`, `description`, `deadline`)
VALUES
    (1, 'Summer House', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.', 1397501105),
    (2, 'Winter House', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.', 1397501132);
登录后复制
登录后复制

最后,使用hook_menu()使用Drupal注册一个路径(仅用于测试的任何路径),并将以下内容粘贴到其回调函数中:

$projects = entity_load('project', array(1, 2));
dpm($projects);
return 'Some string';
登录后复制

首先,我们使用entity_load()函数加载具有ID 1和2的项目实体,然后我们使用Devel dpm()函数(因此请确保在您的站点上启用了Devel以进行测试)将它们打印到屏幕上。不要忘记页面的回调函数需要返回一些内容,否则它将无法构建。

现在,如果您导航到该页面,您将在Krumo中看到数据库中2个实体的数据。

或者,您可以使用EntityFieldQuery类根据所需的任何属性(不仅仅是id)查询新的实体。有关此工作原理的更多信息,您可以查看本Sitepoint教程,它将帮助您入门。

实体类和控制器

不幸的是,Drupal核心没有提供太多辅助函数来处理实体(entity_load()几乎是唯一的)。但是,Entity API模块填补了这一空白。

为了使用其功能,我们需要更改我们前面声明的实体信息,并指定可用于处理实体的PHP类。现在,我们将向hook_entity_info()实现中键入的project数组中添加另外两个键:

前面提到的代码中已经包含了 'entity class' => 'Entity', 'controller class' => 'ProjectEntityController',

EntityAPIController类(位于模块的entity.controller.inc文件中)为处理实体提供了一些合理的默认值。它扩展了默认的Drupal核心DrupalDefaultEntityController类,并且负责(除许多其他事情外)执行CRUD操作。

这两个类都可以在您的自定义模块中扩展以调整功能(如查询、加载或显示实体)。我们将在稍后看到如何做到这一点。

但首先,我想向您展示如何保存新的实体。目前,在我的数据库中有2条记录,其ID为1和2。我想调整我们在上面测试页面回调函数中编写的代码,以便在不存在的情况下创建ID为3的新实体。它可能如下所示:

/**
 * Implements hook_schema().
 */
function demo_schema() {

  $schema = array();

  $schema['demo_projects'] = array(
    'description' => 'The base table for the Project entity',
    'fields' => array(
      'id' => array(
        'description' => 'Primary key of the Project entity',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'name' => array(
        'description' => 'Project name.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => FALSE,
      ),
      'description' => array(
        'description' => 'Project description.',
        'type' => 'text',
        'size' => 'big',
        'not null' => FALSE,
        'default' => NULL
      ),
      'deadline' => array(
        'description' => 'Project deadline.',
        'type' => 'int',
        'length' => 11,
        'not null' => FALSE,
      ),
    ),
    'primary key' => array('id'),
  );

  return $schema;
}
登录后复制
登录后复制

如您所见,现在我们尝试加载3个项目实体并检查第三个实体是否存在。如果它不存在,我们将使用Entity API提供的entity_create()辅助函数,将属性设置为一些随机值,然后使用实体上的save()方法将其持久保存到数据库。此方法由Entity类提供,其工作是调用我们在上面定义的控制器类上的save()方法。该方法将执行持久保存实体所需的逻辑。但这所有事情都在幕后发生,我们不必担心它。

如果您重新加载该页面,您应该只看到返回的2个项目实体,但如果第二次加载,则应该有3个。

覆盖实体类

在本教程的这一部分中,我想向您展示的最后一件事是如何显示您的实体。为此,我们将坚持使用我们一直在使用的页面回调函数,并使其呈现实体列表。

首先,我们需要覆盖默认EntityAPIController类的buildContent()方法。原因是控制器无法对我们的数据做出假设,因此我们需要提供一些关于如何显示它的信息。首先,让我们声明扩展前一个类的控制器类:

/**
 * Implements hook_entity_info().
 */
function demo_entity_info() {

  $info = array();

  $info['project'] = array(
    'label' => t('Project'),
    'base table' => 'demo_projects',
    'entity keys' => array(
      'id' => 'id',
      'label' => 'name',
    ),
    'module' => 'demo',
    'entity class' => 'Entity',
    'controller class' => 'ProjectEntityController',
  );

  return $info;
}
登录后复制
登录后复制

我选择了类名ProjectEntityController,您需要确保使用此名称替换您在hook_entity_info()实现中为控制器类键设置的值。别忘了。

在这个类中,我们可以从原始类中复制方法名,并使其返回其父类将返回的内容:

在这个类中,我们可以从原始类中复制方法名,并使其返回其父类将返回的内容。我们基本上向数组添加了两个新项目。第一个将用<div>包装描述,第二个将在段落标签之间输出格式化的日期。这是基本的Drupal主题,如果您不理解这里发生了什么,请复习一下。但是您会注意到项目名称缺失。Drupal将自动呈现它,因为我们在hook_entity_info()实现的实体键中将其指定为标签。最后一步是转到我们的页面回调函数并使其显示我们的实体。一种快速的方法(仅用于演示目的):

INSERT INTO `demo_projects` (`id`, `name`, `description`, `deadline`)
VALUES
    (1, 'Summer House', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.', 1397501105),
    (2, 'Winter House', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.', 1397501132);
登录后复制
登录后复制

和以前一样,我们首先加载具有相应ID的实体。然后,我们通过entity_view()辅助函数运行它们,该函数最终将调用我们刚刚覆盖的buildContent()方法。此函数返回每个实体的渲染数组列表。我们渲染每一个并将结果存储在$output数组中,然后将其连接并返回。

您可以刷新页面,您应该会看到您加载的所有实体的列表。确保清除缓存,以便更改可见。

结论

在本教程中,我们通过在代码中定义我们自己的实体类型来开始学习Drupal中的实体。我们已经了解了如何为它们表示的数据编写模式定义以及如何使用Drupal注册它们。然后,我们看到了使用Entity API contrib模块以面向对象的方式处理实体的强大功能。

在本教程的第二部分中,我们将研究三个主要方面。首先,我们将创建一些页面来显示单个项目实体并启动用于管理项目的管理界面。其次,我们将通过UI使其可字段化。第三,我们将将其公开给Views,以便我们可以进行一些适当的查询和列表显示。敬请关注!

关于在Drupal中构建自定义实体的常见问题解答

创建Drupal自定义实体的先决条件是什么?

在开始创建Drupal自定义实体之前,您需要对Drupal的Entity API有基本的了解。您还应该熟悉PHP和面向对象编程的概念。此外,您应该已经设置了Drupal开发环境。这包括在本地机器或服务器上安装和配置Drupal。

如何在Drupal中创建具有捆绑包的自定义内容实体?

在Drupal中创建具有捆绑包的自定义内容实体涉及多个步骤。首先,您需要在自定义模块中定义您的实体及其属性。然后,您需要创建一个表单来添加和编辑您的实体。之后,您需要为实体的操作定义路由。最后,您需要创建一个视图构建器来显示您的实体。

Drupal中的内容实体和配置实体有什么区别?

在Drupal中,内容实体是可以由用户创建、编辑和删除的内容片段。示例包括节点、用户和评论。另一方面,配置实体是存储在数据库中并可以导出到代码的配置片段。示例包括视图、图像样式和用户角色。

如何在Drupal 8中创建内容实体类型?

在Drupal 8中创建内容实体类型涉及在自定义模块中定义您的实体及其属性。您还需要创建一个表单来添加和编辑您的实体,定义实体操作的路由,并创建一个视图构建器来显示您的实体。

我可以使用Entity API模块在Drupal中创建自定义实体吗?

是的,您可以使用Entity API模块在Drupal中创建自定义实体。此模块提供了一种统一的方式来处理实体及其属性。它还提供用于对实体执行操作的API,例如创建、读取、更新和删除。

创建Drupal自定义实体的好处是什么?

创建Drupal自定义实体允许您定义您自己的数据结构和业务逻辑。这可以使您的站点更高效且更易于管理。自定义实体还可以让您充分利用Drupal的Entity API,该API提供了用于处理实体的强大工具。

如何在Drupal中向自定义实体添加字段?

要在Drupal中向自定义实体添加字段,您需要使用Field API。这涉及在实体的基字段定义方法中定义您的字段。您还可以使用Field UI模块通过Drupal管理界面向实体添加字段。

如何在Drupal中显示自定义实体?

要在Drupal中显示自定义实体,您需要为您的实体创建一个视图构建器。这涉及定义一个扩展EntityViewBuilder类的类并实现view方法。您还可以使用Views模块创建实体的自定义视图。

如何在Drupal中创建用于添加和编辑自定义实体的表单?

要在Drupal中创建用于添加和编辑自定义实体的表单,您需要为您的实体定义一个表单类。这涉及扩展EntityForm类并实现form、validate和submit方法。

如何在Drupal中删除自定义实体?

要在Drupal中删除自定义实体,您需要使用Entity API的delete方法。这涉及加载您的实体,调用delete方法,然后保存您的实体。您还可以使用Entity API的deleteMultiple方法一次删除多个实体。

以上是在Drupal -setup中构建您自己的自定义实体的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板