# 定制数据迁移：从 WordPress 到 discourse

**URL:** https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185
**Category:** Migration
**Tags:** sso, wordpress
**Created:** [2023年四月10日 11:39 UTC](https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185 "2023-04-10T11:39:40Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![muhammad\_ghufran](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/muhammad_ghufran/32/301962_2.png) [@muhammad\_ghufran](https://meta.discourse.org/u/muhammad_ghufran)
#### Post date: [2023年四月10日 11:39 UTC](https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185/1 "2023-04-10T11:39:40Z")

</div>

我使用了 discourse 脚本并将 phpbb 数据迁移到了 discourse，现在我已将我的网站迁移到 WordPress，并且需要迁移一些用户数据。我在 discourse 中创建了自定义用户字段，并使用了“wpdc\_sso\_params”钩子来迁移自定义字段数据。  
但问题是它会在用户登录时同步数据，如果某些用户没有再次登录或过期用户的数据将不会以这种方式迁移。  
是否有任何钩子或脚本可以一次性迁移所有用户数据？

另一件事是，我们正在映射自定义字段，如何映射全名以及名字和姓氏字段？就像我们可以使用“wpdc\_sso\_avatar\_url”钩子设置自定义头像一样。

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [2023年四月18日 06:58 UTC](https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185/3 "2023-04-18T06:58:05Z")

</div>

> [@muhammad\_ghufran](#):
>
> 但问题是它会在用户登录时同步数据，如果某些用户未再次登录或用户已过期，数据将不会以这种方式迁移。  
> 是否有任何钩子或脚本可以一次性迁移所有用户数据？

如果您的 WordPress 网站上启用了 [WP Discourse](https://github.com/discourse/wp-discourse) 插件，您可以编写一个脚本，循环遍历您网站上的所有用户，并为每个要更新的用户调用 `sync_sso_record` 函数，并传入 SSO 参数：

[https://github.com/discourse/wp-discourse/blob/main/lib/utilities.php#L78](https://github.com/discourse/wp-discourse/blob/main/lib/utilities.php#L78)

这是一个静态函数，因此您需要使用以下方式调用它：

```plaintext
WPDiscourse\\Utilities\\Utilities::sync_sso_record($sso_params_array, $wp_user_id)

```

我尝试这样做已经有一段时间了。在尝试循环遍历网站上的所有用户之前，请先用一个用户进行测试。

> [@muhammad\_ghufran](#):
>
> 另一件事是我们正在映射自定义字段，如何映射全名以及名字和姓氏字段？

您可以使用 Discourse 的 `external_name` 字段来映射全名。您使用 `external_name` 字段设置的名称将成为 Discourse 上的用户姓名。如果您需要单独的名字和姓氏字段，则需要在 Discourse 上为它们创建自定义字段。

如果您在此过程中遇到任何麻烦，请告诉我。我明天可以尝试测试一下。

---

<div class="post-metadata">

### Author: ![muhammad\_ghufran](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/muhammad_ghufran/32/301962_2.png) [@muhammad\_ghufran](https://meta.discourse.org/u/muhammad_ghufran)
#### Post date: [2023年四月18日 07:13 UTC](https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185/4 "2023-04-18T07:13:34Z")

</div>

> [@simon](#):
>
> ```plaintext
> WPDiscourse\Utilities\PublicPluginUtilities::sync_sso_record($sso_params_array, $wp_user_id)
> 
> ```
> 
> I

```plaintext
$myusers = get_users( );
	$sso_params_array = [];
	$sso_params_array['custom.user_field_1'] = $user->user_login;
	$sso_params_array['custom.user_field_2'] = get_user_meta( $user->ID, 'first_name', true );
	$sso_params_array['custom.user_field_3'] = get_user_meta( $user->ID, 'last_name', true );
	foreach ( $myusers as $myuser ) {
		WPDiscourse\Utilities\PublicPluginUtilities::sync_sso_record($sso_params_array, $myuser->ID;);
	}

```

@simon 我这样做对吗？

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [2023年四月18日 07:23 UTC](https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185/5 "2023-04-18T07:23:27Z")

</div>

您需要在 `foreach` 循环内设置 `$sso_params_array`。类似这样：

```php
$myusers = get_users();
foreach ( $myusers as $myuser ) {
    $sso_params_array = [];
    $sso_params_array['custom.user_field_1'] = $myuser->user_login;
    $sso_params_array['custom.user_field_2'] = get_user_meta( $myuser->ID, 'first_name', true );
    $sso_params_array['custom.user_field_3'] = get_user_meta( $myuser->ID, 'last_name', true );

	WPDiscourse\Utilities\Utilities::sync_sso_record($sso_params_array, $myuser->ID;);
	}

```

不过，可以先只用一个用户进行尝试。例如：

`$myuser = get_user_by('id', 1);`

最好为此创建一个测试用户。您可以使用此函数获取用户：[get\_user\_by() – Function | Developer.WordPress.org](https://developer.wordpress.org/reference/functions/get_user_by/)

---

<div class="post-metadata">

### Author: ![muhammad\_ghufran](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/muhammad_ghufran/32/301962_2.png) [@muhammad\_ghufran](https://meta.discourse.org/u/muhammad_ghufran)
#### Post date: [2023年四月18日 07:24 UTC](https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185/6 "2023-04-18T07:24:26Z")

</div>

@simon  
使用  
WPDiscourse\Utilities\PublicPluginUtilities::sync\_sso\_record($sso\_params\_array, $myuser-\>ID);  
时出现致命错误。

PHP Fatal error: Uncaught Error: Call to undefined method WPDiscourse\Utilities\PublicPluginUtilities::sync\_sso\_record()

[wp discourse](https://github.com/discourse/wp-discourse) 插件已激活，SSO 运行正常。

我尝试  
use WPDiscourse\Utilities\Utilities as DiscourseUtilities;  
DiscourseUtilities::sync\_sso\_record($sso\_params, 3992);  
这样就不会出现致命错误，但自定义字段数据未保存在 discourse 中。

返回此错误

WP\_Error Object ( [errors] =\> Array ( [wpdc\_response\_error] =\> Array ( [0] =\> An invalid response was returned from Discourse ) ) [error\_data] =\> Array ( [wpdc\_response\_error] =\> Array ( [http\_code] =\> 422 [http\_body] =\> {“failed”:“FAILED”,“message”:“The `external_id` is required but was blank”} ) ) [additional\_data:protected] =\> Array ( ) )

---

<div class="post-metadata">

### Author: ![muhammad\_ghufran](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/muhammad_ghufran/32/301962_2.png) [@muhammad\_ghufran](https://meta.discourse.org/u/muhammad_ghufran)
#### Post date: [2023年四月18日 09:46 UTC](https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185/7 "2023-04-18T09:46:07Z")

</div>

@simon 请检查一下问题

---

<div class="post-metadata">

### Author: ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)
#### Post date: [2023年四月18日 10:08 UTC](https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185/8 "2023-04-18T10:08:09Z")

</div>

你好 muhammad 🙂

这里的每个人都在尽力帮助解决问题。Simon 正在帮助你，并且会自动收到回复通知，除非他禁用了通知。

所以，没有必要 @提及他并顶起一个话题，尤其是在只等待了不到 3 小时之后。请在这方面保持耐心 🙂

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [2023年四月18日 18:28 UTC](https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185/9 "2023-04-18T18:28:42Z")

</div>

> [@muhammad\_ghufran](#):
>
> 我尝试过  
> use WPDiscourse\Utilities\Utilities as DiscourseUtilities;  
> DiscourseUtilities::sync\_sso\_record($sso\_params, 3992);
> 
> 这样调用没有致命错误，但是自定义字段数据没有保存在 discourse 中。

抱歉我之前提供的代码有误。你调用函数的方式是正确的。这样也应该可以工作：

`WPDiscourse\\Utilities\\Utilities::sync_sso_record($sso_params, 3992);`

我会在之前的帖子中编辑进去。

> [@muhammad\_ghufran](#):
>
> 这样调用没有致命错误，但是自定义字段数据没有保存在 discourse 中。
> 
> 返回此错误

这是错误信息：

`{“failed”:“FAILED”,“message”:“external_id is required but was blank”}`

你需要设置 `$sso_params_array` 中的 `external_id` 参数。`external_id` 应该设置为用户的 WordPress ID。

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [2023年五月18日 18:28 UTC](https://meta.discourse.org/t/custom-data-migration-from-wordpress-to-discourse/261185/10 "2023-05-18T18:28:44Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
