用户
概述
本页描述了与 Joomla User
类相关的功能,可通过 用户 API 访问。在本页底部,还提供了模块的代码,你可以安装此代码以演示部分功能。
通常,user
代表可以登录到 Joomla 实例的人员的身份,无论该实例是前端、后端(管理员功能)还是两者。与 user
关联的是
- 静态信息,如用户名和电子邮件地址,以及用户偏好,如语言、首选编辑器等。
- 动态信息,如最后登录日期/时间
- 权限数据,它指定每个用户所具备的权限,允许他们在 Joomla 实例中的某些项目上执行操作。
Joomla 用户 API 允许您查看用户帐号属性,修改这些属性,检查用户权限,删除用户帐号以及执行用户帐号管理功能(比如封禁帐号)。
设置某些用户属性会影响用户登录的能力,比如封禁帐号或更改密码。但是,用户 API 代码不会包括您可能需要同时采取的其他操作,比如向用户发送一封电子邮件来警告他们已被封禁。
基本操作
为当前已登录用户获取用户对象
use Joomla\CMS\Factory;
$user = Factory::getApplication()->getIdentity();
如果尚未有用户登录,则 Factory::getApplication()->getIdentity()
会返回一个“空白”用户对象,其中 id
字段设置为 0(零)。
如需获取有关任何其他已注册用户的相关信息,您可以使用 UserFactory 类(从依赖项注入容器中获取)的功能
use Joomla\CMS\User\UserFactoryInterface;
...
// Get the UserFactory
$userFactory = Factory::getContainer()->get(UserFactoryInterface::class);
// to get User object for user with id = 99
$user = $userFactory->loadUserById(99);
// to get User object for user with username = "joomuser"
$user = $userFactory->loadUserByUsername("joomuser");
获取用户对象时,通常在 Joomla 代码中使用的另一种方法是直接对其进行实例化。如果您传递用户的 ID,那么该用户对象将会加载
use Joomla\CMS\User\User;
...
$id = 99;
$user = new User($id);
但是,以这种方式实例化类(而不是通过从依赖项注入容器中获取的工厂方法)确实会增加您在单元测试中模拟类的难度。
获取用户对象后,您可以显示有关该用户的信息。例如,以下代码显示当前用户的姓名、电子邮件和用户名称
echo "<p>This user's name is {$user->name}, email is {$user->email}, and username is {$user->username}</p>";
用户对象属性
Joomla 将与用户关联的某些数据项存储在 #__users
表中的固定字段中,并将其他数据项存储在 #__users
表中的 params
字段中。这随后会反映在作为 User
对象的属性可用的数据项中,以及您必须使用 params
属性才能访问的数据项中。
关于管理员用户功能,通常情况下,固定字段中的数据项都位于管理员“用户管理/编辑”表单的第一个选项卡中(当前名称为“帐号详情”),而存储在 params 中的属性则显示在子选项卡(当前名称为“基本设置”)中。
以下是通过调用 getIdentity()
后自动生成,并按照 API 文档中定义的顺序排列的属性
- id - 唯一的数字用户 ID。(在其他 Joomla 数据库表中,此 ID 用作外键,指向关联的用户记录)。
- 姓名 —— 用户的姓名(例如:Vint Cerf)
- 用户名 —— 用户的登录/屏幕名称(例如:shmuffin1979)
- 电子邮件 —— 用户的电子邮件地址(例如:[email protected])
- 密码 —— 用户密码的加密版本
- 密码_明文 —— 当且仅当更改用户密码时才设置为该用户的密码。否则,保持空白。
- 阻止 —— 当用户在 Joomla 中被设置为“阻止”时(即阻止他们登录)设置为“1”
- sendEmail —— 指定此用户是否应该接收系统电子邮件
- 注册日期 —— 设置为用户首次注册的日期。
- 上次访问日期 —— 设置为用户上次访问网站的日期。
- 激活 —— 激活令牌。当网站允许用户自注册时使用此令牌。为了完成帐户设置,系统会向已自注册的人发送电子邮件,电子邮件中嵌入的链接包含此激活令牌。
- 参数 —— 从属用户属性的名称/值对的 JSON 字符串(见下文)。
- 组 —— 将用户组 ID 关联为数组 =>(字符串)此用户为其成员的用户组的组 ID
- 访客 —— 如果用户未登录,则此变量将设置为“1”。其他变量将是未设置的或默认值。
- 上次重置时间 —— 设置为上次重置密码的时间。
- 重置计数 —— 统计密码重置次数。
- 要求重置 —— 表示下次用户登录时会强制他们重置密码。
存储在数据库中的 params
字段中的用户属性,并可通过 $user->getParam()
获取,如下所示。
- admin_style —— back-end 模板的 ID。
- admin_language —— back-end 语言的语言标签
- language —— 前端的语言语言标签
- editor —— 首选编辑器
- timezone —— 用户选择的时区(标准 PHP 时区之一)。还可以通过
$user->getTimezone()
获取时区。
例如,若要获取用户首选的前端语言,请调用 User
对象的 getParam()
成员函数,传入所需参数的名称(即“language”)以及一个默认值(以防为空)。
use Joomla\CMS\Factory;
$user = Factory::getApplication()->getIdentity();
$language = $user->getParam('language', 'the default');
echo "<p>Your Frontend language is set to {$language}.</p>";
确定状态
通常,在继续之前,您只需确保用户已登录。当当前用户未登录时,guest
属性将设置为“1”。当用户经过身份验证,guest
将设置为“0”。
$user = JFactory::getApplication()->getIdentity();
if ($user->guest) {
echo "<p>You must login to see this content.</p>";
} else {
echo "<p>You are logged in, you can see the content.</p>";
}
(如果你使用 loadUserById
或 loadUserByUsername
查找系统上另一个用户的用户对象,则请注意,guest
并不指示此用户是否“已登录”(从存在该用户的当前会话 cookie 的意义上来说);设置为 0 的 guest
更准确地表示已加载有效的用户记录。)
权限
并非所有用户都拥有同等权限。例如,超级管理员可以编辑任何人的内容,而发布者可能只能编辑自己的内容。某些文章可能是机密的,只有获得查看权限的用户才能查看这些文章。
用户 API 中有 4 个与权限相关的函数调用
authorise()
authorise()
函数成员可用于确定当前用户是否具有执行某项任务的权限。第一个参数用于识别我们希望检查是否允许执行的任务。第二个参数指示我们希望从中检索 ACL 信息的组件。
$user = Factory::getApplication()->getIdentity();
if ($user->authorise('core.edit', 'com_content'))
{
echo "<p>You may edit all content.</p>";
}
else
{
echo "<p>You may not edit all content.</p>";
}
if ($user->authorise('core.edit.own', 'com_content'))
{
echo "<p>You may edit your own content.</p>";
}
else
{
echo "<p>You may not edit your own content.</p>";
}
getAuthorisedCategories()
你可以调用 getAuthorisedCategories()
,传入组件和希望执行的操作,此函数将返回一个类别 ID 数组,此用户可以在其上执行该操作。例如
$user->getAuthorisedCategories('com_content', 'core.delete')
返回此用户可以删除的 com_content
类别的类别 ID 数组。
getAuthorisedGroups()
$user->getAuthorisedGroups()
返回此用户所属的用户组 ID 数组。你可以通过导航至“用户/组”管理页面查看用户组 ID。
getAuthorisedViewLevels()
$user->getAuthorisedViewLevels()
返回查看访问权限 ID 的数组(你可以通过导航至“用户/访问权限”管理页面查看此数组)。通常,想要限制查看页面的组件会将访问权限分配给每个项目(即你可以在该管理页面上看到的访问权限之一),然后将分配的访问权限 ID 存储在项目数据库表中名为 Access
的数据库字段中,与项目对应。然后,要检查给定用户是否可以查看该项目,你可以检查 Access
数据库字段中的值是否位于该用户的授权视图级别列表中。
例如,如果您希望将名为“article50”的文章限制到名为 Special(ID 为 3)的查看访问级别,那么您可以在 article50 内容记录的访问字段中输入 3,如果 getAuthorisedViewLevels()
返回的数组包含元素 3,则用户将被允许查看它。
数据库操作
下图显示了如何使用用户 API 来更新用户数据。黑色箭头表示控制流:绿色箭头表示数据的方向。
请注意,用户数据的编辑在 Joomla 管理员用户功能(com_users
组件)中进行管理,其中执行了许多检查,以确保用户只能执行他们有权执行的操作。例如,一般用户可能不会授予自己其他特权。如果您使用用户 API,那么绝大多数这些验证都将不会执行,因此您可能需要自己构建其他验证检查。
User
类使用 Joomla Table
类在数据库级别执行 CRUD 操作。更改用户记录的操作将导致插件用户事件被触发。
当插件事件移至手册时,更新以上链接
]
load()
使用 $user->load($id)
从数据库加载用户记录(由 $id
标识)的属性。用户类代码将从数据库中读取数据,并且(假定它是一个有效用户)将属性存储在类属性中,包括存储附加属性的 params 字段。然后您可以直接访问这些属性,例如 $user->name
。
bind().
如果您有一个属性名称到属性值的关联数组 $data
,例如 array('name' => 'Vint Cerf', 'username' => 'shmuffin1979')
,请使用 $user->bind($data)
。然后,bind()
方法将使用传递的值更新本地属性。
您还可以直接设置属性值 $user->name = 'Vint Cerf'
或通过 setParams()
设置 params 属性。
save()
使用 $user->save()
将已设置的更新属性写入数据库。save()
代码将属性值复制到其“table”结构中并调用表类的 bind() 和 store() 方法将它们写入数据库。
插入记录
可以类似地使用上述机制插入新用户记录,唯一的区别是先不从数据库加载现有记录。
删除记录
要删除用户记录,首先将其从数据库加载,然后使用 delete()
方法,例如
$user = Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById(99);
$user->delete();
其他用户表中的相关记录(例如,保存到用户组的映射的 #__user_usergroup_map
和保存用户之间消息的 #__messages
)也将被删除,并且该操作将触发事件 onUserBeforeDelete
和 onUserAfterDelete
,使插件也可以删除任何相关用户数据。但是,如果用户创建了文章或与联系记录相关联,则那些记录中对用户 id 的引用将保留。
示例模块代码
以下是简单 Joomla 模块的代码,安装并运行该代码以演示 Joomla 用户 API 功能。你还可以从 下载 mod_sample_user zip 文件 中下载代码。
在文件夹 mod_sample_user 中创建以下两个文件
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="4.4" client="site" method="upgrade">
<name>User demo</name>
<version>1.0.1</version>
<description>Code demonstrating use of Joomla User class</description>
<files>
<filename module="mod_sample_user">mod_sample_user.php</filename>
</files>
</extension>
<?php
defined('_JEXEC') or die('Restricted Access');
use Joomla\CMS\Factory;
use Joomla\CMS\Language\LanguageHelper;
use Joomla\CMS\User\UserFactoryInterface;
$input = Factory::getApplication()->input;
// find the user - either from username=xxx parameter or current user
if ($input->exists('username'))
{
$username = $input->get('username', "", "STRING");
echo "Getting details for {$username}<br>";
$user = Factory::getContainer()->get(UserFactoryInterface::class)->loadUserByUsername($username);
}
else
{
$user = Factory::getApplication()->getIdentity();
}
if ($user->id == 0)
{
echo "Please logon or provide a valid username as URL parameter";
return;
}
// output the user's email address and Frontend language
$language = $user->getParam('language', 'the default');
echo "Email address of {$user->name} is {$user->email}, Frontend language is {$language}<br>";
// Set new Frontend language of this user if userlanguage=xxx parameter set
// This will fail if you try to change the language of a Super User, and you're not logged on as a Super User
if ($new_language = $input->get('userlanguage', "", "STRING"))
{
if (array_key_exists($new_language, LanguageHelper::getContentLanguages()))
{
$user->setParam('language', $new_language);
if ($user->save())
{
echo "Language successfully set to {$new_language}<br>";
}
else
{
echo "Setting language to {$new_language} failed<br>{$user->getError()}<br>";
}
}
else
{
echo "Setting language to {$new_language} failed - language doesn't exist<br>";
}
}
// if we're on a single article page, then check if the user can edit the article
$option = $input->get('option', "", "cmd");
$view = $input->get('view', "", "string");
$id = $input->get('id', 0, "int");
if ($option == "com_content" && $view == "article")
{
if ($user->authorise('core.edit', "com_content.article.{$id}"))
{
echo "{$user->name} may edit this article<br>";
}
else
{
echo "{$user->name} may not edit this article<br>";
}
}
压缩 mod_sample_user
目录,创建 mod_sample_user.zip
。
在 Joomla 管理员界面中,转到安装扩展,然后通过上传包文件选项卡选择此 zip 文件来安装此示例用户模块。
通过编辑该模块(在内容/站点模块页面中单击该模块)使该模块可见,然后
- 将模块状态设置为已发布
- 为其在页面中选择一个要显示的位置
- 在菜单分配选项卡中指定其应显示的页面
访问站点网页时,你应该在所选位置看到该模块。该模块执行以下操作
- 获取用户对象,并显示用户的姓名、电子邮件地址和首选前端语言。你可以通过登录或向 URL username=XXX 指定参数(用系统中的有效用户名替换 XXX)定义要选择的用户名。
- 如果你指定了 URL 参数,例如 userlanguage=es-ES,则代码会将此语言(在本例中为西班牙语半岛语)设置为该用户的首选前端语言(前提是该语言已在系统中安装为内容语言)。
- 如果你导航到显示单个文章的页面,则代码会输出此用户是否可以编辑该文章。
您可以轻松地改编模块代码来对上面描述的一些其他 API 调用进行试验。