# 使用 WP-Discourse 或 API 添加组和类别（带安全）？

**URL:** https://meta.discourse.org/t/add-groups-and-categories-with-security-with-wp-discourse-or-the-api/212787
**Category:** WordPress
**Created:** [2021年十二月21日 15:35 UTC](https://meta.discourse.org/t/add-groups-and-categories-with-security-with-wp-discourse-or-the-api/212787 "2021-12-21T15:35:18Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![timgrahl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/timgrahl/32/165663_2.png) [@timgrahl](https://meta.discourse.org/u/timgrahl)
#### Post date: [2021年十二月21日 15:35 UTC](https://meta.discourse.org/t/add-groups-and-categories-with-security-with-wp-discourse-or-the-api/212787/1 "2021-12-21T15:35:18Z")

</div>

我们通过 Wordpress/Woocommerce 系统进行会员管理。几年来，我们一直在子域名上使用 Discourse，并通过 SSO 集成，效果一直很好。我的 functions 文件中有一段代码，可以在用户加入/取消会员时添加/移除组访问权限。

我们为会员系统添加了一项新功能，允许用户加入一个 6-8 人的小组，进行每周的 Zoom 视频通话。

为了管理这个功能，我们创建了一个名为“Cohorts”（队列）的 Wordpress 文章类型，其中包含每周的通话信息，然后通过自定义用户字段将这些 Cohorts 分配给用户。

以下是我想要实现的目标：

1. 为每个 Cohort 创建一个组。
2. 为每个 Cohort 创建一个子分类，只有来自 #1 的组才能访问。
3. 将每个会员添加到他们各自的组中，这样他们就可以访问他们所属 Cohort 的子分类。

我知道如何实现 #3，但有没有办法以编程方式添加组和子分类（以及安全设置）？

我在 WP-Discourse 工具中找不到此功能。另外，查看 API 时，我可以看到如何添加分类，但看不到安全功能。

我想要实现的功能是否可行？

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [2021年十二月22日 03:36 UTC](https://meta.discourse.org/t/add-groups-and-categories-with-security-with-wp-discourse-or-the-api/212787/2 "2021-12-22T03:36:03Z")

</div>

是的，这是可能的。您可以使用 `discourse_request` 实用方法从 WordPress 发起任何 API 请求到 Discourse，例如：

```plaintext
use WPDiscourse\\Utilities\\Utilities as DiscourseUtilities;
$args = array(
   "body" => "",
   "type" => "post"
);
$response = DiscourseUtilities::discourse_request( $path, $args );

```

这将正确格式化请求，并使用您在 [WP Discourse](https://github.com/discourse/wp-discourse) 设置中提供的 API 密钥和用户。您将需要一个全局密钥来执行您提到的操作（如果您也为正常的 [WP Discourse](https://github.com/discourse/wp-discourse) 功能使用相同的密钥）。

#### 创建群组

您需要的端点是：[Discourse API Docs](https://docs.discourse.org/#operation/createGroup%E3%80%82API) 文档中没有完整的参数列表，但您可以在此处找到它们：[discourse/app/controllers/admin/groups\_controller.rb at main · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/main/app/controllers/admin/groups_controller.rb#L152)

#### 创建分类

您需要的端点是：[https://docs.discourse.org/#operation/createCategory。同样，完整的参数列表在这里：https://github.com/discourse/discourse/blob/main/app/controllers/categories\_controller.rb#L319](https://docs.discourse.org/#operation/createCategory%E3%80%82%E5%90%8C%E6%A0%B7%EF%BC%8C%E5%AE%8C%E6%95%B4%E7%9A%84%E5%8F%82%E6%95%B0%E5%88%97%E8%A1%A8%E5%9C%A8%E8%BF%99%E9%87%8C%EF%BC%9Ahttps://github.com/discourse/discourse/blob/main/app/controllers/categories_controller.rb#L319)

请注意，“安全设置”是通过 `permissions` 参数处理的。您只需要为其提供一个对象，其中群组名称作为键，权限级别整数作为值，例如：

```plaintext
{
  "cohort1": 2,
  "staff": 1
}

```

您可以在此处找到权限级别整数列表：[discourse/app/models/category\_group.rb at main · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/main/app/models/category_group.rb#L10)

---

<div class="post-metadata">

### Author: ![timgrahl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/timgrahl/32/165663_2.png) [@timgrahl](https://meta.discourse.org/u/timgrahl)
#### Post date: [2021年十二月24日 12:38 UTC](https://meta.discourse.org/t/add-groups-and-categories-with-security-with-wp-discourse-or-the-api/212787/3 "2021-12-24T12:38:00Z")

</div>

@Angus，太感谢你了！这正是我需要的！

我已经成功创建了我的群组，将用户分配到群组，并创建了具有适当安全设置的类别。

我真的很感激你的帮助。

不过还有另一个问题……当我尝试运行 PUT 请求来更新类别或群组时，我收到了这个错误：

**致命错误** ：未捕获的错误：未定义函数 wp\_remote\_put() 在 […]/public/wp-content/plugins/wp-discourse/lib/plugin-utilities.php:393

这是我尝试使用新名称更新类别 ID 61 的测试代码：

```plaintext
$path = "/categories/61.json";
$args = array(
            "type" => "put",
            "body" => array (
                "name" => "Cohorts 1",
            )
        );
$response = DiscourseUtilities::discourse_request( $path, $args )

```

我哪里做错了？

---

<div class="post-metadata">

### Author: ![timgrahl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/timgrahl/32/165663_2.png) [@timgrahl](https://meta.discourse.org/u/timgrahl)
#### Post date: [2021年十二月28日 15:22 UTC](https://meta.discourse.org/t/add-groups-and-categories-with-security-with-wp-discourse-or-the-api/212787/4 "2021-12-28T15:22:22Z")

</div>

有什么想法吗？非常感谢！

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [2021年十二月30日 01:27 UTC](https://meta.discourse.org/t/add-groups-and-categories-with-security-with-wp-discourse-or-the-api/212787/5 "2021-12-30T01:27:08Z")

</div>

抱歉 Tim，我这几天不在。看起来需要调整 `discourse_request` 方法来支持这个。我下周会为此提交一个 PR，合并可能还需要一周时间。

如果你想更快地得到结果，可以使用底层的 WP 方法，如下所示：

```plaintext
$api_credentials = DiscourseUtilities::get_api_credentials();
if ( is_wp_error( $api_credentials ) ) {
    return $api_credentials;
}

$headers = array(
    'Api-Key' => sanitize_key( $api_credentials['api_key'] ),
    'Api-Username' => sanitize_text_field( $api_credentials['api_username'] ),
    'Accept' => 'application/json',
);
$body = array( /* specific to the endpoint you're using */ );
$url = /* The absolute url for the endpoint you're using */ ;

$opts = array(
   'headers' => $headers,
   'body' => json_encode( $body ),
   'method' => 'PUT'
);

$result = wp_remote_request( $url, $opts );

```

---

<div class="post-metadata">

### Author: ![tom00953](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom00953/32/259874_2.png) [@tom00953](https://meta.discourse.org/u/tom00953)
#### Post date: [2022年五月17日 10:48 UTC](https://meta.discourse.org/t/add-groups-and-categories-with-security-with-wp-discourse-or-the-api/212787/6 "2022-05-17T10:48:38Z")

</div>

> [@timgrahl](#):
>
> 我们通过 Wordpress/Woocommerce 系统运行会员资格。我们已经使用 Discourse 在子域上通过 SSO 运行了几年，效果一直很好。我在我的 functions 文件中有代码，可以在用户加入/取消时分别添加/删除组访问权限。

嘿 @timgrahl，您能否分享适用于 Wordpress 和 Woocommerce 的有效函数，用于将用户添加到/从中删除组？

我正在使用 Woocommerce 和会员资格，并试图让它生效……如果 wordpress 用户拥有有效的 Woocommerce 会员资格，那么用户将被添加到 `X 组`……当会员资格被取消或过期时，用户将从 `X 组` 中删除

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [2022年五月17日 12:13 UTC](https://meta.discourse.org/t/add-groups-and-categories-with-security-with-wp-discourse-or-the-api/212787/7 "2022-05-17T12:13:34Z")

</div>

嘿 Tom，要将 Discourse 群组与 WooCommerce 会员资格同步，您需要使用此处所述的方法：

> [@Manage group membership in Discourse with WP Discourse SSO](https://meta.discourse.org/t/managing-discourse-group-membership-with-wp-discourse-sso/74724):
>
> WP Discourse functions The WP Discourse plugin has a couple of functions that can be used to associate WordPress users with Discourse groups. These functions are only enabled on sites that are using WordPress as the SSO provider for Discourse. add\_user\_to\_discourse\_group( $user\_id, $group\_names ) [View Code](https://github.com/discourse/wp-discourse/blob/main/lib/utilities.php#L278-L301) remove\_user\_from\_discourse\_group( $user\_id, $group\_names ) [View Code](https://github.com/discourse/wp-discourse/blob/main/lib/utilities.php#L303-L326) Each of these functions take the same two parameters: $user\_id: the WordPress user’s id $group\_names: a comma separat…

---

<div class="post-metadata">

### Author: ![tom00953](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom00953/32/259874_2.png) [@tom00953](https://meta.discourse.org/u/tom00953)
#### Post date: [2022年五月17日 12:27 UTC](https://meta.discourse.org/t/add-groups-and-categories-with-security-with-wp-discourse-or-the-api/212787/8 "2022-05-17T12:27:14Z")

</div>

是的，我看到了……但仍然太笨拙，无法为此创建代码片段 😕
