Drupal开发参考资料全解析
模板可用变量
在Drupal开发中,有一些辅助变量可供模板使用:
-
$classes_array
:这是一个包含HTML类属性值的数组,它会在
$classes
变量中被展平为一个字符串。
-
$is_admin
:当当前用户是管理员时,该标志为
true
。
-
$is_front
:当页面显示为首页时,该标志为
true
。
-
$logged_in
:当当前用户是已登录成员时,该标志为
true
。
SimpleTest参考
SimpleTest是Drupal 7内置的测试框架,它提供了多种类型的断言和导航方法,以下是详细介绍:
1.
二进制断言
| 断言 | 描述 |
| — | — |
|
assertTrue($x)
| 如果
$x
为
false
,则测试失败。 |
|
assertFalse($x)
| 如果
$x
为
true
,则测试失败。 |
|
assertNull($x)
| 如果
$x
已设置,则测试失败。 |
|
assertNotNull($x)
| 如果
$x
未设置,则测试失败。 |
|
assertIsA($x, $t)
| 如果
$x
不是类或类型
$t
,则测试失败。 |
|
assertNotA($x, $t)
| 如果
$x
是类或类型
$t
,则测试失败。 |
|
assertEqual($x, $y)
| 如果
$x == $y
为
false
,则测试失败。 |
|
assertNotEqual($x, $y)
| 如果
$x == $y
为
true
,则测试失败。 |
|
assertWithinMargin($x, $y, $m)
| 如果
abs($x - $y) < $m
为
false
,则测试失败。 |
|
assertOutsideMargin($x, $y, $m)
| 如果
abs($x - $y) < $m
为
true
,则测试失败。 |
|
assertIdentical($x, $y)
| 如果
$x == $y
为
false
或类型不匹配,则测试失败。 |
|
assertNotIdentical($x, $y)
| 如果
$x == $y
为
true
且类型匹配,则测试失败。 |
|
assertReference($x, $y)
| 除非
$x
和
$y
是同一个变量,否则测试失败。 |
|
assertClone($x, $y)
| 除非
$x
和
$y
是相同的副本,否则测试失败。 |
|
assertPattern($p, $x)
| 除非正则表达式
$p
与
$x
匹配,否则测试失败。 |
|
assertNoPattern($p, $x)
| 如果正则表达式
$p
与
$x
匹配,则测试失败。 |
|
expectError($x)
| 忽略任何即将到来的匹配错误。 |
|
assert($e)
| 如果期望对象
$e
失败,则测试失败。 |
-
内容断言
| 断言 | 描述 |
| — | — |
|assertTitle($title)| 如果标题完全匹配,则测试通过。 |
|assertText($text)| 如果与可见文本和“alt”文本匹配,则测试通过。 |
|assertNoText($text)| 如果与可见文本和“alt”文本不匹配,则测试通过。 |
|assertPattern($pattern)| 对页面内容进行Perl模式匹配。 |
|assertNoPattern($pattern)| 进行Perl模式匹配以确保找不到内容。 |
|assertLink($label)| 如果存在具有此文本的链接,则测试通过。 |
|assertNoLink($label)| 如果不存在具有此文本的链接,则测试通过。 |
|assertLinkById($id)| 如果存在具有此ID属性的链接,则测试通过。 |
|assertNoLinkById($id)| 如果不存在具有此ID属性的链接,则测试通过。 |
|assertField($name, $value)| 如果具有此名称的输入标签具有此值,则测试通过。 |
|assertFieldById($id, $value)| 如果具有此ID的输入标签具有此值,则测试通过。 |
|assertResponse($codes)| 如果HTTP响应与列表匹配,则测试通过。 |
|assertMime($types)| 如果MIME类型在列表中,则测试通过。 |
|assertAuthentication($protocol)| 如果当前挑战是此协议,则测试通过。 |
|assertNoAuthentication()| 如果当前没有挑战,则测试通过。 |
|assertRealm($name)| 如果当前挑战领域匹配,则测试通过。 |
|assertHeader($header, $content)| 如果获取的头信息与此值匹配,则测试通过。 |
|assertNoHeader($header)| 如果未获取到头信息,则测试通过。 |
|assertCookie($name, $value)| 如果当前存在匹配的cookie,则测试通过。 |
|assertNoCookie($name)| 如果当前不存在此名称的cookie,则测试通过。 | -
导航方法
| 方法 | 描述 |
| — | — |
|getUrl()| 获取当前位置。 |
|get($url, $parameters)| 使用这些参数发送GET请求。 |
|post($url, $parameters)| 使用这些参数发送POST请求。 |
|head($url, $parameters)| 发送HEAD请求而不替换页面内容。 |
|retry()| 重新加载最后一个请求。 |
|back()| 类似于浏览器的后退按钮。 |
|forward()| 类似于浏览器的前进按钮。 |
|authenticate($name, $password)| 在挑战后重试。 |
|restart()| 像新会话一样重新启动浏览器。 |
|getCookie($name)| 获取当前上下文的cookie值。 |
|ageCookies($interval)| 在重启前使当前cookie过期。 |
|clearFrameFocus()| 回到将所有框架视为一个页面的状态。 |
|clickSubmit($label)| 点击具有此标签的第一个按钮。 |
|clickSubmitByName($name)| 点击具有此名称属性的按钮。 |
|clickSubmitById($id)| 点击具有此ID属性的按钮。 |
|clickImage($label, $x, $y)| 通过标题或alt文本点击类型为image的输入标签。 |
|clickImageByName($name, $x, $y)| 通过名称点击类型为image的输入标签。 |
|clickImageById($id, $x, $y)| 通过ID属性点击类型为image的输入标签。 |
|submitFormById($id)| 提交表单而不包含提交值。 |
|clickLink($label, $index)| 通过可见的标签文本点击锚点。 |
|clickLinkById($id)| 通过ID属性点击锚点。 |
|getFrameFocus()| 获取当前选定框架的名称。 |
|setFrameFocusByIndex($choice)| 从1开始计数聚焦到一个框架。 |
|setFrameFocus($name)| 通过名称聚焦到一个框架。 | -
请求修饰符
| 请求修饰符 | 描述 |
| — | — |
|getTransportError()| 获取最后一个套接字错误。 |
|showRequest()| 输出即将发出的请求。 |
|showHeaders()| 输出传入的头信息。 |
|showSource()| 输出原始HTML页面内容。 |
|ignoreFrames()| 不加载框架集。 |
|setCookie($name, $value)| 从现在起设置一个cookie。 |
|addHeader($header)| 总是将此头信息添加到请求中。 |
|setMaximumRedirects($max)| 在多次重定向后停止。 |
|setConnectionTimeout($timeout)| 在字节之间的此时间后终止连接。 |
|useProxy($proxy, $name, $password)| 通过此代理URL发出请求。 |
安装钩子
在Drupal开发中,
.install
文件有一些特定的钩子,以下是详细介绍:
| 钩子 | 描述 |
| — | — |
|
hook_install()
| 当模块安装时执行设置任务。 |
|
hook_uninstall()
| 移除模块设置的任何信息。 |
|
hook_update_N()
| 执行单个更新。对于每个需要数据库更改的补丁,添加一个新的
hook_update_N()
,它将由
update.php
调用。数据库更新根据您兼容的Drupal版本按顺序编号。 |
|
hook_schema()
| 定义数据库模式的当前版本。 |
|
hook_modules_installed()
| 在模块安装后执行必要的操作。 |
|
hook_modules_uninstalled()
| 在模块卸载后执行必要的操作。 |
|
hook_install_tasks()
| 返回安装配置文件要执行的任务数组。 |
|
hook_install_tasks_alter()
| 更改完整的安装任务列表。 |
|
hook_requirements()
| 检查安装要求并进行状态报告。 |
|
hook_enable()
| 在模块启用后执行必要的操作。每次启用模块时都会调用此钩子。 |
|
hook_disable()
| 在模块禁用前执行必要的操作。每次禁用模块时都会调用此钩子。 |
Schema API概述
Drupal模式定义是一个数组结构,代表一个或多个表及其相关的键和索引。通过
hook_schema()
定义模式,通常该钩子位于
modulename.install
文件中。实现
hook_schema()
并指定模块声明的表,就可以在所有支持的数据库引擎上轻松创建和删除这些表,无需处理不同数据库引擎的SQL方言差异。
Drupal定义了许多内容管理结构,最常见的是节点,它是内容类型的核心容器。所有Drupal管理的内容都从节点扩展而来。字段框架允许用户创建自定义内容类型,以满足更专业的需求。但也有其他管理对象,如用户、块和分类术语,有许多函数用于查询、修改和删除这些对象。
如果只是想存储一小部分数据,或者是一组不一定被视为传统Drupal内容的大数据集,这些Drupal管理对象可能会过于繁琐。因此,可能需要向Drupal数据库添加自己管理的表,而Drupal核心不需要知道或关心这些表。
创建数据库表以数据库无关的方式有点棘手,但幸运的是,Drupal的Schema API使其成为可能。我们不直接向数据库传递
CREATE TABLE
或
ALTER TABLE
查询,而是使用与其他Drupal结构一致的语法。
Schema API类
Drupal有一些类可以以数据库无关的方式访问模式信息,如下表所示:
| 名称 | 描述 |
| — | — |
|
DatabaseSchema
| 实现
QueryPlaceholderInterface
以提供访问Schema API的通用方法。 |
|
DatabaseSchemaObjectDoesNotExistException
| 如果要修改的对象不存在,则抛出异常。 |
|
DatabaseSchemaObjectExistsException
| 如果要创建的对象已经存在,则抛出异常。 |
|
DatabaseSchema_mysql
| 实现特定于MySQL数据库引擎的功能。 |
|
DatabaseSchema_pgsql
| 实现特定于PostgreSQL数据库引擎的功能。 |
|
DatabaseSchema_sqlite
| 实现特定于SQLite数据库引擎的功能。 |
|
DatabaseSchema_sqlsvr
| 实现特定于SQL Server数据库引擎的功能。 |
以下是Schema API操作的流程图:
graph TD;
A[开始] --> B[创建自定义模式];
B --> C[使用schema钩子];
C --> D[调用相关函数和方法];
D --> E{操作类型};
E -- 创建表 --> F[db_create_table];
E -- 添加字段 --> G[db_add_field];
E -- 添加索引 --> H[db_add_index];
E -- 删除表 --> I[db_drop_table];
E -- 其他操作 --> J[对应函数和方法];
F --> K[结束];
G --> K;
H --> K;
I --> K;
J --> K;
Schema API提供了一系列函数和方法,用于在代码中操作模式,以下是部分常用的函数和方法介绍:
| 名称 | 描述 |
| — | — |
|
db_add_field
| 向表中添加新字段。 |
|
db_add_index
| 添加索引。 |
|
db_add_primary_key
| 为数据库表添加主键。 |
|
db_add_unique_key
| 添加唯一键。 |
|
db_change_field
| 更改字段定义。 |
|
db_create_table
| 根据Drupal表定义创建新表。 |
|
db_drop_field
| 删除字段。 |
|
db_drop_index
| 删除索引。 |
|
db_drop_primary_key
| 删除数据库表的主键。 |
|
db_drop_table
| 删除表。 |
|
db_drop_unique_key
| 删除唯一键。 |
|
db_field_exists
| 检查给定表中是否存在列。 |
|
db_field_names
| 从键/索引列指定器数组返回字段名称数组。 |
|
db_field_set_default
| 设置字段的默认值。 |
|
db_field_set_no_default
| 设置字段没有默认值。 |
|
db_find_tables
| 查找所有与指定基表名相似的表。 |
|
db_index_exists
| 检查给定表中是否存在索引。 |
|
db_rename_table
| 重命名表。 |
|
db_table_exists
| 检查表是否存在。 |
|
drupal_get_schema
| 获取表的模式定义,或整个数据库模式。 |
|
drupal_get_schema_unprocessed
| 返回模块模式的未处理和未更改版本。 |
|
drupal_install_schema
| 创建模块
hook_schema()
实现中的所有表。 |
|
drupal_schema_fields_sql
| 从表模式中检索字段列表。该列表适用于SQL查询。 |
|
drupal_uninstall_schema
| 删除模块在其
hook_schema()
中定义的所有表。 |
|
drupal_write_record
| 根据模式将记录保存到数据库。 |
|
hook_schema
| 定义数据库模式的当前版本。 |
Schema钩子
创建模块模式的最佳方法是创建一个数组,定义数据结构的所有方面,并在
.install
文件中使用schema钩子。schema钩子应返回一个数组,每个模块定义的表都有一个键,以下是详细的键定义:
-
'description'
:一个非标记纯文本字符串,描述此表及其用途。对其他表的引用应包含在花括号中。例如,
node_revisions
表的描述字段可能包含“为每个{node}存储每个版本的标题和正文数据。”
-
'fields'
:一个关联数组
('fieldname' => specification)
,描述表的数据库列。规范也是一个数组,以下是规范参数的定义:
-
'description'
:一个非标记纯文本字符串,描述此字段及其用途。对其他表的引用应包含在花括号中。
-
'type'
:通用数据类型:
'char'
、
'varchar'
、
'text'
、
'blob'
、
'int'
、
'float'
、
'numeric'
、
'serial'
、
'date'
、
'datetime'
或
'time'
。大多数类型只是映射到相应的数据库引擎特定数据类型。对于自增字段使用
'serial'
,在MySQL上它将扩展为
'INT auto_increment'
。
-
'serialize'
:一个布尔值,指示字段是否将作为序列化字符串存储。
-
'size'
:数据大小:
'tiny'
、
'small'
、
'medium'
、
'normal'
、
'big'
。这是对字段将存储的最大值得提示,并确定将使用的数据库引擎特定数据类型(例如,在MySQL上,
TINYINT
vs.
INT
vs.
BIGINT
)。
'normal'
是默认值,选择基本类型(例如,在MySQL上,
INT
、
VARCHAR
、
BLOB
等)。并非所有数据类型都支持所有大小。请参阅
DatabaseSchema::getFieldTypeMap()
了解可能的组合。
-
'not null'
:如果为
true
,则此数据库列不允许
NULL
值。默认为
false
。
-
'default'
:字段的默认值。值的PHP类型很重要:
''
、
'0'
和
0
都不同。如果为类型
'int'
的字段指定
'0'
作为默认值,它将不起作用,因为
'0'
是一个包含字符“零”的字符串,而不是一个整数。
-
'length'
:类型为
'char'
、
'varchar'
或
'text'
的字段的最大长度。对于其他字段类型忽略。
-
'unsigned'
:一个布尔值,指示类型(仅
'int'
、
'float'
和
'numeric'
)是有符号还是无符号。默认为
FALSE
。对于其他字段类型忽略。
-
'precision'
、
'scale'
:对于类型
'numeric'
的字段,指示精度(有效数字的总数)和小数位数(小数点右边的小数位数)。两个值都是必需的。对于其他字段类型忽略。
除了
'type'
之外的所有参数都是可选的,但类型为
'numeric'
的列必须指定
'precision'
和
'scale'
。
-
'primary key'
:一个或多个键列指定器的数组,形成主键。
-
'unique keys'
:唯一键的关联数组
('keyname' => specification)
。每个规范是一个或多个键列指定器的数组,在表上形成一个唯一键。
-
'foreign keys'
:关系的关联数组
('my_relation' => specification)
。每个规范是一个数组,包含引用表的名称
('table')
和列映射数组
('columns')
。列映射由键对
('source_column' => 'referenced_column')
定义。
-
'indexes'
:索引的关联数组
('indexname' => specification)
。每个规范是一个或多个键列指定器的数组,在表上形成一个索引。
键列指定器可以是列名的字符串,也可以是包含两个元素的数组:列名和长度,指定命名列的前缀。
全局变量
Drupal核心在页面构建中使用了一些全局变量,以下是部分常用全局变量的介绍:
| 名称 | 位置 | 描述 |
| — | — | — |
|
$base_path
|
includes/bootstrap.inc
| Drupal安装的基本路径。至少默认为
'/'
。 |
|
$base_root
|
includes/bootstrap.inc
| 主机的根URL,不包括路径。 |
|
$base_theme_info
|
includes/theme.inc
| 表示基础主题的对象数组。 |
|
$base_url
|
includes/bootstrap.inc
| Drupal安装的基本URL。 |
|
$channel
|
modules/aggregator/aggregator.parser.inc
| 包含标题、链接、描述和其他键的关联数组。链接应为绝对URL。 |
|
$conf
|
./settings.php
| 全局设置文件中定义的站点配置值。 |
|
$conf
|
includes/bootstrap.inc
| 存储在
'variable'
表中的持久变量数组。 |
|
$cookie_domain
|
includes/bootstrap.inc
| 用于会话cookie的域。对于像
'localhost'
这样的主机或仅暴露IP地址的主机,不会设置cookie域。 |
|
$databases
|
./settings.php
| 数据库连接数组。 |
|
$drupal_test_info
|
modules/simpletest/drupal_web_test_case.php
| 保存正在运行的测试信息的全局变量。 |
|
$element
|
modules/aggregator/aggregator.parser.inc
| 描述要渲染的数据的结构化数组。 |
|
$forum_topic_list_header
|
modules/forum/forum.module
| 论坛主题标题信息数组。 |
|
$image
|
modules/aggregator/aggregator.parser.inc
| 聚合器解析使用的当前图像标签。 |
|
$installed_profile
|
includes/bootstrap.inc
| 刚刚安装的配置文件的名称。 |
|
$item
|
modules/aggregator/aggregator.parser.inc
| 通用字符串或数组。 |
|
$items
|
modules/aggregator/aggregator.parser.inc
| 聚合器使用的项目数组。 |
|
$language
|
includes/bootstrap.inc
| 包含活动界面语言信息的对象。它表示用户界面文本元素(如标题、标签或消息)将显示的语言。 |
|
$language_content
|
modules/field/field.multilingual.inc
| 包含活动内容语言信息的对象。它由Field API用作默认值,当未指定语言时,用于选择要显示的字段翻译。 |
|
$language_url
|
includes/locale.inc
| 包含活动URL语言信息的对象。它由URL相关函数(如
l()
)用作默认值,当未明确指定语言时。 |
|
$menu_admin
|
includes/path.inc
| 布尔值,指示菜单管理员正在运行菜单访问检查。 |
|
$multibyte
|
includes/unicode.inc
| 当前多字节模式。可能的值:
UNICODE_ERROR
、
UNICODE_SINGLEBYTE
、
UNICODE_MULTIBYTE
。 |
|
$pager_limits
|
includes/pager.inc
| 每个分页器每页的项目数数组。数组索引是分页器元素索引(默认为0)。 |
|
$pager_page_array
|
includes/pager.inc
| 每个分页器的当前页码数组。 |
|
$pager_total
|
includes/pager.inc
| 每个分页器的总页数数组。数组索引是分页器元素索引(默认为0)。 |
|
$pager_total_items
|
includes/pager.inc
| 每个分页器的总项目数数组。数组索引是分页器元素索引(默认为0)。 |
|
$tag
|
modules/aggregator/aggregator.parser.inc
| 活动标签名称。 |
|
$theme
|
includes/theme.inc
| 活动主题名称。 |
|
$theme_engine
|
includes/theme.inc
| 与活动主题相关的主题引擎。 |
|
$theme_info
|
includes/theme.inc
| 活动主题对象。 |
|
$theme_key
|
includes/theme.inc
| 活动主题的名称。 |
|
$theme_path
|
includes/theme.inc
| 活动主题的路径。 |
|
$timers
|
includes/bootstrap.inc
| 由
timer_start()
创建的计时器。 |
|
$update_free_access
|
sites/default/settings.php
| 允许在未以管理员身份登录时运行
update.php
脚本。在生产系统中务必设置为
FALSE
! |
|
$user
|
includes/bootstrap.inc
| 表示当前登录用户的对象。包含首选项和其他用户信息。 |
通过对这些模板变量、测试框架、安装钩子、Schema API和全局变量的了解和运用,开发者可以更加高效地进行Drupal开发,构建出功能强大、稳定可靠的网站和应用程序。在实际开发过程中,可以根据具体需求灵活使用这些工具和方法,以满足不同的业务场景和功能要求。同时,要注意遵循Drupal的开发规范和最佳实践,确保代码的可维护性和扩展性。
Drupal开发参考资料全解析
实际应用示例
在实际的Drupal开发中,我们可以结合上述介绍的各种工具和方法来完成具体的任务。以下是几个实际应用的示例:
1. 使用SimpleTest进行单元测试
假设我们有一个自定义模块,其中有一个函数用于判断用户是否为管理员。我们可以使用SimpleTest的二进制断言来对这个函数进行单元测试。
// 自定义模块中的函数
function mymodule_is_user_admin($user) {
return in_array('administrator', $user->roles);
}
// 使用SimpleTest进行单元测试
class MyModuleTest extends DrupalWebTestCase {
public function testIsUserAdmin() {
// 创建一个模拟的用户对象,假设该用户是管理员
$admin_user = new stdClass();
$admin_user->roles = array('administrator');
$this->assertTrue(mymodule_is_user_admin($admin_user), '用户是管理员,函数返回正确');
// 创建一个模拟的用户对象,假设该用户不是管理员
$non_admin_user = new stdClass();
$non_admin_user->roles = array('authenticated user');
$this->assertFalse(mymodule_is_user_admin($non_admin_user), '用户不是管理员,函数返回正确');
}
}
2. 使用Schema API创建数据库表
假设我们要创建一个简单的日志表,用于记录用户的操作信息。我们可以使用Schema API来完成这个任务。
// 在mymodule.install文件中实现hook_schema()
function mymodule_schema() {
$schema['mymodule_log'] = array(
'description' => '存储用户操作日志的表',
'fields' => array(
'id' => array(
'type' => 'serial',
'not null' => true,
'description' => '日志的唯一ID',
),
'user_id' => array(
'type' => 'int',
'not null' => true,
'description' => '执行操作的用户ID',
),
'action' => array(
'type' => 'varchar',
'length' => 255,
'not null' => true,
'description' => '用户执行的操作描述',
),
'timestamp' => array(
'type' => 'int',
'not null' => true,
'description' => '操作执行的时间戳',
),
),
'primary key' => array('id'),
'indexes' => array(
'user_id' => array('user_id'),
),
);
return $schema;
}
然后,在模块安装时,Drupal会自动调用
drupal_install_schema('mymodule')
来创建这个表。
开发注意事项
在使用上述工具和方法进行Drupal开发时,需要注意以下几点:
- 兼容性问题 :不同版本的Drupal对某些函数和方法的支持可能会有所不同,因此在开发过程中要确保使用的函数和方法与当前的Drupal版本兼容。例如,在Drupal 8及以上版本中,部分API可能已经被弃用或有了新的实现方式。
- 性能优化 :在使用数据库操作时,要注意性能问题。避免频繁的数据库查询,可以使用缓存机制来减少数据库负载。例如,对于一些不经常变化的数据,可以使用Drupal的缓存系统进行缓存。
- 安全性 :在处理用户输入和数据库操作时,要注意安全性。防止SQL注入、XSS攻击等安全问题。例如,在使用用户输入构建SQL查询时,要使用Drupal提供的安全函数进行转义。
总结
Drupal开发提供了丰富的工具和方法,包括模板变量、SimpleTest测试框架、安装钩子、Schema API和全局变量等。通过合理运用这些工具和方法,开发者可以更加高效地进行Drupal开发,构建出功能强大、稳定可靠的网站和应用程序。
在实际开发过程中,要根据具体需求灵活使用这些工具和方法,同时要注意兼容性、性能优化和安全性等问题。遵循Drupal的开发规范和最佳实践,确保代码的可维护性和扩展性,为用户提供更好的体验。
希望本文对您在Drupal开发方面有所帮助,祝您开发顺利!
以下是一个总结Drupal开发关键步骤的流程图:
graph LR;
A[需求分析] --> B[模块设计];
B --> C[使用Schema API创建表];
C --> D[编写业务逻辑代码];
D --> E[使用SimpleTest进行测试];
E --> F{测试是否通过};
F -- 是 --> G[部署上线];
F -- 否 --> D;
G --> H[持续维护和优化];
通过这个流程图,我们可以清晰地看到Drupal开发的主要步骤,从需求分析到最终的持续维护和优化,每个环节都紧密相连,确保开发出高质量的Drupal项目。
超级会员免费看
79

被折叠的 条评论
为什么被折叠?



