woocommerce/docs/best-practices/data-management/zh-cn/crud-objects.md
2026-04-15 10:18:01 +08:00

324 lines
No EOL
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
post_title: Developing using WooCommerce CRUD objects
sidebar_label: Using CRUD objects
---
# 使用 WooCommerce CRUD 对象进行开发
CRUD 是您可以对数据库或资源执行的四种基本操作的缩写——创建、读取、更新、删除。
[WooCommerce 3.0 引入了 CRUD 对象](https://woocommerce.wordpress.com/2016/10/27/the-new-crud-classes-in-woocommerce-2-7/)用于处理 WooCommerce 数据。**在您的代码中,应尽可能使用这些对象,而不是直接更新元数据或使用 WordPress 文章对象。**
每个对象都包含其控制数据的结构化数据(属性)、每个属性的 getter 和 setter以及与数据存储交互的保存/删除方法。数据存储处理从数据库的实际保存/读取。对象本身无需知道数据存储在哪里。
## CRUD 的优势
* 结构 - 每个对象都有预定义的结构并保持其自身数据有效。
* 控制 - 我们控制数据流以及任何所需的验证,因此我们知道何时发生更改。
* 易于开发 - 作为开发人员,您无需了解所处理数据的内部细节,只需知道其名称。
* 抽象 - 数据可以移动到其他地方,例如自定义表,而不会影响现有代码。
* 统一 - 我们可以使用相同的代码在管理员界面、REST API 和 CLI 中更新内容。一切都是统一的。
* 简化代码 - 用于更新对象的程序性代码更少,这降低了故障可能性并增加了单元测试覆盖率。
## CRUD 对象结构
[`WC_Data`](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/abstracts/abstract-wc-data.php) 类是 CRUD 对象的基本实现,所有 CRUD 对象都继承自它。最重要的属性是 `$data`(一个包含每个对象所支持属性的数组)和 `$id`(对象的 ID
[优惠券对象类](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/class-wc-coupon.php) 是扩展 `WC_Data` 并为所有属性添加 CRUD 函数的一个很好的例子。
### 数据
`$data` 存储属性名称和默认值:
```php
/**
* 数据数组,包含默认值。
* @since 3.0.0
* @var array
*/
protected $data = array(
'code' => '',
'amount' => 0,
'date_created' => '',
'date_modified' => '',
'discount_type' => 'fixed_cart',
'description' => '',
'date_expires' => '',
'usage_count' => 0,
'individual_use' => false,
'product_ids' => array(),
'excluded_product_ids' => array(),
'usage_limit' => 0,
'usage_limit_per_user' => 0,
'limit_usage_to_x_items' => 0,
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '',
'maximum_amount' => '',
'email_restrictions' => array(),
'used_by' => array(),
);
```
### Getter 与 Setter 方法
此数组(属性)中的每个键都对应一个 getter 和 setter 方法,例如 `set_used_by()``get_used_by()``$data` 本身是私密的,因此必须使用 getter 和 setter 方法来访问数据。
Getter 示例:
```php
/**
* 获取所有使用过当前优惠券的用户记录。
* @since 3.0.0
* @param string $context
* @return array
*/
public function get_used_by( $context = 'view' ) {
return $this->get_prop( 'used_by', $context );
}
```
Setter 示例:
```php
/**
* 设置哪些用户使用过此优惠券。
* @since 3.0.0
* @param array $used_by
* @throws WC_Data_Exception
*/
public function set_used_by( $used_by ) {
$this->set_prop( 'used_by', array_filter( $used_by ) );
}
```
`set_prop``get_prop``WC_Data` 的一部分。它们会应用各种过滤器(基于上下文)并处理变更,因此我们可以高效地仅保存已更改的属性,而不是所有属性。
关于 `$context` 的说明:当获取用于前端或显示的数据时,使用 `view` 上下文。这会对数据应用过滤器,以便扩展可以动态更改值。在后台显示要编辑的值以及保存到数据库时,应使用 `edit` 上下文。使用 `edit` 上下文不会对数据应用任何过滤器。
### 构造函数
CRUD 对象的构造函数便于从数据库读取数据。实际的读取操作并非由 CRUD 类执行,而是由其数据存储完成。
示例:
```php
/**
* 优惠券构造函数。加载优惠券数据。
* @param mixed $data 优惠券数据、对象、ID 或代码。
*/
public function __construct( $data = '' ) {
parent::__construct( $data );
if ( $data instanceof WC_Coupon ) {
$this->set_id( absint( $data->get_id() ) );
} elseif ( is_numeric( $data ) && 'shop_coupon' === get_post_type( $data ) ) {
$this->set_id( $data );
} elseif ( ! empty( $data ) ) {
$this->set_id( wc_get_coupon_id_by_code( $data ) );
$this->set_code( $data );
} else {
$this->set_object_read( true );
}
$this->data_store = WC_Data_Store::load( 'coupon' );
if ( $this->get_id() > 0 ) {
$this->data_store->read( $this );
}
}
```
请注意它如何根据传递给对象的数据设置 ID然后调用数据存储从数据库检索数据。一旦通过数据存储读取了数据或者未设置 ID就会设置 `$this->set_object_read( true );`,以便数据存储和 CRUD 对象知道它已被读取。设置此标志后,系统将开始跟踪更改。
### 保存与删除
在 CRUD 子类中,保存和删除方法是可选的,因为 `WC_Data` 父类可以处理它们。当调用 `save`数据存储用于将数据保存到数据库。Delete 则从数据库中移除对象。必须调用 `save` 才能使更改持久化,否则它们将被丢弃。
`WC_Data` 中的 save 方法如下所示:
```php
/**
* Save should create or update based on object existence.
*
* @since 2.6.0
* @return int
*/
public function save() {
if ( $this->data_store ) {
// 在保存到数据库前触发操作。允许您在保存前调整对象属性。
do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store );
if ( $this->get_id() ) {
$this->data_store->update( $this );
} else {
$this->data_store->create( $this );
}
return $this->get_id();
}
}
```
根据对象是否已有 ID使用更新/创建。ID 将在创建后设置。
delete 方法如下:
```php
/**
* Delete an object, set the ID to 0, and return result.
*
* @since 2.6.0
* @param bool $force_delete
* @return bool result
*/
public function delete( $force_delete = false ) {
if ( $this->data_store ) {
$this->data_store->delete( $this, array( 'force_delete' => $force_delete ) );
$this->set_id( 0 );
return true;
}
return false;
}
```
## CRUD 用法示例
### 创建新的简单产品
```php
$product = new WC_Product_Simple();
$product->set_name( 'My Product' );
$product->set_slug( 'myproduct' );
$product->set_description( 'A new simple product' );
$product->set_regular_price( '9.50' );
$product->save();
$product_id = $product->get_id();
```
### 更新现有优惠券
```php
$coupon = new WC_Coupon( $coupon_id );
$coupon->set_discount_type( 'percent' );
$coupon->set_amount( 25.00 );
$coupon->save();
```
### 获取客户信息
```php
$customer = new WC_Customer( $user_id );
$email = $customer->get_email();
$address = $customer->get_billing_address();
$name = $customer->get_first_name() . ' ' . $customer->get_last_name();
```
### 优惠券管理
本页面用于管理优惠券。您可以查看、创建、编辑和删除优惠券。
* **新增**优惠券:点击“新增”按钮,可以创建新的优惠券。
* **编辑**优惠券:点击优惠券列表中的“编辑”按钮,可以修改现有优惠券的设置。
* **删除**优惠券:点击优惠券列表中的“删除”按钮,可以删除优惠券。
### 优惠券详情
显示单个优惠券的详细信息,包括:
* **名称 (Name)**:优惠券的名称。
* **折扣 (Discount)**:优惠券的折扣类型和金额。
* **使用 (Use)**:优惠券的使用限制,例如最小订单金额、使用次数等。
* **有效期 (Expiration Date)**:优惠券的有效期。
* **其他设置 (Other Settings)**:其他自定义设置。
### 优惠券列表
显示所有优惠券的列表,包括:
* **名称 (Name)**:优惠券的名称。
* **折扣 (Discount)**:优惠券的折扣类型和金额。
* **使用次数 (Count)**:优惠券已使用的次数。
* **状态 (Status)**:优惠券的状态,例如“有效”、“已过期”、“已禁用”。
### 批量操作
您可以对多个优惠券进行批量操作,例如:
* **删除 (Delete)**:删除选中的优惠券。
* **更新 (Updating)**:更新选中的优惠券的状态。
### 导入/导出
您可以将优惠券数据从一个系统导入到另一个系统,或者将优惠券数据导出为文件。
* **导入 (Import)**:从文件导入优惠券数据。
* **导出 (Export)**:将优惠券数据导出为文件。
### 优惠券代码
以下是一些常用的优惠券代码示例:
* `%s`:占位符,表示用户可以自定义的文本。
* `{name}`:占位符,表示客户的名称。
### 邮件通知
当客户使用优惠券时,您可以发送电子邮件通知。
* **邮件 (Mail)**:发送电子邮件通知。
* **收件人 (Address)**:收件人的电子邮件地址。
* **主题 (Subject)**:电子邮件的主题。
* **正文 (Body)**:电子邮件的正文内容。
### 账单 (Billing)
显示与优惠券相关的账单信息。
* **金额 (Amount)**:优惠券的金额。
* **百分比 (Percent)**:优惠券的百分比折扣。
* **类型 (Type)**:优惠券的类型。
### 常见问题
* **如何创建新的优惠券?**
点击“新增”按钮,填写优惠券的详细信息,然后点击“保存”按钮。
* **如何修改现有优惠券?**
点击优惠券列表中的“编辑”按钮,修改优惠券的设置,然后点击“保存”按钮。
* **如何删除优惠券?**
点击优惠券列表中的“删除”按钮,确认删除操作。
* **如何使用优惠券?**
在结账时,输入优惠券代码,系统会自动应用折扣。
* **优惠券的有效期是什么?**
优惠券的有效期由您在创建优惠券时设置。
* **如何查看优惠券的使用情况?**
在优惠券详情页面,您可以查看优惠券的使用次数和状态。
* **如何导出优惠券数据?**
点击“导出”按钮,选择导出的文件格式,然后点击“下载”按钮。
* **如何导入优惠券数据?**
点击“导入”按钮,选择要导入的文件,然后点击“上传”按钮。
### 错误信息
* `Invalid coupon code.`:优惠券代码无效。
* `Coupon has expired.`:优惠券已过期。
* `Coupon has already been used.`:优惠券已使用。
* `Minimum order amount not met.`:未达到最小订单金额。
* `Coupon cannot be applied to this product.`:该优惠券无法应用于该商品。
* `Error updating coupon.`:更新优惠券时出错。
* `Error deleting coupon.`:删除优惠券时出错。
* `Error importing coupon data.`:导入优惠券数据时出错。
* `Error exporting coupon data.`:导出优惠券数据时出错。
### 提示
* 您可以使用搜索框快速查找优惠券。
* 您可以使用分页功能浏览优惠券列表。
* 您可以使用排序功能对优惠券列表进行排序。
* 您可以使用过滤器功能筛选优惠券列表。
* 如果您在使用优惠券时遇到问题,请联系客服。
* 请定期检查和更新您的优惠券,以确保其有效性。
* 您可以创建自定义的优惠券代码,以满足您的特定需求。
* 您可以