跳至主要内容
版本:5.1

用户

概述

本页描述了与 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>";
}

(如果你使用 loadUserByIdloadUserByUsername 查找系统上另一个用户的用户对象,则请注意,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 操作。更改用户记录的操作将导致插件用户事件被触发。

待办事项

当插件事件移至手册时,更新以上链接

User database operations]

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)也将被删除,并且该操作将触发事件 onUserBeforeDeleteonUserAfterDelete,使插件也可以删除任何相关用户数据。但是,如果用户创建了文章或与联系记录相关联,则那些记录中对用户 id 的引用将保留。

示例模块代码

以下是简单 Joomla 模块的代码,安装并运行该代码以演示 Joomla 用户 API 功能。你还可以从 下载 mod_sample_user zip 文件 中下载代码。

在文件夹 mod_sample_user 中创建以下两个文件

mod_sample_user/mod_sample_user.xml
<?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>
mod_sample_user/mod_sample_user.php
<?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 调用进行试验。